-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathMPPopupMenu.pas
220 lines (192 loc) · 5.46 KB
/
MPPopupMenu.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
unit MPPopupMenu;
interface
uses
Windows, Messages, SysUtils, Classes, VCL.Graphics, VCL.Controls, VCL.Forms,
VCL.Dialogs,
VCL.Menus;
type
TMenuItemClickEvent = procedure(Item: TMenuItem) of object;
TMPPopupList = class(TPopupList)
private
FActiveMenuItem: TMenuItem;
protected
constructor Create; //override;
procedure WndProc(var Message: TMessage); override;
end;
TMPPopupMenu = class(TPopupMenu)
private
FOnItemMiddleClick, FOnItemRightClick: TMenuItemClickEvent;
protected
function DispatchRC(aHandle: HMENU; aPosition: Integer): Boolean;
procedure MClick(AItem: TMenuItem);
procedure RClick(AItem: TMenuItem);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Popup(X, Y: Integer); override;
published
property OnItemMiddleClick: TMenuItemClickEvent read FOnItemMiddleClick
write FOnItemMiddleClick;
property OnItemRightClick: TMenuItemClickEvent read FOnItemRightClick
write FOnItemRightClick;
end;
TMPMenuItem = class(TMenuItem)
protected
procedure AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect;
State: TOwnerDrawState; TopLevel: Boolean); override;
end;
var
MPPopupList: TMPPopupList;
implementation
uses CommonU, CommandsClass_U;
{ TMPPopupList }
constructor TMPPopupList.Create;
begin
inherited;
FActiveMenuItem := nil;
end;
procedure TMPPopupList.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_MENURBUTTONUP:
begin
for var i := 0 to Count - 1 do
begin
var pm := TPopupMenu(Items[i]);
if (pm is TMPPopupMenu) and
(TMPPopupMenu(Items[i]).DispatchRC(Message.lParam, Message.wParam)) then
Exit;
end;
end;
WM_MENUSELECT:
begin
FActiveMenuItem := nil;
with TWMMenuSelect(Message) do
begin
// Check if popup menu is open: https://www.swissdelphicenter.ch/en/showcode.php?id=958
if not ((MenuFlag and $FFFF > 0) and (Menu = 0)) then
begin
var FindKind := fkCommand;
if MenuFlag and MF_POPUP <> 0 then
FindKind := fkHandle;
for var I := 0 to Count - 1 do
begin
var Item: HMenu;
if FindKind = fkHandle then
begin
if Menu <> 0 then
Item := GetSubMenu(Menu, IDItem)
else
begin
break; //avmaksimov
end;
end
else
Item := IDItem;
var FMenuItem := TPopupMenu(Items[I]).FindItem(Item, FindKind);
if FMenuItem <> nil then
begin
FActiveMenuItem := FMenuItem;
//inherited;
//Exit;
end;
end; // for
end; // Check if popup menu is open
//FActiveMenuItem := nil;
end; // TWMMenuSelect(Message)
inherited;
end; // WM_MENUSELECT
WM_MBUTTONDOWN:
if Assigned(FActiveMenuItem) then
begin
for var i := 0 to Count - 1 do
begin
var pm := TPopupMenu(Items[i]);
if pm is TMPPopupMenu then
TMPPopupMenu(Items[i]).MClick(FActiveMenuItem);
end;
end;
end;
inherited WndProc(Message);
end;
{ TRCPopupMenu }
constructor TMPPopupMenu.Create(AOwner: TComponent);
begin
inherited;
PopupList.Remove(Self);
MPPopupList.Add(Self);
end;
destructor TMPPopupMenu.Destroy;
begin
MPPopupList.Remove(Self);
PopupList.Add(Self);
inherited;
end;
function TMPPopupMenu.DispatchRC(aHandle: HMENU; aPosition: Integer): Boolean;
var
FParentItem: TMenuItem;
begin
Result := False;
if Handle = aHandle then
FParentItem := Items
else
FParentItem := FindItem(aHandle, fkHandle);
if FParentItem <> nil then
begin
RClick(FParentItem.Items[aPosition]);
Result := True;
end;
{ if Handle = aHandle then
begin
RClick(Items[aPosition]);
Result := True;
end; }
end;
procedure TMPPopupMenu.Popup(X, Y: Integer);
const
Flags: array [Boolean, TPopupAlignment] of Word =
((TPM_LEFTALIGN, TPM_RIGHTALIGN, TPM_CENTERALIGN),
(TPM_RIGHTALIGN, TPM_LEFTALIGN, TPM_CENTERALIGN));
//Buttons: array [TTrackButton] of Word = (TPM_RIGHTBUTTON, TPM_LEFTBUTTON);
var
AFlags: Integer;
begin
DoPopup(Self);
AFlags := Flags[UseRightToLeftAlignment, Alignment]
{ or Buttons[TrackButton] };
if (Win32MajorVersion > 4) or
((Win32MajorVersion = 4) and (Win32MinorVersion > 0)) then
begin
AFlags := AFlags or (Byte(MenuAnimation) shl 10);
AFlags := AFlags or TPM_RECURSE;
end;
TrackPopupMenuEx(Items.Handle, AFlags, X, Y, MPPopupList.Window, nil);
end;
procedure TMPPopupMenu.MClick(AItem: TMenuItem);
begin
if Assigned(FOnItemMiddleClick) then
FOnItemMiddleClick(AItem);
end;
procedure TMPPopupMenu.RClick(AItem: TMenuItem);
begin
if Assigned(FOnItemRightClick) then
FOnItemRightClick(AItem);
end;
{ var
oldPL: TPopupList; }
{ TMyMenuItem }
procedure TMPMenuItem.AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect;
State: TOwnerDrawState; TopLevel: Boolean);
begin
if (Tag <> 0) and (Count = 0) and
(TCommandData(Tag).ExtendCommandToFullName = '') then
ACanvas.Font.Style := [fsStrikeOut];
// ACanvas.Font.Color := clRed;
// ACanvas.Font.Style := [fsBold];
inherited AdvancedDrawItem(ACanvas, ARect, State, TopLevel);
end;
initialization
MPPopupList := TMPPopupList.Create;
finalization
MPPopupList.Free;
end.