Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.11;
Скачать: CL | DM;

Вниз

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

 
Th ©   (2003-07-08 11:00) [0]

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

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


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


 
Poirot ©   (2003-07-08 17:21) [1]

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


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

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

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


 
Th ©   (2003-07-09 12:48) [3]

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


 
DVM ©   (2003-07-09 12:53) [4]


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

> Th ©

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

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

GetSystemMenu( hSysMenuWnd , true );

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




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

DVM © (09.07.03 12:53)

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


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

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


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


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


> WM_SYSCOMMAND с SC_KEYMENU

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


 
DVM ©   (2003-07-09 13:31) [8]


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

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


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

DVM © (09.07.03 13:31)

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


 
DVM ©   (2003-07-10 10:37) [10]

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

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

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


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

DVM © (10.07.03 10:37)

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


 
Th ©   (2003-07-10 14:32) [12]

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


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

Th © (10.07.03 14:32)

DDK\win_me\inc16\windows.h



Страницы: 1 вся ветка

Текущий архив: 2003.09.11;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.02 c
3-33459
SPIRIT
2003-08-20 15:04
2003.09.11
Ошибочный аргумент


1-33596
qwerty2
2003-09-01 15:39
2003.09.11
Как узнать дату изменения файла в Windows 98?


4-33839
Antipich
2003-07-12 15:14
2003.09.11
Как сэмулировать нажатие Ctrl+V


7-33833
Antonyan
2003-06-27 12:32
2003.09.11
Exe файл


1-33608
dataMaster
2003-09-01 13:32
2003.09.11
Как запретить изменение ширины колонок в ListView