Problems getting title of windowsapps, such as Photos

169 Views Asked by At

I have a need to get the handle of the window showing a particular image so that it can be aligned with other windows. ShellExecuteEx is used to launch the registered application for the image type, and this works OK (even when the registered application is a DLL, as in the case of 'Photo Viewer').

Unfortunately, the new windowsapps under Windows 10 (e.g. 'Photos' aka "microsoft.photos.exe") don't seem to be playing fair. AssocQueryString says no application is associated with the image type if I had manually associated 'Photos', even though 'Photos' is launched OK when I double-click on such an image.

The title bar for the 'Photos' window clearly says something like 'Photos - file.jpg', but calls to GetWindowText only returns the "Photos" part, with no identifying filename. I also tried sending a WM_GETTEXT message to the window but the result was the same.

Is there something odd about these windowsapps? What is the rationale for only returning the generic part of the window title? Is there a way to get the whole window titles, as displayed?

1

There are 1 best solutions below

0
Strive Sun On BEST ANSWER

the question does say that I'm trying to get the handle of the window showing the image. I was using the title bar to distinguish one window from another in all other cases.

It has been pointed out in the comments that you need to use UI Automation to reliably obtain the title text.

You can try the following code to get the control title.

#include <Windows.h>
#include <stdio.h>
#include <UIAutomation.h>

IUIAutomation* pClientUIA;
IUIAutomationElement* pRootElement;

void FindControl(const long controlType)
{
    HRESULT hr;
    BSTR name;
    IUIAutomationCondition* pCondition;
    VARIANT varProp;
    varProp.vt = VT_I4;
    varProp.uintVal = controlType;
    hr = pClientUIA->CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, &pCondition);
    if (S_OK != hr)
    {
        printf("CreatePropertyCondition error: %d\n", GetLastError());
    }

    IUIAutomationElementArray* pElementFound;
    hr = pRootElement->FindAll(TreeScope_Subtree, pCondition, &pElementFound);
    if (S_OK != hr)
    {
        printf("CreatePropertyCondition error: %d\n", GetLastError());
    }
    IUIAutomationElement* pElement;
    hr = pElementFound->GetElement(0, &pElement);
    if (S_OK != hr)
    {
       printf("CreatePropertyCondition error: %d\n", GetLastError());
    }
    hr = pElement->get_CurrentName(&name);
    if (S_OK != hr)
    {
       printf("CreatePropertyCondition error: %d\n", GetLastError());
    }
    wprintf(L"Control Name: %s\n", name);
}

int main()
{

    HRESULT hr = CoInitializeEx(NULL, COINITBASE_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
    if (S_OK != hr)
    {
        printf("CoInitializeEx error: %d\n", GetLastError());
        return 1;
    }



    hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER, IID_IUIAutomation, reinterpret_cast<void**>(&pClientUIA));
    if (S_OK != hr)
    {
        printf("CoCreateInstance error: %d\n", GetLastError());
        return 1;
    }

    HWND hwnd = (HWND)0x00030AF6;  //hwnd of "Photos"
    if (hwnd == NULL)
    {
        printf("FindWindow error: %d\n", GetLastError());
        return 1;
    }

    hr = pClientUIA->ElementFromHandle(hwnd, &pRootElement);
    if (S_OK != hr)
    {
        printf("ElementFromHandle error: %d\n", GetLastError());
        return 1;
    }

    FindControl(UIA_TextControlTypeId);
}

Debug:

enter image description here