Проблема:
Вызов ShellExecuteEx с lpVerb = "openas" открывает диплог выбора приложения для открытия файла. НО!!! Этот диалог не получает фокус=( И я по своей простоте душевной думал, если я получу id процесса(диалога) и переберу все окна, и сравню id процесса(диалога) с id процесса(окна), и если они совпадут, то будет мне счастье! id процесса(диалога) правильный, я проверял Spy'ем.
Как оказалось ничего подобного=( Этот диалог EnumWindows не нашел=( Возможно потому-что у этого диалога стиль стоит WS_POPUP...
Кто-нибудь с этим сталкивался? Как мне найти этот диалог?
Здравствуйте, Mihajlo, Вы писали:
M>Проблема: M>Вызов ShellExecuteEx с lpVerb = "openas" открывает диплог выбора приложения для открытия файла. НО!!! Этот диалог не получает фокус
1. Фокус должен быть обязательно.
2. Непонятное поведение окна признак повреждения памяти.
3. Повреждения памяти часто встречаются при роботе с си-строками.
4. Посмотри все вызовы сишных функций для работы со строками.
5. Посмотри все вызовы типа SendMessage (hWnd, WM_SETTEXT, 0, (LPARAM)str), т.е. там где есть передача строки системе.
Держи в уме что все строки должны заканчиваться символом '\0'
Здравствуйте, Mihajlo, Вы писали:
M>Как оказалось ничего подобного=( Этот диалог EnumWindows не нашел=( Возможно потому-что у этого диалога стиль стоит WS_POPUP... M>Кто-нибудь с этим сталкивался? Как мне найти этот диалог?
msdn said:
The EnumWindows function enumerates all top-level windows on the screen
окно, поднимаемое openas — не есть top-level, даже если его спай так показывает
Здравствуйте, Mihajlo, Вы писали:
M>Вызов ShellExecuteEx с lpVerb = "openas" открывает диплог выбора приложения для открытия файла. НО!!! Этот диалог не получает фокус=( И я по своей простоте душевной думал, если я получу id процесса(диалога) и переберу все окна, и сравню id процесса(диалога) с id процесса(окна), и если они совпадут, то будет мне счастье!
Каким образом ты намерен перебрать окна процесса ? В твоем примере ты перебираешь окна потока, а вовсе не процесса. Поэтому не исключено, что это окно принадлежит другому потоку этого же процесса.
>id процесса(диалога) правильный, я проверял Spy'ем.
А проверить ID потока этого диалога можно было и сравнить с ID потока основного окна ?
Здравствуйте, CEMb, Вы писали:
CEM>Здравствуйте, Mihajlo, Вы писали:
M>>Как оказалось ничего подобного=( Этот диалог EnumWindows не нашел=( Возможно потому-что у этого диалога стиль стоит WS_POPUP... M>>Кто-нибудь с этим сталкивался? Как мне найти этот диалог?
CEM>msdn said: CEM>
CEM>The EnumWindows function enumerates all top-level windows on the screen
CEM>окно, поднимаемое openas — не есть top-level, даже если его спай так показывает
ИМХО spy++ все же правильно показывает, надо просто посмотреть у него Parent Window в свойствах этого окна.
Здравствуйте, Pavel Dvorkin, Вы писали:
CEM>>окно, поднимаемое openas — не есть top-level, даже если его спай так показывает
PD>ИМХО spy++ все же правильно показывает, надо просто посмотреть у него Parent Window в свойствах этого окна.
Ну да, а я и не говорил, что неправильно я и сам его так показываю
PD>А проверить ID потока этого диалога можно было и сравнить с ID потока основного окна ?
А вот это проверить надо... к примеру, у GetOpenFileName — контекстное меню на списке файлов с последующими диалогами открывается в отдельных потоках
Здравствуйте, CEMb, Вы писали:
PD>>А проверить ID потока этого диалога можно было и сравнить с ID потока основного окна ?
CEM>А вот это проверить надо... к примеру, у GetOpenFileName — контекстное меню на списке файлов с последующими диалогами открывается в отдельных потоках
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, CEMb, Вы писали:
PD>>>А проверить ID потока этого диалога можно было и сравнить с ID потока основного окна ?
CEM>>А вот это проверить надо... к примеру, у GetOpenFileName — контекстное меню на списке файлов с последующими диалогами открывается в отдельных потоках
PD>http://rsdn.ru/forum/winapi/1295946.1.aspx
Не, там GUI поток с окнами открывается. Т.е. можно поднять свойства папки (в своём же процессе), а сам GetOpenFileName закрыть. Останется висеть окно свойств, в другом среде.
Здравствуйте, kero, Вы писали:
CEM>>>>окно, поднимаемое openas — не есть top-level, даже если его спай так показывает
K>не поясните — а какое ?
Какое окно?
Ну вот я сейчас в студии, в меню зашёл, File->Open. Открылся диалог, у него тред № N1, правая кнопка мышки на файле (любом) ->Properties — открылось окно, смотрю у него threadId — № N2, правая кнопка Open With -> Choose Program... Открывшееся окно со списком, ThreadId — № N3.
А вот про меню я нагнал. По крайней мере, в студии — оно из того же потока
PD>>>ИМХО spy++ все же правильно показывает, надо просто посмотреть у него Parent Window в свойствах этого окна.
K>как раз с Parent Window в свойствах у spy++ беда: путает parent и owner
А там ещё есть рут и анцестор рут, и я вот путаюсь, кто из этих четырёх (или их ещё больше?) за что отвечает
CEM>>>>>окно, поднимаемое openas — не есть top-level, даже если его спай так показывает
K>>не поясните — а какое ?
CEM>Какое окно? CEM>Ну вот я сейчас в студии, в меню зашёл, File->Open. Открылся диалог, у него тред № N1, правая кнопка мышки на файле (любом) ->Properties — открылось окно, смотрю у него threadId — № N2, правая кнопка Open With -> Choose Program... Открывшееся окно со списком, ThreadId — № N3.
Нет, спрашивал не о треде, а о том, какое поднимаемое openas окно, по-вашему, не top-level.
PD>>>>ИМХО spy++ все же правильно показывает, надо просто посмотреть у него Parent Window в свойствах этого окна.
K>>как раз с Parent Window в свойствах у spy++ беда: путает parent и owner
CEM>А там ещё есть рут и анцестор рут, и я вот путаюсь, кто из этих четырёх (или их ещё больше?) за что отвечает
Насчет ошибки Spy++ (всех версий): вычисляет parent — через GetParent и/или GetWindowLong(GWL_HWNDPARENT) без учета того, что и то, и другое могут выдавать как parent, так и owner. Игнорируя (появившуюся еще в 98) GetAncestor, при GA_PARENT дающую точный parent.
Здравствуйте, kero, Вы писали:
CEM>>>>>>окно, поднимаемое openas — не есть top-level, даже если его спай так показывает
K>>>не поясните — а какое ?
CEM>>Какое окно? CEM>>Ну вот я сейчас в студии, в меню зашёл, File->Open. Открылся диалог, у него тред № N1, правая кнопка мышки на файле (любом) ->Properties — открылось окно, смотрю у него threadId — № N2, правая кнопка Open With -> Choose Program... Открывшееся окно со списком, ThreadId — № N3.
K>Нет, спрашивал не о треде, а о том, какое поднимаемое openas окно, по-вашему, не top-level.
А, ну, наверно, у которого GetParent(hWnd) не пуст. Ну, даже наверно не по-моему, а по EnumWindows-оему
Здравствуйте, CEMb, Вы писали:
K>>Нет, спрашивал не о треде, а о том, какое поднимаемое openas окно, по-вашему, не top-level.
CEM>А, ну, наверно, у которого GetParent(hWnd) не пуст. Ну, даже наверно не по-моему, а по EnumWindows-оему
Здравствуйте, kero, Вы писали:
K>>>Нет, спрашивал не о треде, а о том, какое поднимаемое openas окно, по-вашему, не top-level.
CEM>>А, ну, наверно, у которого GetParent(hWnd) не пуст. Ну, даже наверно не по-моему, а по EnumWindows-оему
K>Ну, не верно же.
А как?
msdn about top-level window (Glossary):
top-level window
A window that has no parent window.
Здравствуйте, CEMb, Вы писали:
CEM>А как? CEM>msdn about top-level window (Glossary): CEM>
top-level window
CEM>A window that has no parent window.
CEM>Т.е. сюда же относим окна с непустым овнером?
Хм, а мне казалось, что демка по ссылке выше не оставляет шансов не разобраться, да и о проблемности GetParent там сказано...
Короче. После Win98 (т.е. с появлением GetAncestor) довольно ущербное определение top-level как "window that has no parent window" вообще утеряло всякий смысл: ну, нет таких валидных hWnd, чтобы GetAncestor(hWnd,GA_PARENT) = 0.
Так что top-level — это когда GetAncestor(hWnd,GA_PARENT) = (Get)DesktopWindow. Или менее в лоб: когда GetAncestor(hWnd,GA_ROOT) = hWnd.
К примеру, все 3 окна этой выставки старых спаевских глюков —