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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> hook on closing program 
:(
    Опции темы
GremlinProg
Дата 17.8.2009, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



GoldFinch, внимательно перечитай:
Цитата(tusha @  15.8.2009,  00:20 Найти цитируемый пост)
необходимо запретить юзеру закрывать программу путем нажатия на крестик

Цитата(tusha @  17.8.2009,  12:56 Найти цитируемый пост)
юзеры иногда вместо того, чтоб свернуть , попадают по крестику

и скажи:
1. будет ли включен флаг b, если выполняется условие !a && b
2. будет ли включен флаг b, если выполняется условие !(a || b)

все просто до безобразия: b - это кнопка сворачивания, а - это кнопка закрытия
скрывая панель, ты тем самым скрываешь все кнопки, включая b, которой люди пользуются,
WS_SYSMENU работает аналогично, зачем мутить воду-то, непонимаю


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



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

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




Модератор: Сообщение скрыто.

PM MAIL ICQ   Вверх
GremlinProg
Дата 17.8.2009, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



GoldFinch, на будущее: еще хоть раз увижу подобные наезды на участников, будешь потешаться в одиночестве, и за пределами форума

опять же повторюсь, я не придираюсь к твоим советам, я просто предвосхищаю заблуждения участников, в которые ты их вводишь осознанно, и все надеюсь, что когда-нибудь совесть в тебе проснется и ты перестанешь давать советы мимо темы

"иногда лучше молчать..."©


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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



Вот полное решение ИМХО.

Код

#include <windows.h>
#include <tchar.h>

WNDPROC g_defproc;

LRESULT CALLBACK WndProc(HWND hWnd,UINT Message, UINT wParam, LONG lParam)
{
    switch(Message)
    {
    case WM_CLOSE:
        return 0;
    }
    return g_defproc(hWnd, Message, wParam, lParam);
}

int main()
{
    HWND hwnd = FindWindow( 0, _T("Калькулятор") ); // Тут можно и класс окна вписать.
    g_defproc = (WNDPROC)SetWindowLong( GWL_WNDPROC, (LONG)g_defproc );
    
    MSG msg;
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}


Добавлено через 4 минуты и 25 секунд
Хотя, хз как будет работать между процессами

Это сообщение отредактировал(а) Cheloveck - 17.8.2009, 17:20


--------------------
user posted image
PM Jabber   Вверх
GremlinProg
Дата 17.8.2009, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Cheloveck @  17.8.2009,  19:19 Найти цитируемый пост)
Хотя, хз как будет работать между процессами

эт точно,
субклассинг логичен, но для чужого процесса не подойдет


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


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

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



Цитата(Cheloveck @  17.8.2009,  18:19 Найти цитируемый пост)
Хотя, хз как будет работать между процессами
никак не будет.

tusha, во-первых сообщения могут доставляться окну не только через очередь сообщений, но и посредством прямого или опосредованного вызова оконной процедуры - хук WH_GETMESSAGE соответственно в этом случае не срабатывает. такая доставка перехватывается хуками WH_CALLWNDPROC/WH_CALLWNDPROCRET, но изменять сообщение в этих хуках нельзя.
во-вторых, и это основное - в своем обработчике хука ты не делаешь ничего для отмены сообщения.

должно быть как-то так:
Код

if(code==HC_ACTION)
{
    PMSG p = (PMSG)lParam;
    if (p->message == SC_CLOSE)
    {
        TCHAR fullname[MAX_PATH];
        ::GetModuleFileName(0, fullname, MAX_PATH);
        TCHAR *fname = _tcsrchr(fullname, '\\');
        if (fname++ && !_tcsicmp(fname, _TEXT("notepad.exe")))
        {
            MessageBoxEx(NULL,L"Unable to close application",L"ACHTUNG!",MB_ICONERROR,0);
            p->message = WM_NULL; // !!!
            return 0;
        }
    }
}
return CallNextHookEx(hhk,code,wParam,lParam);

PM MAIL   Вверх
Cheloveck
Дата 17.8.2009, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



да, проверил, моя не работать((


--------------------
user posted image
PM Jabber   Вверх
Earnest
Дата 17.8.2009, 20:32 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Может, попробовать просто задизэблить крестик?
Цитата

Use the following code to disable the Close button.
EnableMenuItem (GetSystemMenu(hwnd, FALSE), SC_CLOSE,MF_BYCOMMAND | MF_GRAYED);

Хоть речь о меню, но вроде бы та же команда активирует и крестик.
Вроде нет ту ничего такого, что между процессами работать не будет...
Разве что если целевое приложение само постоянно активирует системные команды в холостом цикле.


--------------------
...
PM   Вверх
GremlinProg
Дата 17.8.2009, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



да, Earnest, как раз то что tusha и требовалось:
Цитата(tusha @  15.8.2009,  00:20 Найти цитируемый пост)
 запретить юзеру закрывать программу путем нажатия на крестик (варианты alt+f4, taskmanager можно не учитывать)



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


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 17.7.2008

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



Код

EnableMenuItem (GetSystemMenu(hwnd, FALSE), SC_CLOSE,MF_BYCOMMAND | MF_GRAYED);

прикольно, спасибо за совет. 
однако хотелось бы чтоб визуально окно оставалось без измененийй , в данном случае у него дизеблится крестик. 

про WM_NULL додул раньше, однако как сказал тов. dumb для данного фильтра (WH_CALLWNDPROC) это отказывалось работать. будем пробовать дальше, если ниче не выйдет, то придется дизейблить крестик ))) 
PM MAIL   Вверх
tusha
Дата 2.9.2009, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 17.7.2008

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



вобщем наткнулся на такой бок(?)
(из предыдущих моих тем) запускаю следующий код:

Код

WindowName = L"Untitled - Notepad";
WinHandle = ::FindWindowW(0,WindowName);
if (WinHandle != NULL)
{
    EnableMenuItem(::GetSystemMenu((HWND)WinHandle, FALSE), SC_CLOSE, MF_ENABLED);        
        //стараюсь полюбому дать доступ к кнопке закрыть

    EnableMenuItem(::GetSystemMenu((HWND)WinHandle, FALSE), SC_CLOSE, MF_GRAYED | MF_DISABLED); // потом ее дизейблю
    SetDlgItemText(IDC_BUTTON1,L"Enable");
    ::DrawMenuBar(WinHandle);// также UpdateWindow пробовал
}

ситуация следующая: первый раз, когда блокнот висит на экране и запускается приложение - крестик стает сереньким - все как надо.
на кнопку с кодом 
Код

EnableMenuItem(::GetSystemMenu((HWND)ClientWinHandle, FALSE), SC_CLOSE, MF_ENABLED);

реагурует отлично
--------------------------------------------------
потом закрываем программу (блокнот остается с ЗАБЛОКИРОВАННЫМ крестиком) и запускаем ее снова - пробуем разблокировать крестик - ничего не получается....  smile функция же в данной ситуации возвращает всегда -1 (т.е. какбудто меню вообще нету)

в ситуации когда прогу закрываю, но крестик окна блокнота MF_ENABLED - все работает отлично 

ктонибудь сталкивался с таким? есть идеи?

Добавлено через 4 минуты и 43 секунды
еще одно маленькое уточнение - хендл окна я получаю, но рядом со значением в скобках стоит unused ????
PM MAIL   Вверх
GremlinProg
Дата 3.9.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



перед закрытием своей программы, просто вывзови:
Код

::GetSystemMenu( WinHandle, TRUE );

тогда и восстанавливать состояние кнопки не потребуется
конечно, WinHandle должен храниться на протяжении всей работы твоей программы

параметр TRUE означает, что копия системного меню, которую ты создал будет уничтожена,
а на его место будет установлено меню по-умолчанию

пока ты этого не сделаешь, системное меню невозможно будет скопировать,
т.е. ты как бы закрываешь дверь, на свой секретный код, и каждый раз этот код уникален,
но не открываешь ее вновь после работы своей программы, чтобы ее можно было закрыть повторно

это видимо просто механизм защиты от утечек ресурсов, который позволяет копировать меню только с оригинала

Добавлено через 6 минут и 52 секунды
да, кстати, не нужно вызывать GetSystemMenu всякий раз, когда тебе требуется дескриптор меню,
у тебя должно быть только 2 вызова этой функции: в начале работы с меню и в конце, перед закрытием твоей программы


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


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 17.7.2008

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



гениально) 
поставил бы +1 но кол-во постов пока не позволяет.)))
и главное что в описании EnableMenuItem нету хотя бы упоминания про этот прикол) иль я не внимательно смотрел)

ЗЫ: век живи век учись у дураком помрешь
PM MAIL   Вверх
GremlinProg
Дата 3.9.2009, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(tusha @  3.9.2009,  14:46 Найти цитируемый пост)
и главное что в описании EnableMenuItem нету хотя бы упоминания про этот прикол) иль я не внимательно смотрел)

в EnableMenuItem упоминаний и не должно быть, в GetSystemMenu должно быть, но оно несколько смазано,
в поддержке есть, только немного на другом примере: http://support.microsoft.com/kb/300688
Цитата(How to disable the Close button on the Application window and the Exit command on the File menu @  support.microsoft.com)

Please note that this technique affects the Close button on the application window of Microsoft Access, not the Close button on the Database window. After disabling these options, neither is automatically re-enabled when your database closes. If the user closes the database and leaves Microsoft Access open, the user will not be able to quit Microsoft Access by using the Close button or the Exit command on the File menu. In this case, your application should re-enable both options before it terminates. Otherwise, the user will have to quit and restart Microsoft Access in order for the Close button and the Exit command on the File menu to be enabled.


Добавлено через 12 минут и 13 секунд
хотя я поспешил,
о защите тут не говорится, просто пишут, что мол при закрытии управляющего приложения, сис. меню не будет восстановлено,
что может поставить пользователя в ступор: "как же его закрыть"


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


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 17.7.2008

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



Цитата

    bRevert
        [in] Specifies the action to be taken. If this parameter is FALSE, GetSystemMenu returns a handle to the copy of the window menu currently in use. The copy is initially identical to the window menu, but it can be modified. If this parameter is TRUE, GetSystemMenu resets the window menu back to the default state. The previous window menu, if any, is destroyed. 


http://msdn.microsoft.com/en-us/library/ms...28VS.85%29.aspx

 smile 
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.0586 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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