Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как отловить системную команду закрытия. [D7, Win95/98, WinXP]


Страницы:   1 2

LEXX_55 ©   (2005-05-30 14:28:00) 

Здраствуйте знатоки. Усть системная команда SC_MINIMIZE - свернуть окно. А какая системная команда на закрытие окна (приложения)?


LEXX_55   (2005-05-31 08:06:00) [1]

Получил нужный результат. Всем спасибо!!!


LEXX_55   (2005-05-31 08:02:00) [2]

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


LEXX_55   (2005-05-31 06:26:00) [3]

Подождите....
Почему тогда это работает?
if (Msg.WParam = SC_MINIMIZE) then MFHideClick(Self);


alpet   (2005-05-30 20:38:00) [4]

begin...end ©   (30.05.05 19:49) [22]
Мда, пожалуй надо вчитаться было:

In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.


begin...end   (2005-05-30 19:49:00) [5]

> alpet ©   (30.05.05 15:36) [11]

> if msg.WParam = SC_CLOSE

См. [6].


alpet   (2005-05-30 19:16:00) [6]

Ошибки значит в первом проекте есть. Смотри как доходит сообщение WM_SYSCOMMAND до окна формы (Spy++ / Winsight32).


LEXX_55   (2005-05-30 17:17:00) [7]


> alpet ©   (30.05.05 16:48) [18]

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


Alex870   (2005-05-30 16:58:00) [8]

Понял свою ошибку. Я использовал tagMsg, а не TMessage.


alpet   (2005-05-30 16:48:00) [9]

У тебя действительно странно код себя ведет, посмотри может ошибка где.

procedure TForm1.WMCommand(var msg: TMessage);
begin
label1.Caption := format ('WM_SYSCOMMAND, wParam = $%x, lParam = $%x',
                       [msg.wparam, msg.lparam]);
if msg.WParam = SC_CLOSE then msg.Result := 0
 else DefaultHandler (msg);
end;

У меня при перетаскивании формы (мышью за заголовок) wParam всегда равно $F012, а lParam меняется и реально означает экранные координаты курсора мыши.


Alex870   (2005-05-30 16:38:00) [10]

Выяснил (признаю, что частично ошибался) в Low-order WParam WM_SYSCOMMAND передается yPos (абсолютная) координат мыши, а в Hi - xPos. В LParam не передается ничего!!! Это конечно противоречит справке, но мне кажется тут дело в Messages.pas, мне кажется, что мы получаем что-то другое, нежели WM_SYSCOMMAND.


Alex870   (2005-05-30 16:14:00) [11]


> alpet ©   (30.05.05 16:06) [15]

А ты выведи, ну скажем на Label, значение WParam, и пощелкай по кнопке в разных местах.


alpet   (2005-05-30 16:06:00) [12]

WM_SYSCOMMAND
wParam
Specifies the type of system command requested. This parameter can be one of the following values.

lParam
The low-order word specifies the horizontal position of the cursor, in screen coordinates, if a window menu command is chosen with the mouse. Otherwise, this parameter is not used.
...


alpet   (2005-05-30 16:03:00) [13]

То есть, у меня этот код работает, а у тебя нет?


Alex870   (2005-05-30 16:03:00) [14]

Я так понял, что в WParam передается не только uCmdType, но и координаты мыши на кнопке (могу ошибаться), однако если написать if ((M.wParam and $FFF0) >= $360) and ($370 >= (M.wParam and $FFF0)) then ...для стандартного заголовка - работает.


LEXX_55   (2005-05-30 15:43:00) [15]


> alpet ©   (30.05.05 15:36) [11]

у меня почти такойже код только вместо
then msg.Result := 0
else DefaultHandle (msg);

стоит
then MFHideClick(Self);
результат одинаков.


alpet   (2005-05-30 15:36:00) [16]


type
 TForm1 = class(TForm)
...
procedure WMCommand (var msg: TMessage); message WM_SYSCOMMAND;
end
...
procedure TForm1.WMCommand(var msg: TMessage);
begin
if msg.WParam = SC_CLOSE then msg.Result := 0
 else DefaultHandle (msg);
end;


Вот так сообщение блокируется. Но лучше если обработка будет происходить через перехват оконной процедуры (см. свойство TControl.WindowProc), чтобы обработка других кодов происходила правильно.


LEXX_55   (2005-05-30 15:19:00) [17]


> Alex870   (30.05.05 15:04) [9]

форма должна закрыватья, но другим путем.


Alex870   (2005-05-30 15:04:00) [18]

А почему не использовать wm_close, ну например:

procedure MyFormClose(var M: tagMSG); message wm_close;
а там делать то, что угодно. Если Вы VCL не используете, то аналогично можно реализовать и в главной процедуре окна.


DVM   (2005-05-30 14:57:00) [19]

HWND hWnd = Form1->Handle; // здесь Handle нужного окна
HMENU hMenu = GetSystemMenu(hWnd, false);
if (hMenu)
       {
       EnableMenuItem(hMenu, SC_CLOSE, MF_GRAYED);
       }

или даже

DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);


LEXX_55   (2005-05-30 14:55:00) [20]


> begin...end ©   (30.05.05 14:53) [6]

Не хотит. Просто закрывает приложение.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо