我需要获得显示特定图像的窗口的句柄,以便它能与其他窗口对齐。ShellExecuteEx被用来启动图像类型的注册应用程序,这样做是正确的(即使注册的应用程序是一个DLL,如'Photo Viewer'的情况)。
不幸的是,Windows 10下的新窗口应用程序(例如'Photos'又名 "microsoft.photos.exe")似乎并不公平。AssocQueryString显示,如果我手动关联了 "照片",则没有任何应用程序与图像类型相关联,尽管当我双击这样的图像时,"照片 "启动正常。
照片 "窗口的标题栏上清楚地写着 "照片 - file.jpg",但调用GetWindowText只返回 "照片 "部分,没有识别文件名。我也试过向窗口发送WM_GETTEXT消息,但结果还是一样。
这些windowsapps有什么奇怪的地方吗?只返回窗口标题的通用部分的理由是什么?有什么方法可以得到整个窗口标题,如显示的那样?
问题确实说我是想得到显示图像的窗口的句柄。在其他情况下,我都是用标题栏来区分一个窗口和另一个窗口。
有人在评论中指出,你需要使用 UI自动化 来可靠地获取标题文本。
你可以尝试以下代码来获取控件标题。
#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);
}
调试。