获取 Windows 应用程序标题的问题,例如照片
Problems getting title of windowsapps, such as Photos
我需要获取显示特定图像的 window 的句柄,以便它可以与其他 windows 对齐。 ShellExecuteEx 用于启动图像类型的注册应用程序,这工作正常(即使注册的应用程序是 DLL,如 'Photo Viewer' 的情况)。
不幸的是,windows10 下的新 windows 应用程序(例如 'Photos' 又名 "microsoft.photos.exe")似乎并不公平。 AssocQueryString 说如果我手动关联 'Photos',则没有应用程序与图像类型关联,即使当我 double-click 这样的图像时 'Photos' 启动正常。
'Photos' window 的标题栏清楚地写着类似 'Photos - file.jpg' 的内容,但只调用 GetWindowText returns "Photos" 部分,没有识别文件名。我也尝试向 window 发送一条 WM_GETTEXT 消息,但结果是一样的。
这些 windows 应用程序有什么奇怪的地方吗?仅返回 window 标题的通用部分的理由是什么?有没有办法获得整个 window 标题,如图所示?
问题确实说我正在尝试获取显示图像的 window 的句柄。在所有其他情况下,我使用标题栏将一个 window 与另一个区分开来。
已经在评论中指出,您需要使用UI Automation才能可靠地获取标题文本。
您可以试试下面的代码来获取控件标题。
#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);
}
调试:
我需要获取显示特定图像的 window 的句柄,以便它可以与其他 windows 对齐。 ShellExecuteEx 用于启动图像类型的注册应用程序,这工作正常(即使注册的应用程序是 DLL,如 'Photo Viewer' 的情况)。
不幸的是,windows10 下的新 windows 应用程序(例如 'Photos' 又名 "microsoft.photos.exe")似乎并不公平。 AssocQueryString 说如果我手动关联 'Photos',则没有应用程序与图像类型关联,即使当我 double-click 这样的图像时 'Photos' 启动正常。
'Photos' window 的标题栏清楚地写着类似 'Photos - file.jpg' 的内容,但只调用 GetWindowText returns "Photos" 部分,没有识别文件名。我也尝试向 window 发送一条 WM_GETTEXT 消息,但结果是一样的。
这些 windows 应用程序有什么奇怪的地方吗?仅返回 window 标题的通用部分的理由是什么?有没有办法获得整个 window 标题,如图所示?
问题确实说我正在尝试获取显示图像的 window 的句柄。在所有其他情况下,我使用标题栏将一个 window 与另一个区分开来。
已经在评论中指出,您需要使用UI Automation才能可靠地获取标题文本。
您可以试试下面的代码来获取控件标题。
#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);
}
调试: