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

Поиск:

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


Шустрый
*


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

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



необходимо запретить юзеру закрывать программу путем нажатия на крестик (варианты alt+f4, taskmanager можно не учитывать) . както давно надыбал на Винграде тему где описывается создание простейшего клавиатурного шпиона через хуки. во тчто слепил. прошу не пинать сильно (все мы когдато учились  smile )
DLL
Код

HHOOK hhk;

LRESULT CALLBACK PreventClose(int code,WPARAM wParam,LPARAM lParam);
extern "C" __declspec(dllexport) bool SetHook(wchar_t *windowclassname, bool state);

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    return TRUE;
}

bool SetHook(wchar_t *windowclassname, bool state)
{
    HWND hWnd = FindWindowEx(NULL,NULL,windowclassname,NULL);
    if (hWnd==NULL)
        return false;

    if (state)
    {
        hhk=SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)PreventClose, (HINSTANCE)hWnd, 0);
        if (!hhk)
            return false;
        return true;
    }
    else
    {
        UnhookWindowsHookEx(hhk);
        return true;
    }    
}

LRESULT CALLBACK PreventClose(int code,WPARAM wParam,LPARAM lParam)
{ 
    if(code==HC_ACTION)
    {
        if (((CWPSTRUCT *)lParam)->message==WM_CLOSE)
            MessageBoxEx(NULL,L"Unable to close application",L"ACHTUNG!",MB_ICONERROR,0);
    }
    return CallNextHookEx(hhk,code,wParam,lParam); }



MAIN
Код

#include "stdafx.h"
#include <iostream>
#include <WINDOWS.H>

extern "C" __declspec(dllimport) bool SetHook(wchar_t *winclassname, bool _s);
using namespace std;

typedef
bool (*SETHOOK)(bool);

int _tmain(int argc, _TCHAR* argv[])
{
    wchar_t _n[]=L"Notepad";

    HINSTANCE hDll;
    hDll = LoadLibrary(L"hooking.dll");
    if(!hDll)return 0;
    MSG msg;
    
    SETHOOK sh;
    sh = (SETHOOK)GetProcAddress(hDll,"SetHook");
    cout << SetHook(_n,true);
    
    if(sh)
        sh(true);
    
    while(GetMessage(&msg,0,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    if(sh)
        sh(false);

    return 0;
}


=) вот что вышло. вобщем нифига не получается., блокнот как закрывался так и закрывается, никаких изменений.
меня смущают 1 и 3 параметры SetWindowsHookEx - правильный ли я ставлю фильтр? и как подвязать фильтр к конктретной программе? - в данном случае Notepad
натолкните на правильную мысль
буду благодарен за советы)
PM MAIL   Вверх
GoldFinch
Дата 14.8.2009, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



при WM_CLOSE
return 0;

Добавлено через 1 минуту и 4 секунды
найди нужное место в целевой проге и пропатчи его
PM MAIL ICQ   Вверх
tusha
Дата 17.8.2009, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



не, чет не получается....  smile 
при данном коде, даже хук не получаетсяя поставить. - 
Код

hhk=SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)PreventClose, (HINSTANCE)hWnd, 0);

всегда NULL

если сделать так:
Код

HINSTANCE hInst;
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    hInst=(HINSTANCE)hModule;
    return TRUE;
}
............................................................................................
hhk=SetWindowsHookEx(WH_MSGFILTER, (HOOKPROC)PreventClose, hInst,0);

хук типа ставится.. - но не понятно куда))) 

отработка же 
Код

if (((MSG *)lParam)->message==WM_CLOSE)
        {
            //MessageBoxEx(NULL,L"Unable to close application",L"ACHTUNG!",MB_ICONERROR,0);
            return 0;
        }
 по прежнему не происходит..... 
мож фильтр не правильный?
PM MAIL   Вверх
Cheloveck
Дата 17.8.2009, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

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

Зачем хуки?


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


Шустрый
*


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

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



хм, прикол в том, что из моей проги мне надо контролировать стороннее приложение (notepad, mspaint к примеру). или я чтото не до конца понимаю.... в каком контексте надо юзать 
Код

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

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



****


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

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



tusha, найди в целевой проге место где она обрабатывает сообщения, и при WM_CLOSE возвращай 0
PM MAIL ICQ   Вверх
tusha
Дата 17.8.2009, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



у меня нету исходников проги. только exe)

Добавлено через 6 минут и 47 секунд
вот что получилось на данный момент:
хук устанавливаю так:
Код

hhk=SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)PreventClose, hInst, 0);


обработка сообщений:
Код

if(code==HC_ACTION)
    {        
        if (((PMSG)lParam)->message==SC_CLOSE)        
        {
            MessageBoxEx(NULL,L"Unable to close application",L"ACHTUNG!",MB_ICONERROR,0);
            return 0;
        }
    }
    return CallNextHookEx(hhk,code,wParam,lParam); }

при закрытии блокнота АХТУНГ показыватеся )))) НО блокнот таки закрывается. + аналоггичный мессадж показывается на закрытие всех приложений (получился такой себе глобальный хук)  smile 
PM MAIL   Вверх
GoldFinch
Дата 17.8.2009, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



tusha, реверсируй этот .ехе - получишь "исходники"
для этого можно использовать отладчик, например OllyDbg
PM MAIL ICQ   Вверх
tusha
Дата 17.8.2009, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



гм... мож я не совсем правильно обрисовал задачу (или я не понимаю что до меня хотят донести =) )..
есть прога - не моя, исходников нету, менять ее НЕЛЬЗЯ (лицензия) - которая получает данные с датчиков в режиме онлайн. юзеры иногда вместо того, чтоб свернуть , попадают по крестику - тем самым прерывая получение данных.

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

получить ассемблерный код впринципе можно, а смысл?
PM MAIL   Вверх
GremlinProg
Дата 17.8.2009, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



с первым параметром проблем нет, но вот третий -  да
Цитата(tusha @  15.8.2009,  00:20 Найти цитируемый пост)
(HINSTANCE)hWnd

HINSTANCE != HWND при всем желании
Код

HINSTANCE hInst;
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    hInst = hModule;
    return TRUE;
}

bool SetHook(wchar_t *windowclassname, bool state){
...
 ThreadID = GetWindowThreadProcessId( hWnd, NULL );
 hhk=SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)PreventClose, hInst, ThreadID);
...
}

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


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



****


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

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



на самом деле, задача решается так:
Код

#include <Windows.h>

int main()
{
    HWND hwnd=FindWindowW(0,L"Калькулятор");
    SetWindowLongPtr(hwnd,GWL_STYLE,WS_VISIBLE);
    return GetLastError();
}

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


Эксперт
****


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

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



Цитата(GoldFinch @  17.8.2009,  15:11 Найти цитируемый пост)

на самом деле, задача решается так:
Код

#include <Windows.h>

int main()
{
    HWND hwnd=FindWindowW(0,L"Калькулятор");
    SetWindowLongPtr(hwnd,GWL_STYLE,WS_VISIBLE);
    return GetLastError();
}

со стилями надо экспериментировать

да, со стилями надо экспериментировать, только что, по твоему твой код делает?
Цитата(Window Styles @ MSDN)

WS_VISIBLE 
Creates a window that is initially visible.
This style can be turned on and off by using ShowWindow or SetWindowPos.


Добавлено через 4 минуты и 57 секунд
ты просто выключаешь все стили окна, причем закрыть его по прежнему можно: Alt+F4


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



****


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

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



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

избавляться от Alt+F4 ТС не надо
PM MAIL ICQ   Вверх
GremlinProg
Дата 17.8.2009, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(GoldFinch @  17.8.2009,  16:04 Найти цитируемый пост)
я тестировал свой код, он делает что надо - убирает крестик (вместе со всей строкой заголовка)

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


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



****


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

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



решение с заменой стиля - именно то которое требуется
надо посмотреть родной стиль окна (например spy++) и изменить его так, чтобы крестик пропал\заблокировался

Добавлено через 5 минут и 46 секунд
вот полностью доделанное решение
Код

#include <Windows.h>

int main()
{
    HWND hwnd=FindWindowW(0,L"Калькулятор");
    LONG_PTR style = GetWindowLongPtr(hwnd,GWL_STYLE);
    style^=WS_SYSMENU;
    SetWindowLongPtr(hwnd,GWL_STYLE,style);
    return GetLastError();
}

убирает все кнопки из строки заголовка, сохраняя все остальные стили
(строка заголовка остается)
PM MAIL ICQ   Вверх
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   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0849 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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