Ghost2
> Она будет блокирующей если в ней просто запустить еще один main loop и при помощи CallWindowProc вызывать процесс обработки событий родительского окна. Все работает точно так же, как с MessageBox
циклом да, можно. Адрес функции обработки родительского окна только откуда брать если если hwndOwner = 0.
entryway
> Такой диалог добавляет только +1 поток
интересно для чего.
Aroch
> Адрес функции обработки родительского окна только откуда брать
EnumWindows. Внутри винды может какое-то более прямолинейное API есть.
Ghost2
> Внутри винды может какое-то более прямолинейное API есть.
DispatchMessage же
Aroch
> > Такой диалог добавляет только +1 поток
> интересно для чего.
Возможно для:
// // Used by the worker thread to enumerate network disk resources. // extern DWORD cbNetEnumBuf; extern LPTSTR gpcNetEnumBuf;
https://github.com/tongzx/nt5src/blob/master/Source/XPSP1/NT/shel… eopen.c#L9188
Как раз там по коду создается именно один:
// // If there is no worker thread for network disk enumeration, // start up here rather than in the dll, since it's only // for the fileopen dlg. // // Always start a thread if the number of active fileopen dialogs // goes from 0 to 1 // if (( lpCurDlg->dwCurDlgNum == 0) && ( !hLNDThread)) { ... hLNDThread = CreateThread( ..., ListNetDrivesHandler, ...);
Dmitry_Milk
> DispatchMessage же
Не понял.
Ghost2
> EnumWindows
так а если окон несколько, всем слать?
entryway
> Возможно для:
с одной стороны похоже на правду, с другой network там отдельной кнопкой и преждевременно.
> // Always start a thread if the number of active fileopen dialogs
> // goes from 0 to 1
хех, похоже на тот поток с WorkerW как раз, он тоже в единственном экземпляре не зависимо от количества открытых окон диалога.
Aroch
Кнопка Network для нового подключения, а поток проверяет доступность подключенных/сохраненных. Смотри внутрь ListNetDrivesHandler / GetNetDrives, там WNetOpenEnum + WNetEnumResource, с последующим "Add the Entries to the listbox".
Ghost2
> Не понял.
Зачем мучаться с поисками WndProc родительского (а может не только родительского) окна, когда DispatchMessage сам найдет и вызовет нужный WndProc для hwnd из сообщения?
Dmitry_Milk
> для hwnd из сообщения
для какого hwnd? Тебе его надо сперва как-то получить и тут вариант перебрав все окна процесса.
entryway
> а поток проверяет доступность подключенных/сохраненных. Смотри внутрь ListNetDrivesHandler / GetNetDrives, там WNetOpenEnum + WNetEnumResource, с последующим "Add the Entries to the listbox".
при этом кнопка Network поди сразу в enabled не дожидаясь результата проверки или по уму?
Aroch
> для какого hwnd? Тебе его надо сперва как-то получить
Так из сообщения же, там же не ради забавы вызывается WndProc одного из окон под модальным, а из-за необходимости обработать возникшее для него сообщение (если допустимо, то есть, если это, например WM_PAINT или WM_TIMER)
Я вчера сунулся в ту репу от XP-шки, которую entryway подсказал, поглядеть конкретнее в кишки. Если я правильно разобрался (назначение многих функций с наскоку непонятно), то происходит примерно так:
GetOpenFileName (да и скорее всего прочие стандартные диалоги из comdlg32) в кишках в конце концов превращается в
DialogBoxIndirectParam (одна из универсальных функций открытия произвольного модального диалога), а та в свою очередь - в InternalDialogBox, которая в свою очередь - в DialogBox2, внутри которого организован цикл сообщений на PeekMessage/DispatchMessage (начало цикла на строке 1108, цикл правда посложнее чем обычно, но все равно содержит выборку сообщений из очереди и в конце концов отправку в DispatchMessage, откуда и попадает в нужное окно).
Собственно, вся блокировка потока, которая возникает при вызове GetOpenFileName (и вообще любых прочих диаологов) - это блокировка на вызове NtUserWaitMessage в отрицательной ветке if-а над PeekMessage.
Dmitry_Milk
> PeekMessage
то есть там еще и жадный цикл.
> превращается в DialogBoxIndirectParam
в который передается hwnd из переданной клиентом структуры и который мы выставили в 0. Дальше я не смотрел. Если нашел место где там обрабатывается 0 и идет поиск hwnd родителя, скинь ссылку.
Aroch
> в который передается hwnd из переданной клиентом структуры и который мы выставили в 0
Это не важно, что там передали в качестве родительского. Сообщения во внутреннем цикле событий обрабатываются для всех окон (в том числе и для самого диалога и для родительского окна, если оно есть), потому что второй параметр у PeekMessage (фильтр по hwnd) задан NULL (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)).
То есть, нет необходимости "искать hwnd родителя, если передали 0", потому что hwnd по любому будет в сообщении, вытащенном PeekMessage из очереди.
Aroch
> то есть там еще и жадный цикл
Не совсем. Если я правильно понял логику - жадность (то есть поток продолжает выполнять функцию даже в отсутствии сообщений) только до момента появления окна, а после появления окна False от PeekMessage приводит к вызову NtUserWaitMessage, который отдает управление системе до тех пор, пока что-то не изменится в очереди сообщений.
UPD. Нет, посложнее. Там еще какие-то флаги проверяются, в частности fWantIdleMsgs, который служит признаком того, что надо посылать WM_ENTERIDLE родителю, если он есть. Но похоже там все равно сделано так, что постоянного idle-цикла не будет, и все равно рано или поздно дойдет до NtUserWaitMessage.
Чатжпт, а о чем ведут речь в этом треде умные мужы последние 3 страницы?
jaguard
> Чатжпт, а о чем ведут речь в этом треде умные мужы последние 3 страницы?
изначально про то что нефиг трогать системное окно открытия/сохранения файла и пытаться центрировать его по окну родителя каждый раз при появлении.
Тема в архиве.