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

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

Координаты меню [D7, Win95/98, WinXP]


Wiz@rd ©   (2004-11-04 20:24:00) 

Как известно TrackPopupMenu показывает высплывающее меню. Внимание вопрос: Как перед показом меню узнать Rect где оно разместиться на экране?


Wiz@rd   (2004-11-06 14:27:00) [1]

Там через win2k transparency - это не то, хотя там есть пара интересных моментов. Насчёт вашего примера - конечно это круто, но опять глюк как я и думал - если расстояние до конца экрана меньше ширины экрана, то Rect даётся неправильный, ладно бы только это - меню иногда упирается не только в экран, но и во всякие тулбары, в принципе всё норм кроме этого глюка, будем искать...


easy   (2004-11-06 12:19:00) [2]

полупрозрачное меню -
http://www.codeproject.com/menu/trans_menu.asp


Wiz@rd   (2004-11-06 12:15:00) [3]

Мне надо рисовать полупрозрачное меню, поэтому надо скопировать ту часть экрана, на которой оно появится, сейчас попробую ваш способ


easy   (2004-11-05 14:53:00) [4]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Forms, Menus;

type
 TForm1 = class(TForm)
   PopupMenu1: TPopupMenu;
   Item1: TMenuItem;
   Item2: TMenuItem;
   Item3: TMenuItem;
   Item4: TMenuItem;
   Item51: TMenuItem;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
   FNewWndProc, FOldWndProc: Pointer;
   mHandle: hwnd;
   hHookID: HHOOK;
   procedure NewWndProc(var Message: TMessage);
   procedure DefineWndProc;
   procedure UnDefineWndProc(h: hwnd);
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

function HookCallWndProc(nCode: Integer; wParam, lParam: Longint): Longint; stdcall;
const
 MENU_CLASS = '#32768';
var
 cwps: TCWPStruct;
begin
 if (nCode = HC_ACTION) then
 begin
   CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));
   case cwps.message of
     WM_INITMENUPOPUP:
       begin
         with Form1 do begin
           mHandle := FindWindow(MENU_CLASS, nil);
           if (IsWindow(mHandle)) then begin
             DefineWndProc;
           end;
         end;
       end;
   end;
 end;
 Result := CallNextHookEx(WH_CALLWNDPROC, nCode, wParam, lParam);
end;

procedure TForm1.DefineWndProc;
begin
 FNewWndProc := Classes.MakeObjectInstance(NewWndProc);
 FOldWndProc := Pointer(GetWindowLong(mHandle, GWL_WNDPROC));
 SetWindowLong(mHandle, GWL_WNDPROC, Longint(FNewWndProc));
end;

procedure TForm1.NewWndProc(var Message: TMessage);
var
 r: trect;
begin
 case Message.Msg of

   WM_WINDOWPOSCHANGED: begin
       getwindowrect(mHandle, r);
       //тут лежит этот rect
       caption := 'Left:' + inttostr(r.Left) +
         ' Right:' + inttostr(r.Right) +
         ' Top:' + inttostr(r.Top) +
         ' Bottom:' + inttostr(r.Bottom);
     end;
   WM_NCDESTROY: begin
       UnDefineWndProc(mHandle);
       exit;
     end;
 end;
 Message.Result := CallWindowProc(FOldWndProc, mHandle, Message.Msg,
   Message.WParam, Message.LParam);
end;

procedure TForm1.UnDefineWndProc(h: hwnd);
begin
 SetWindowLong(h, GWL_WNDPROC, Longint(FOldWndProc));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 tpid: DWORD;
begin
 tpid := GetWindowThreadProcessId(Handle, nil);
 hHookID := SetWindowsHookEx(WH_CALLWNDPROC, HookCallWndProc, 0, tpid);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 if (hHookID <> 0) then
   UnhookWindowsHookEx(hHookID);
end;

end.


только надо-ли?

> Wiz@rd   (04.11.04 20:24) [0]

что с ректом-то потом делать?


clickmaker   (2004-11-05 14:31:00) [5]


> можно перехватить что-то типа WM_WINDOWPOSCHANGED в оконной
> процедуре PopupMenu

а как ее достать?


easy   (2004-11-05 13:32:00) [6]


> Игорь Шевченко ©   (04.11.04 21:28) [1]

туда не войдёт border

> если меню ещё нет

нет меню - нет и Rect
при WM_INITMENUPOPUP Rect TrackPopupMenu имеет размеры 100х100, по краиней мере так в 2к-ХР

> узнать Rect

можно перехватить что-то типа WM_WINDOWPOSCHANGED в оконной процедуре PopupMenu


Wiz@rd   (2004-11-04 23:41:00) [7]

да но это когда меню уже показано, если меню ещё нет, то возвращается 0, 0, 0, 0. Так что это неподходит


Игорь Шевченко   (2004-11-04 21:28:00) [8]

GetMenuItemRect для всех элементов меню не поможет ?


Наверх

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