Always on Top

Discussion in 'WASM.WIN32' started by AntiB, Jun 26, 2009.

  1. AntiB

    AntiB New Member

    Blog Posts:
    0
    Доброе время суток, хочу сделать следующую программу:
    чтобы добавила к каждому приложению в системное меню запись, при нажатие которого изменялся стиль окна чтобы устоновливался или снимался флаг "Always on Top".

    насколько я понимаю, нужно внедряться в каждый процесс в виде dll и сделать:
    GetSystemMenu( hWnd ) и потом AppendMenu чтобы добавить элемент к списку. Но как получить hWnd процесса в который я внедрился?

    Всем заранее спасибо!
     
  2. wasm_test

    wasm_test wasm test user

    Blog Posts:
    0
    EnumWindows + GetWindowThreadProcessId
    больше не знаю способа
     
  3. AntiB

    AntiB New Member

    Blog Posts:
    0
    ну еще есть EnumThreadWindows, только как искать окно если код длл выполняется прежде чем окно создаться ?
     
  4. ohne

    ohne New Member

    Blog Posts:
    0
    ну ждите пока создатся
    какие проблемы то
     
  5. Clerk

    Clerk Забанен

    Blog Posts:
    0
    AntiB
    Если нет окна, то что вы собрались искать..
     
  6. AntiB

    AntiB New Member

    Blog Posts:
    0
    Смотрите уважаемые коллеги, я создал dll и записываю в реестр чтобы при старте программы (любой) эта dll грузилась в адресное пространство процесса. То есть сначала происходит запуск DllMain чем точка входа программы, так как программа сама создает окна, во время работы DllMain - нету НИКАКИХ окон (так как они еще не созданы). Решение проблемы сделал хаком - создал поток и начала ждать появление окна, но есть два бага:
    1) создается окно и переключаеться на мой поток, поток делает EnumThreadWindows и находит один хендл, но в реальности (в тестовой программе, стандартный проект MS VS с окнами, думаю и в других) - три хендла есть. И что мы имеем: подменил оконную процедуру только для 1 хендла, а должен для 3.
    2) при наведение мышки на границу окна (чтобы появился курсор изменение размера) и делается подмена оконной процедуры - программа перестает реагировать на внешний мир. Пробовал делать SuspendThread/ResumeThread - толку мало.

    Есть какие-то мнение насчет этого?
     
  7. AntiB

    AntiB New Member

    Blog Posts:
    0
    Я делаю так:
    Code (Text):
    1.     OldWindowProc = (WNDPROC)SetWindowLongPtr( hWnd,
    2.                                                GWL_WNDPROC,
    3.                                                (LONG_PTR)NewProc );
    Code (Text):
    1. LRESULT
    2. CALLBACK
    3. NewProc  (
    4.     IN      HWND hWnd,
    5.     IN      UINT uMsg,
    6.     IN      WPARAM wParam,
    7.     IN      LPARAM lParam
    8.     )
    9. {
    10.     return CallWindowProc( OldWindowProc,
    11.                            hWnd,
    12.                            uMsg,
    13.                            wParam,
    14.                            lParam );
    15. }
    вот при этом зависает программа (не могу двигать ней).

    Что здесь не так?
     
  8. Clerk

    Clerk Забанен

    Blog Posts:
    0
    AntiB
    В таблице GUI-калбэков(KernelCallbackTable что юзается из KiUserCallbackDispatcher в юзермоде) заменить соответствующий указатель на свой обработчик(либо указатель на таблицу подменить - это лучше, ибо таблица в секции кода, а указатель на неё в PEB, широко применяемый способ кстати), что вызывается при создании окна, тогда не придётся делать циклы ожидания.
    Вобщем часто возникающая ошибка - при захвате какоголибо обработчика, после отработки нового следует возвратить управление на предыдущий непосредственно, без использования апи, если новый обработчик не выполнит действия, которые должен выполнить предыдущий обработчик.
     
  9. AntiB

    AntiB New Member

    Blog Posts:
    0
    Clerk
    Спасибо!