заблокировать окна как модальный диалог?

Тема в разделе "WASM.WIN32", создана пользователем katrus, 23 май 2007.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Как известно, модальный диалог, будучи вызван с HWND некого окна блокирует его. А как сделать то же самое "искуственно", желательно на чистом win32 без MFC?
     
  2. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Смотри описание сообщения WM_ENABLE в MSDN

    Код (Text):
    1.  xor     eax,eax
    2.  push    eax        ; не используется, 0
    3.  push    eax        ; 0 == заблокировать / 1 == разблокировать
    4.  push    WM_ENABLE
    5.  push    hWnd       ; хэндл окна
    6.  call    SendMessage
     
  3. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    G13
    То же самое можно сделать вызвав EnableWindow(...). K сожалению, это не совсем то, что нужно. Таким образом можно сделать disable на определенный контроль, но не на все окно с его дочерними подокнами и контролями. Например вызвав EnableWindow для окна IE - ничего не получаем. Окно остается полностью активным.

    Конечно можно пробежатся по всем подокнам и сделать их неактвными (запоминая состояние каждого дочернего подокна, чтоб потом можно было востановить первоначальное состояние), но это немного муторно, и, очевидно, DoModal имеет другую логику. Когда вызывается DoModal, окно не меняет своего цвета, а когда делаем EnableWindow(..., FALSE), окно становится серым. Полагаю, модальные диалоги что то "подхимичивают" с message loop. Но что?
     
  4. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    EnableWindow() просто посылает WM_ENABLE - а IE спокойненько не обрабатывает его - иными словами не вызывает DefWindowProc(). Надо сделать отдельный Message Loop для твоего окна и обрабатывать толко сообщения к твоему HWND, а всё другое игнорировать.
     
  5. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    AsmGuru62
    А как игнорировать все сообщения к определенному окну?
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    katrus
    Ничего не делать в ответ на данные сообщения. И не отсылать к DefWindowProc.
     
  7. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Quantum
    Не все так просто. Допустим есть IЕ со своим собственным окном и message loop. Я из совершенно другого процесса бросаю на него модальный диалог (MFC делает это на ура). От того, что я в своем процессе запускаю некий message loop ничего не изменится. Как фильтровать сообшения в чужом окне?
     
  8. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    А если поставить hook ?
     
  9. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    kush
    hook? А на что? Глобальный hook?
     
  10. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    если отбрасывать все сообщения, окно не будет перерисовываться и будет считаться "не отвечающим"
     
  11. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    Да, hook, наверное, не выход. Тем более много возни.
    Есть другая идея:
    Наверняка каждый при разработке GUI приложения допускал ошибку, связанную с зацикливанием. Если этот цикл оказался, например, в обработчике нажатия кнопки. То окно фактически становится disabled.
    Попробуй вставить в оконную процедуру приложения " jmp $ ".
     
  12. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    kush
    все верно. Но проблема в том, что цикл сообщений не принадлежит моему процессу. Другими словами зациклить его я не могу.
     
  13. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    Неужели трудно пропатчить чужой процесс ? (риторический вопрос)

    1) Получили адрес оконной процедуры вражеского окна:
    GetWindowLong(HWND hWnd, GWL_WNDPROC)

    2) Ясно, что он вдругом процессе. Но ведь есть магическая функция WriteProcessMemory. Вставляем с ее помощью два байта.
     
  14. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Пропатчить могу. И это совсем не сложно. Но хочется обойтись "конвенциональным" оружием. Если, допустим, я пишу библиотечку которая включает некий аналог модального диалога, то, что мне патчить всех направо и налево? Антивирусы шапками закидают. :)
     
  15. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    Ну может сабклассинг тебя устроит ?
     
  16. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Не совсем. Мне очень важно блокировать окна IE.
     
  17. kush

    kush New Member

    Публикаций:
    0
    Регистрация:
    24 май 2007
    Сообщения:
    46
    Тогда вернемся к хукам. По видимому, это единственный как ты говоришь, "конвенциональный" способ попасть в адресное пространство чужого процесса.
    Процедура хука WH_CALLWNDPROC будет обрабатывать сообщения к нужному окну до того, как они дойдут до этого окна. Ее код будет находиться в адресном пространстве чужого процесса.
    Теперь пошлем чужому окну сообщение WM_USER + 100 + X. А в обработчике хука укажем, что по приходу данного сообщения нужно показать модальную форму. Теперь, если этому окну из любого другого процесса придет данное сообщение, то оно будет заблокировано, причем средствами windows.

    З.Ы: только не говори, что и этот способ не подходит.
     
  18. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    katrus
    Надо было начинать с того, что окно создаётся из другого процесса. Чтобы продублировать модальность достаточно вызвать EnableWindow(hWnd, 0) на родительское окно и создать собственный цикл обработки сообщений - модальные диалоги именно так и поступают. Естественно, из другого процесса не получится перебить цикл сообщений, т.к. у каждого процесса свой цикл. Поэтому модальное окно нужно создавать из процесса IE. Для этого достаточно поместить код создания окна и цикл сообщений в функцию в DLL и заставить IE вызвать эту функцию через хук (SetWindowsHookEx). Никого патчить не нужно.
     
  19. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    katrus

    >Например вызвав EnableWindow для окна IE - ничего не получаем. Окно остается полностью активным.

    ??
    А у меня и EnableWindow, и SetWindowLong+/-WS_DISABLED с IE что хотят, то и делают.
    Неужели из-за версии ? :)
     
  20. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    kero
    Видимо, katrus имел в виду сообщение WM_ENABLE, а не функцию EnableWindow.