Почему мне не удалось найти родительского окна, указанного в Spy ++?

Представьте, что есть веб-страница с <input type="file" />, Я открываю эту страницу в Firefox и нажимаю кнопку файла. Затем появится диалоговое окно.

Я хочу установить редактирование имени файла всплывающего диалога программно в C ++:

введите описание изображения здесь

Сначала я использую Spy ++ для проверки класса окна, свойства окна Firefox и всплывающего диалога в Spy ++ выглядят так:

Firefox window:
Handle:     001E013E
Caption:    Table with objects - Mozilla Firefox
Class:      MozillaWindowClass

Popup dialog:
Handle:     004508BE
Caption:    File Upload
Class:      #32770 (Dialog)

Spy ++ также показывает, что окно браузера является родителем всплывающего диалога.

Мой код выглядит так:

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

int main()
{
HWND hBrowser = FindWindow(L"MozillaWindowClass", NULL);
printf("Browser hwnd=%X\n", hBrowser);

HWND hDialog = FindWindowEx(hBrowser, NULL, L"#32770 (Dialog)", NULL);
printf("Dialog hwnd=%X\n", hDialog);

system("pause");
}

Но ценность hBrowser не равно значению в диалоге Spy ++ и значению hDialog является NULL, У меня только одно открытое окно Firefox, только с одной вкладкой.

Затем я попытался изменить свой код на:

// 0x001E013E is the handle in Spy++
HWND hDialog = FindWindowEx((HWND)0x001E013E, NULL, L"#32770 (Dialog)", NULL);

hDialog по-прежнему выводит как NULL,

Вопросы:

  1. Почему дескриптор в Spy ++ и тот, который я получаю в программе, не совпадают?
  2. Имеет ли «родительское окно» в Spy ++ то же значение, что и родительский параметр в FindWindowEx?

Примечание: я не могу использовать заголовок окна для поиска, из-за проблемы локализации (Firefox может быть установлен на других языках, кроме английского).

-1

Решение

MozillaWindowClass является владельцем открытого диалога, это не родитель, с которым вы можете использовать FindWindowEx, Также может быть несколько окон MozillaWindowClass, поэтому лучше сначала поискать диалог:

BOOL CALLBACK FindMozillaOpenFilenameDialogEnumProc(HWND hWnd, LPARAM param)
{
HWND*pData = (HWND*) param;
if (GetClassLongPtr(hWnd, GCW_ATOM) == 32770) // Found a dialog?
{
HWND hOwner = GetWindow(hWnd, GW_OWNER);
if (hOwner)
{
WCHAR buf[100];
GetClassName(hOwner, buf, 100);
if (0 == lstrcmp(buf, TEXT("MozillaWindowClass"))) // The dialog is owned by a Mozilla window?
{
HWND hCombo = GetDlgItem(hWnd, 0x047c); // cmb13
GetClassName(hCombo, buf, 100);
buf[8] = '\0'; // Some Windows versions use ComboBox and some use ComboBoxEx32, we only care if it is some type of combobox
if (0 == lstrcmp(buf, TEXT("ComboBox"))) // The dialog contains a ComboBox with the expected ID?
{
*pData = hWnd;
return false;
}
}
}
}
return true;
}int main()
{

HWND hDialog = NULL;
EnumWindows(FindMozillaOpenFilenameDialogEnumProc, (LPARAM) &hDialog);
printf("Dialog hwnd=%X\n", hDialog);
if (hDialog)
{
HWND hCombo = GetDlgItem(hDialog, 0x047c);
SendMessage(hCombo, WM_SETTEXT, 0, (LPARAM) TEXT("c:\\foo\\bar.exe")); // Could also use CDM_SETCONTROLTEXT?
}
return 0;
}

Этот код опирается на недокументированные и внутренние имена и оконные отношения, он может сломаться в любое время.

Помните, что «MozillaWindowClass» является внутренним именем Mozilla и может измениться в любое время. документированный cmb13 идентификатор элемента управления именем файла задокументирован только для GetOpenFileName а также GetSaveFileName но не для IFileDialog основанные диалоги. Вы действительно должны использовать UI Automation когда вы взаимодействуете с открытым диалогом в другом приложении!

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]