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

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

Искусственный вызов Window Menu приложения


Th ©   (2003-07-08 11:00:00) 

Всегда считал, что для этого есть какая-нибудь функция API. Ан нет...
Вот какой вариант мне пришел в голову первым:

TrackPopupMenu(GetSystemMenu(Form.Handle,false),TPM_HORIZONTAL or TPM_VERTICAL,p.X,p.Y,0,Handle,0);


Довольно бестолковый по моему (проблем много с тем, что надо делать недоступными определенные елементы меню и проч.). Больше ничего не придумывается. Подскажите плз, как еще это можно сделать?


Игорь Шевченко   (2003-07-10 15:08:00) [1]

Th © (10.07.03 14:32)

DDK\win_me\inc16\windows.h


Th   (2003-07-10 14:32:00) [2]

Спасибо, а сообщение то похоже недокументировано.


Игорь Шевченко   (2003-07-10 10:54:00) [3]

DVM © (10.07.03 10:37)

Точно. Спасибо. Сообщение называется WM_SYSMENU


DVM   (2003-07-10 10:37:00) [4]

Вот это сообщение.

postmessage(hWnd, $313, 0, MakeLong(X,Y)) ;

Ну здесь все остальное, я думаю, понятно, hWnd - хэндл того окна, от которого системное меню, (X, Y) - координаты появления (относительно экрана).


Игорь Шевченко   (2003-07-09 14:15:00) [5]

DVM © (09.07.03 13:31)

Если свернуто - меню не вызовется, очевидно. А с сообщением мне самому интересно стало, найдешь - сообщи


DVM   (2003-07-09 13:31:00) [6]


> Игорь Шевченко © (09.07.03 13:00)
> Но вообще-то системное меню окна вызывается через Atl+пробел,
> может, просто послать окну сообщения о нажатии этих клавиш
> ?

А если окно свернуто? Или еще что?


DVM   (2003-07-09 13:29:00) [7]


> Игорь Шевченко ©


> WM_SYSCOMMAND с SC_KEYMENU

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


Игорь Шевченко   (2003-07-09 13:00:00) [8]

Но вообще-то системное меню окна вызывается через Atl+пробел, может, просто послать окну сообщения о нажатии этих клавиш ?


Игорь Шевченко   (2003-07-09 12:57:00) [9]

DVM © (09.07.03 12:53)

Не WM_SYSCOMMAND с SC_KEYMENU случайно ?


DVM   (2003-07-09 12:53:00) [10]


> Th © ( не помню номер, оно у меня дома)


> Th ©

Есть сообщение какое-то (не помню номер, оно у меня дома) для вызова системного меню окна. У того способа, что написан выше есть один большой недостаток: если само приложение что-то мухлюет со своим системным меню, то эти изменения (дополнительные пункты меню и т.д.) не отображаются этой функцией.

Собственные пункты меню можно захватить и этой функцией, убрав строчку:

GetSystemMenu( hSysMenuWnd , true );

Но тогда меню почему-то вызывается через раз.



Th   (2003-07-09 12:48:00) [11]

To DVM Огромное спасибо! А что за способ еще лучше, если не секрет?


DVM   (2003-07-09 12:36:00) [12]

procedure ShowSystemMenu( hSysMenuWnd , hWnd : HWND ; ptCursorPos: TPoint);
var
LItem : LongWord;
hSystemMenu : HMENU;
WP : WINDOWPLACEMENT;
begin
GetSystemMenu( hSysMenuWnd , true );
hSystemMenu := GetSystemMenu( hSysMenuWnd , false );
if hSystemMenu = 0 then exit;
WP.length := SizeOf( WINDOWPLACEMENT );
GetWindowPlacement( hSysMenuWnd, @WP );
case WP.showCmd of
SW_SHOWNORMAL :
begin
EnableMenuItem( hSystemMenu , SC_RESTORE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MOVE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_SIZE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MINIMIZE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MAXIMIZE , MF_BYCOMMAND or MF_ENABLED );
end; // SW_SHOWNORMAL
SW_SHOWMINIMIZED :
begin
EnableMenuItem( hSystemMenu , SC_RESTORE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MOVE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_SIZE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MINIMIZE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MAXIMIZE , MF_BYCOMMAND or MF_ENABLED );
end; // SW_SHOWMINIMIZED
SW_SHOWMAXIMIZED :
begin
EnableMenuItem( hSystemMenu , SC_RESTORE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MOVE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_SIZE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MINIMIZE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MAXIMIZE , MF_BYCOMMAND or MF_GRAYED );
end; // SW_SHOWMAXIMIZED
end; // case
SendMessage( hSysMenuWnd , WM_INITMENUPOPUP , WPARAM( hSystemMenu ), MAKELPARAM( 0 , 1 ) );
SendMessage( hSysMenuWnd , WM_INITMENU , WPARAM( hSystemMenu ) , 0 );
LItem := LongWord( Windows.TrackPopupMenu( hSystemMenu , TPM_RIGHTBUTTON or
TPM_RETURNCMD , ptCursorPos.X , ptCursorPos.y , 0 , hWnd , nil ) );
if LItem > 0 then
begin
if ( LItem <> SC_MINIMIZE ) and ( LItem <> SC_CLOSE ) then SetForegroundWindow( hSysMenuWnd );
PostMessage( hSysMenuWnd, WM_SYSCOMMAND, LItem, MAKELPARAM( ptCursorPos.x, ptCursorPos.y ) );
( hSystemMenu)

procedure ShowSystemMenu( hSysMenuWnd , hWnd : HWND ; ptCursorPos: TPoint);
var
LItem : LongWord;
hSystemMenu : HMENU;
WP : WINDOWPLACEMENT;
begin
GetSystemMenu( hSysMenuWnd , true );
hSystemMenu := GetSystemMenu( hSysMenuWnd , false );
if hSystemMenu = 0 then exit;
WP.length := SizeOf( WINDOWPLACEMENT );
GetWindowPlacement( hSysMenuWnd, @WP );
case WP.showCmd of
SW_SHOWNORMAL :
begin
EnableMenuItem( hSystemMenu , SC_RESTORE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MOVE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_SIZE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MINIMIZE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MAXIMIZE , MF_BYCOMMAND or MF_ENABLED );
end; // SW_SHOWNORMAL
SW_SHOWMINIMIZED :
begin
EnableMenuItem( hSystemMenu , SC_RESTORE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MOVE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_SIZE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MINIMIZE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MAXIMIZE , MF_BYCOMMAND or MF_ENABLED );
end; // SW_SHOWMINIMIZED
SW_SHOWMAXIMIZED :
begin
EnableMenuItem( hSystemMenu , SC_RESTORE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MOVE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_SIZE , MF_BYCOMMAND or MF_GRAYED );
EnableMenuItem( hSystemMenu , SC_MINIMIZE , MF_BYCOMMAND or MF_ENABLED );
EnableMenuItem( hSystemMenu , SC_MAXIMIZE , MF_BYCOMMAND or MF_GRAYED );
end; // SW_SHOWMAXIMIZED
end; // case
SendMessage( hSysMenuWnd , WM_INITMENUPOPUP , WPARAM( hSystemMenu ), MAKELPARAM( 0 , 1 ) );
SendMessage( hSysMenuWnd , WM_INITMENU , WPARAM( hSystemMenu ) , 0 );
LItem := LongWord( Windows.TrackPopupMenu( hSystemMenu , TPM_RIGHTBUTTON or
TPM_RETURNCMD , ptCursorPos.X , ptCursorPos.y , 0 , hWnd , nil ) );
if LItem > 0 then
begin
if ( LItem <> SC_MINIMIZE ) and ( LItem <> SC_CLOSE ) then SetForegroundWindow( hSysMenuWnd );
PostMessage( hSysMenuWnd, WM_SYSCOMMAND, LItem, MAKELPARAM( ptCursorPos.x, ptCursorPos.y ) );
end; // if
DestroyMenu( hSystemMenu );
end; // End of procedure ShowSystemMenu

Есть правда способ еще лучше.


Poirot   (2003-07-08 17:21:00) [13]

А что тут такого - помоему так и можно!


Наверх

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