Текущий архив: 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.48 MB
Время: 0.008 c