Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hook WM_CLOSE 
V
    Опции темы
ApolloKiD
Дата 9.5.2012, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 7.6.2011
Где: Молдавия

Репутация: нет
Всего: нет



Доброго времени суток всем!

Встала передо мной задача хукнуть WM_CLOSE.
Есть программа которая при нажатии на крести [x] сразу закрываеться даже не спрашивает мол "Вы действительно хотите закрыть окно, Да или нет".
Следственно исходников программы у меня тоже нету, есть только ДЛЛ которую я подключаю к этой программе.
Хук я оуществил, при нажатии на крестик выскакивает сообщение "Вы действительно хотите закрыть окно, Да или нет", но окно закрываеться даже если нажимаю "нет".
Может кто-то подсказать что я не так делаю, и что надо сделать чтобы при нажатии на кнопку "Нет" окно не закрывалось.

Вот код:
Код

HHOOK currentHook;
LRESULT CALLBACK HookProc(int nCode, WPARAM wp, LPARAM lp)
{
   CWPSTRUCT cwp = *(CWPSTRUCT *)lp;
   switch(cwp.message)
   {
   case WM_CLOSE:
        if (MessageBox(cwp.hwnd, "Вы действительно хотите закрыть окно?", "Close", MB_YESNO | MB_APPLMODAL) == IDYES)
        {
            DestroyWindow(cwp.hwnd);
        }
       break;
   default:
       return FALSE;
   }
   return CallNextHookEx(currentHook, nCode, wp, lp);
}


extern "C"
{
    __declspec(dllexport) BOOL __stdcall WINAPI DllMain (HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
    {
        switch (dwReason)
        {
        case DLL_PROCESS_ATTACH:
            currentHook = SetWindowsHookExA(WH_CALLWNDPROC, HookProc, 0, GetCurrentThreadId());
            break;
         case DLL_PROCESS_DETACH:
                        UnHookWindowsHookExA(currentHook);
            break;
        }
        return TRUE;
    }
}


Заранее спасибо!
PM MAIL   Вверх
feodorv
Дата 9.5.2012, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(ApolloKiD @  9.5.2012,  18:14 Найти цитируемый пост)
но окно закрываеться даже если нажимаю "нет".

Видимо, сообщение WM_CLOSE всё равно доходит до оконной процедуры  smile С хуком или без)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
ApolloKiD
Дата 9.5.2012, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 7.6.2011
Где: Молдавия

Репутация: нет
Всего: нет



А можно как-то сделать чтобы не доходило при нажатии кнопки "нет" ?
PM MAIL   Вверх
feodorv
Дата 9.5.2012, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(ApolloKiD @  9.5.2012,  18:14 Найти цитируемый пост)
что надо сделать

Думаю, поставить WH_GETMESSAGE хук, и при получении WM_CLOSE и отрицательного результата от MessageBox модифицировать msg так, что оно больше не было WM_CLOSE...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
ApolloKiD
Дата 9.5.2012, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 7.6.2011
Где: Молдавия

Репутация: нет
Всего: нет



А можно примером показать ? =)
PM MAIL   Вверх
GremlinProg
Дата 10.5.2012, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



может проще так:
Цитата(ApolloKiD @ 9.5.2012,  19:14)
Доброго времени суток всем!
   case WM_CLOSE:
        if (MessageBox(cwp.hwnd, "Вы действительно хотите закрыть окно?", "Close", MB_YESNO | MB_APPLMODAL) == IDYES)
        {
            DestroyWindow(cwp.hwnd);
            break;
        }
        break;
        return 0;
   default:
       return FALSE;
   }
   return CallNextHookEx(currentHook, nCode, wp, lp);




--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
feodorv
Дата 10.5.2012, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(GremlinProg @  10.5.2012,  08:32 Найти цитируемый пост)
        return 0;
   default:
       return FALSE;

А чем return 0; от return FALSE; отличается?

Цитата

WH_CALLWNDPROCRET - Installs a hook procedure that monitors messages after they have been processed by the destination window procedure.  

Полагаю, что оконная процедура уже обработала WM_CLOSE.

Это сообщение отредактировал(а) feodorv - 10.5.2012, 09:59


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
GremlinProg
Дата 10.5.2012, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(feodorv @  10.5.2012,  11:53 Найти цитируемый пост)
А чем return 0; от return FALSE отличается?

ни чем не отличается


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
feodorv
Дата 10.5.2012, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Тогда чем это поможет?

Цитата(feodorv @  10.5.2012,  10:53 Найти цитируемый пост)

WH_CALLWNDPROCRET - Installs a hook procedure that monitors messages after they have been processed by the destination window procedure.  

Полагаю, что оконная процедура уже обработала WM_CLOSE.




--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
GremlinProg
Дата 10.5.2012, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(feodorv @ 10.5.2012,  12:01)
Тогда чем это поможет?

Цитата(feodorv @  10.5.2012,  10:53 Найти цитируемый пост)

WH_CALLWNDPROCRET - Installs a hook procedure that monitors messages after they have been processed by the destination window procedure.  

Полагаю, что оконная процедура уже обработала WM_CLOSE.

а при чем тут WH_CALLWNDPROCRET?

Добавлено через 4 минуты и 56 секунд
Цитата(ApolloKiD @  9.5.2012,  19:14 Найти цитируемый пост)
ледственно исходников программы у меня тоже нету, есть только ДЛЛ которую я подключаю к этой программе.

в таком случае хук - мера лишняя,
подойдет сабклассинг главного окна из DLL


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
feodorv
Дата 10.5.2012, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(GremlinProg @  10.5.2012,  11:15 Найти цитируемый пост)
а при чем тут WH_CALLWNDPROCRET? 

Прошу прощения, не туда посмотрел)))

Цитата

WH_CALLWNDPROC - Installs a hook procedure that monitors messages before the system sends them to the destination window procedure.


То есть хук вызывается до оконной процедуры. 
Но даже так в доке написано:
Цитата

After the hook procedure returns control to the system, the message is passed to the window procedure. 

То есть WM_CLOSE всё равно уходит в оконную процедуру.


А вот на что влияет возвращаемое из хука значение - вопрос интересный.
В любом случае попробовать стоит (хотя возвращаемое значение 0 - стандартное, и вряд ли на что-то влияет). Только
Цитата(ApolloKiD @  9.5.2012,  18:14 Найти цитируемый пост)
   default:
       return FALSE;

я бы делать не стал...

Добавлено через 9 минут
Цитата(GremlinProg @  10.5.2012,  11:15 Найти цитируемый пост)
подойдет сабклассинг главного окна из DLL

 smile 

Гм. Если есть HWND главного окна...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 10.5.2012, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(ApolloKiD @  9.5.2012,  22:11 Найти цитируемый пост)
А можно примером показать ? =) 

Что-то вроде такого:
Код

LRESULT CALLBACK GetMsgHook( int nCode, WPARAM wParam, LPARAM lParam)
{
  if( nCode == HC_ACTION )
  {
    MSG *msg = (MSG *) lParam;
    if( msg->message == WM_CLOSE )
      if( MessageBox( msg->hwnd, "Вы действительно хотите закрыть окно?", "Close", MB_YESNO | MB_APPLMODAL) != IDYES )
         msg->message = WM_NULL;
  }
  return CallNextHookEx( currentHook, nCode, wParam, lParam);
}


Это сообщение отредактировал(а) feodorv - 10.5.2012, 11:13


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
ApolloKiD
Дата 11.5.2012, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 7.6.2011
Где: Молдавия

Репутация: нет
Всего: нет



Извиняюсь за опоздание..

Цитата(GremlinProg @  10.5.2012,  10:15 Найти цитируемый пост)
в таком случае хук - мера лишняя,
подойдет сабклассинг главного окна из DLL 


можно пример или ссылку где бы почитать о сабклассинге?

Цитата(feodorv @  10.5.2012,  11:10 Найти цитируемый пост)
Что-то вроде такого:


пробывал ваш метод, вообще 0 реакции..
PM MAIL   Вверх
feodorv
Дата 11.5.2012, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(ApolloKiD @  11.5.2012,  16:43 Найти цитируемый пост)
пробывал ваш метод, вообще 0 реакции.. 

Здесь нужен глобальный хук (не локальный) и знание хендла окна. Но если хендл известен, то лучше реализовать сабклассинг.

Если хендл окна неизвестен, без хука не обойтись. Выше я писал о необходимости понять, на что влияет возвращаемое из хука значение. Соответственно, можно подобрать подходящий хук. Я подобрал:
Код

#include <windows.h>

static HHOOK currentHook;

LRESULT CALLBACK CBTHook( int nCode, WPARAM wParam, LPARAM lParam)
{
  LRESULT rv = CallNextHookEx( currentHook, nCode, wParam, lParam);
  if( nCode == HCBT_SYSCOMMAND && wParam == SC_CLOSE )
    if( MessageBox( NULL, "Вы действительно хотите закрыть окно?", "Close", MB_YESNO | MB_APPLMODAL) != IDYES )
       return TRUE;
  return rv;
}

__declspec(dllexport) BOOL WINAPI DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
{
  switch (dwReason)
  {
    case DLL_PROCESS_ATTACH:
      currentHook = SetWindowsHookEx( WH_CBT, CBTHook, 0, GetCurrentThreadId());
      break;
    case DLL_PROCESS_DETACH:
      UnhookWindowsHookEx( currentHook );
      break;
  }
  return TRUE;
}


Обо всех хуках неплохо написано здесь. Может, реализуете как-нибудь иначе (трудно сказать, все ли варианты закрытия окна охватывает приведённое решение).


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
ApolloKiD
Дата 11.5.2012, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 7.6.2011
Где: Молдавия

Репутация: нет
Всего: нет



Спасибо большое, всё работает =)
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0594 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.