SHOW:
|
|
- or go back to the newest paste.
1 | ' SystemMenu Manager | |
2 | ' | |
3 | - | ' // By Elektor H@cker |
3 | + | ' // By Elektro H@cker |
4 | ||
5 | #Region " SystemMenu Manager " | |
6 | ||
7 | Public Class SystemMenuManager | |
8 | Inherits NativeWindow | |
9 | Implements IDisposable | |
10 | ||
11 | ' ---------------------------- | |
12 | ' MSDN documentation Reference | |
13 | ' ---------------------------- | |
14 | ' Menu Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/ff468865%28v=vs.85%29.aspx | |
15 | ' MenuItemInfo : http://msdn.microsoft.com/en-us/library/windows/desktop/ms647578%28v=vs.85%29.aspx | |
16 | ' MenuInfo : http://msdn.microsoft.com/en-us/library/windows/desktop/ms647575%28v=vs.85%29.aspx | |
17 | ||
18 | #Region " Variables " | |
19 | ||
20 | ''' <summary> | |
21 | ''' The form for which the system menu will be managed. | |
22 | ''' </summary> | |
23 | Private WithEvents form As Form = Nothing | |
24 | ||
25 | ''' <summary> | |
26 | ''' The handle of the form's system menu. | |
27 | ''' </summary> | |
28 | Private MenuHandle As IntPtr = IntPtr.Zero | |
29 | ||
30 | ''' <summary> | |
31 | ''' Stores a MenuInfo structure. | |
32 | ''' </summary> | |
33 | Private mi As New MenuInfo | |
34 | ||
35 | ''' <summary> | |
36 | ''' Stores a menuiteminfo structure. | |
37 | ''' </summary> | |
38 | Private mii As New MenuItemInfo | |
39 | ||
40 | ''' <summary> | |
41 | ''' Stores a menu item Text. | |
42 | ''' </summary> | |
43 | Private ItemText As New System.Text.StringBuilder With {.Capacity = 260} | |
44 | ||
45 | ''' <summary> | |
46 | ''' Brush used to paint the menu background. | |
47 | ''' </summary> | |
48 | Private MenuBrush As IntPtr = IntPtr.Zero | |
49 | ||
50 | ''' <summary> | |
51 | ''' Stores the ItemClickedEventArgs members. | |
52 | ''' </summary> | |
53 | Private ItemClickedArgs As New ItemClickedEventArgs | |
54 | ||
55 | ''' <summary> | |
56 | ''' The State of the Close item. | |
57 | ''' </summary> | |
58 | Private CloseItem_State As ItemState = ItemState.Enabled | |
59 | ||
60 | ''' <summary> | |
61 | ''' Stores the current state of each MenuItem. | |
62 | ''' </summary> | |
63 | Private ItemStates As New Dictionary(Of Item, ItemState) From | |
64 | { | |
65 | {Item.Close, Nothing}, | |
66 | {Item.Move, Nothing}, | |
67 | {Item.Maximize, Nothing}, | |
68 | {Item.Minimize, Nothing}, | |
69 | {Item.Restore, Nothing}, | |
70 | {Item.Size, Nothing} | |
71 | } | |
72 | ||
73 | ''' <summary> | |
74 | ''' Stores the Bitmap image of each MenuItem. | |
75 | ''' </summary> | |
76 | Private ItemBitmaps As New Dictionary(Of Item, Bitmap) From | |
77 | { | |
78 | {Item.Close, Nothing}, | |
79 | {Item.Move, Nothing}, | |
80 | {Item.Maximize, Nothing}, | |
81 | {Item.Minimize, Nothing}, | |
82 | {Item.Restore, Nothing}, | |
83 | {Item.Size, Nothing} | |
84 | } | |
85 | ||
86 | ''' <summary> | |
87 | ''' Stores the current state of each MenuItem specified by position. | |
88 | ''' </summary> | |
89 | Private PositionItemStates As New Dictionary(Of Integer, ItemState) | |
90 | ||
91 | ''' <summary> | |
92 | ''' Stores the Bitmap image of each MenuItem specified by position. | |
93 | ''' </summary> | |
94 | Private PositionItemBitmaps As New Dictionary(Of Integer, Bitmap) | |
95 | ||
96 | #End Region ' Variables | |
97 | ||
98 | #Region " Events " | |
99 | ||
100 | ''' <summary> | |
101 | ''' Event raised when a menu item is clicked. | |
102 | ''' </summary> | |
103 | Public Event ItemClicked As EventHandler(Of ItemClickedEventArgs) | |
104 | Public Class ItemClickedEventArgs : Inherits EventArgs | |
105 | ''' <summary> | |
106 | ''' Item Identifier. | |
107 | ''' </summary> | |
108 | Public Property ID As Integer | |
109 | ''' <summary> | |
110 | ''' Item Text. | |
111 | ''' </summary> | |
112 | Public Property Text As String | |
113 | ''' <summary> | |
114 | ''' Item State. | |
115 | ''' </summary> | |
116 | Public Property State As ItemState | |
117 | ''' <summary> | |
118 | ''' Item Type. | |
119 | ''' </summary> | |
120 | Public Property Type As ItemType | |
121 | End Class | |
122 | ||
123 | #End Region ' Events | |
124 | ||
125 | #Region " Enumerations " | |
126 | ||
127 | ''' <summary> | |
128 | ''' The menu Position ttype. | |
129 | ''' </summary> | |
130 | Public Enum ItemPosition As Integer | |
131 | ||
132 | ''' <summary> | |
133 | ''' The menu item is specified by command. | |
134 | ''' </summary> | |
135 | ByCommand = &H0 | |
136 | ||
137 | ''' <summary> | |
138 | ''' The menu item is specified by position. | |
139 | ''' </summary> | |
140 | ByPosition = &H410 | |
141 | ||
142 | End Enum | |
143 | ||
144 | ''' <summary> | |
145 | ''' The Menu Items. | |
146 | ''' </summary> | |
147 | Public Enum Item As Integer | |
148 | ||
149 | ''' <summary> | |
150 | ''' Closes the window. | |
151 | ''' </summary> | |
152 | Close = &HF060 | |
153 | ||
154 | ''' <summary> | |
155 | ''' Moves the window. | |
156 | ''' </summary> | |
157 | Move = &HF010 | |
158 | ||
159 | ''' <summary> | |
160 | ''' Maximizes the window. | |
161 | ''' </summary> | |
162 | Maximize = &HF030 | |
163 | ||
164 | ''' <summary> | |
165 | ''' Minimizes the window. | |
166 | ''' </summary> | |
167 | Minimize = &HF020 | |
168 | ||
169 | ''' <summary> | |
170 | ''' Restores the window to its normal position and size. | |
171 | ''' </summary> | |
172 | Restore = &HF120 | |
173 | ||
174 | ''' <summary> | |
175 | ''' Sizes the window. | |
176 | ''' </summary> | |
177 | Size = &HF000 | |
178 | ||
179 | End Enum | |
180 | ||
181 | ''' <summary> | |
182 | ''' The states that a menu item can have. | |
183 | ''' </summary> | |
184 | Public Enum ItemState As Integer | |
185 | ||
186 | ''' <summary> | |
187 | ''' The menu item is present and can be selected. | |
188 | ''' </summary> | |
189 | ''' <remarks> | |
190 | ''' This is the default state. | |
191 | ''' </remarks> | |
192 | Enabled = &H0 | |
193 | ||
194 | ''' <summary> | |
195 | ''' The menu item is present but greyed-out and cannot be selected. | |
196 | ''' </summary> | |
197 | Grayed = &H1 | |
198 | ||
199 | ''' <summary> | |
200 | ''' The menu item is present but can not be selected. | |
201 | ''' </summary> | |
202 | Disabled = &H2 | |
203 | ||
204 | ''' <summary> | |
205 | ''' The menu item is not present. | |
206 | ''' </summary> | |
207 | Removed = -1 | |
208 | ||
209 | End Enum | |
210 | ||
211 | ''' <summary> | |
212 | ''' Predefined menu item positions. | |
213 | ''' </summary> | |
214 | Public Enum DefaultPositions As Short | |
215 | ||
216 | ''' <summary> | |
217 | ''' Top position. | |
218 | ''' </summary> | |
219 | First = 0 | |
220 | ||
221 | ''' <summary> | |
222 | ''' Second position. | |
223 | ''' </summary> | |
224 | Second = 1 | |
225 | ||
226 | ''' <summary> | |
227 | ''' Third position. | |
228 | ''' </summary> | |
229 | Third = 2 | |
230 | ||
231 | ''' <summary> | |
232 | ''' Middle position. | |
233 | ''' </summary> | |
234 | Middle = 3 | |
235 | ||
236 | ''' <summary> | |
237 | ''' Penultimate position. | |
238 | ''' </summary> | |
239 | Penultimate = 4 | |
240 | ||
241 | ''' <summary> | |
242 | ''' Bottom position. | |
243 | ''' </summary> | |
244 | Last = 5 | |
245 | ||
246 | End Enum | |
247 | ||
248 | ''' <summary> | |
249 | ''' Mask type of the MenuItemInfo structure. | |
250 | ''' </summary> | |
251 | Public Enum ItemMask As Integer | |
252 | ||
253 | ''' <summary> | |
254 | ''' Retrieves or sets the "hbmpItem" member. | |
255 | ''' </summary> | |
256 | BITMAP = &H80 | |
257 | ||
258 | ''' <summary> | |
259 | ''' Retrieves or sets the "hbmpChecked" and "hbmpUnchecked" members. | |
260 | ''' </summary> | |
261 | CHECKMARKS = &H8 | |
262 | ||
263 | ''' <summary> | |
264 | ''' Retrieves or sets the "dwItemData" member. | |
265 | ''' </summary> | |
266 | DATA = &H20 | |
267 | ||
268 | ''' <summary> | |
269 | ''' Retrieves or sets the "fType" member. | |
270 | ''' </summary> | |
271 | FTYPE = &H100 | |
272 | ||
273 | ''' <summary> | |
274 | ''' Retrieves or sets the "wID" member. | |
275 | ''' </summary> | |
276 | ID = &H2 | |
277 | ||
278 | ''' <summary> | |
279 | ''' Retrieves or sets the "fState" member. | |
280 | ''' </summary> | |
281 | STATE = &H1 | |
282 | ||
283 | ''' <summary> | |
284 | ''' Retrieves or sets the "dwTypeData" member. | |
285 | ''' </summary> | |
286 | TEXT = &H40 | |
287 | ||
288 | ''' <summary> | |
289 | ''' Retrieves or sets the "hSubMenu" member. | |
290 | ''' </summary> | |
291 | SUBMENU = &H4 | |
292 | ||
293 | ''' <summary> | |
294 | ''' Retrieves or sets the "fType" and "dwTypeData" members. | |
295 | ''' "ItemMask.TYPE" is replaced by "ItemMask.BITMAP", "ItemMask.FTYPE", and "ItemMask.TEXT". | |
296 | ''' </summary> | |
297 | TYPE = &H10 | |
298 | ||
299 | End Enum | |
300 | ||
301 | ''' <summary> | |
302 | ''' Item Type of the MenuItemInfo structure. | |
303 | ''' </summary> | |
304 | Public Enum ItemType As Long | |
305 | ||
306 | ''' <summary> | |
307 | ''' Displays the menu item using a bitmap. | |
308 | ''' The low-order word of the dwTypeData member is the bitmap handle, and the cch member is ignored. | |
309 | ''' "ItemType.BITMAP" is replaced by "ItemMask.BITMAP" and "hbmpItem". | |
310 | ''' </summary> | |
311 | BITMAP = &H4L | |
312 | ||
313 | ''' <summary> | |
314 | ''' Displays selected menu items using a radio-button mark instead of a check mark if the hbmpChecked member is NULL. | |
315 | ''' </summary> | |
316 | RADIOCHECK = &H200L | |
317 | ||
318 | ''' <summary> | |
319 | ''' Specifies that the menu item is a separator. | |
320 | ''' A menu item separator appears as a horizontal dividing line. | |
321 | ''' The dwTypeData and cch members are ignored. | |
322 | ''' This value is valid only in a drop-down menu, submenu, or shortcut menu. | |
323 | ''' </summary> | |
324 | SEPARATOR = &H800L | |
325 | ||
326 | ''' <summary> | |
327 | ''' Displays the menu item using a text string. | |
328 | ''' The dwTypeData member is the pointer to a null-terminated string, | |
329 | ''' and the cch member is the length of the string. | |
330 | ''' "ItemType.TEXT" is replaced by "ItemMask.TEXT". | |
331 | ''' </summary> | |
332 | TEXT = &H0L | |
333 | ||
334 | ''' <summary> | |
335 | ''' Right-justifies the menu item and any subsequent items. | |
336 | ''' This value is valid only if the menu item is in a menu bar. | |
337 | ''' </summary> | |
338 | RIGHTJUSTIFY = &H4000L | |
339 | ||
340 | ''' <summary> | |
341 | ''' Specifies that menus cascade right-to-left (the default is left-to-right). | |
342 | ''' This is used to support right-to-left languages, such as Arabic and Hebrew. | |
343 | ''' </summary> | |
344 | RIGHTORDER = &H2000L | |
345 | ||
346 | ''' <summary> | |
347 | ''' Places the menu item on a new line (for a menu bar), | |
348 | ''' or in a new column (for a drop-down menu, submenu, or shortcut menu). | |
349 | ''' For a drop-down menu, submenu, or shortcut menu, a vertical line separates the new column from the old. | |
350 | ''' </summary> | |
351 | MENUBARBREAK = &H20L | |
352 | ||
353 | ''' <summary> | |
354 | ''' Places the menu item on a new line (for a menu bar), | |
355 | ''' or in a new column (for a drop-down menu, submenu, or shortcut menu). | |
356 | ''' For a drop-down menu, submenu, or shortcut menu, the columns are not separated by a vertical line. | |
357 | ''' </summary> | |
358 | MENUBREAK = &H40L | |
359 | ||
360 | ''' <summary> | |
361 | ''' Assigns responsibility for drawing the menu item to the window that owns the menu. | |
362 | ''' The window receives a "WM_MEASUREITEM" message before the menu is displayed for the first time, | |
363 | ''' and a "WM_DRAWITEM" message whenever the appearance of the menu item must be updated. | |
364 | ''' If this value is specified, the dwTypeData member contains an application-defined value. | |
365 | ''' </summary> | |
366 | OWNERDRAW = &H100L | |
367 | ||
368 | End Enum | |
369 | ||
370 | ''' <summary> | |
371 | ''' Mask type of the MenuInfo structure. | |
372 | ''' Indicates the members to be retrieved or set (except for "MenuMask.APPLYTOSUBMENUS"). | |
373 | ''' This member can be one or more of the following values. | |
374 | ''' </summary> | |
375 | Public Enum MenuMask As Integer | |
376 | ||
377 | ''' <summary> | |
378 | ''' Settings apply to the menu and all of its submenus. | |
379 | ''' "SetMenuInfo" API function uses this flag and "GetMenuInfo" API function ignores this flag. | |
380 | ''' </summary> | |
381 | APPLYTOSUBMENUS = &H80000000 | |
382 | ||
383 | ''' <summary> | |
384 | ''' Retrieves or sets the hbrBack member. | |
385 | ''' </summary> | |
386 | BACKGROUND = &H2 | |
387 | ||
388 | ''' <summary> | |
389 | ''' Retrieves or sets the dwContextHelpID member. | |
390 | ''' </summary> | |
391 | HELPID = &H4 | |
392 | ||
393 | ''' <summary> | |
394 | ''' Retrieves or sets the cyMax member. | |
395 | ''' </summary> | |
396 | MAXHEIGHT = &H1 | |
397 | ||
398 | ''' <summary> | |
399 | ''' Retrieves or sets the dwMenuData member. | |
400 | ''' </summary> | |
401 | MENUDATA = &H8 | |
402 | ||
403 | ''' <summary> | |
404 | ''' Retrieves or sets the dwStyle member. | |
405 | ''' </summary> | |
406 | STYLE = &H10 | |
407 | ||
408 | End Enum | |
409 | ||
410 | ''' <summary> | |
411 | ''' The menu style. | |
412 | ''' This member can be one or more of the following values. | |
413 | ''' </summary> | |
414 | Public Enum MenuStyle As Integer | |
415 | ||
416 | ''' <summary> | |
417 | ''' Menu automatically ends when mouse is outside the menu for approximately 10 seconds.. | |
418 | ''' </summary> | |
419 | AUTODISMIS = &H10000000 | |
420 | ||
421 | ''' <summary> | |
422 | ''' The same space is reserved for the check mark and the bitmap. | |
423 | ''' If the check mark is drawn, the bitmap is not. | |
424 | ''' All checkmarks and bitmaps are aligned. | |
425 | ''' Used for menus where some items use checkmarks and some use bitmaps. | |
426 | ''' </summary> | |
427 | CHECKORBMP = &H4000000 | |
428 | ||
429 | ''' <summary> | |
430 | ''' Menu items are OLE drop targets or drag sources. | |
431 | ''' Menu owner receives "WM_MENUDRAG" and "WM_MENUGETOBJECT" messages. | |
432 | ''' </summary> | |
433 | DRAGDROP = &H20000000 | |
434 | ||
435 | ''' <summary> | |
436 | ''' Menu is modeless; that is, | |
437 | ''' there is no menu modal message loop while the menu is active. | |
438 | ''' </summary> | |
439 | MODELESS = &H40000000 | |
440 | ||
441 | ''' <summary> | |
442 | ''' No space is reserved to the left of an item for a check mark. | |
443 | ''' The item can still be selected, but the check mark will not appear next to the item. | |
444 | ''' </summary> | |
445 | NOCHECK = &H80000000 | |
446 | ||
447 | ''' <summary> | |
448 | ''' Menu owner receives a "WM_MENUCOMMAND" message, | |
449 | ''' instead of a "WM_COMMAND" message, when the user makes a selection. | |
450 | ''' "MenuStyle.NOTIFYBYPOS" is a menu header style and has no effect when applied to individual sub menus. | |
451 | ''' </summary> | |
452 | NOTIFYBYPOS = &H8000000 | |
453 | ||
454 | End Enum | |
455 | ||
456 | #End Region ' Enumerations | |
457 | ||
458 | #Region " APIs " | |
459 | ||
460 | '''' <summary> | |
461 | '''' Creates an empty menu. | |
462 | '''' </summary> | |
463 | ' <Runtime.InteropServices. | |
464 | ' DllImport("user32.dll")> | |
465 | ' Private Shared Function CreateMenu() As IntPtr | |
466 | ' End Function | |
467 | ||
468 | '''' <summary> | |
469 | '''' Assigns a new menu to the specified window. | |
470 | '''' </summary> | |
471 | '<DllImport("user32.dll")> _ | |
472 | 'Public Shared Function SetMenu( | |
473 | ' ByVal hWnd As IntPtr, | |
474 | ' ByVal hMenu As IntPtr | |
475 | ') As Boolean | |
476 | 'End Function | |
477 | ||
478 | ''' <summary> | |
479 | ''' Gets the handle of the form's system menu. | |
480 | ''' </summary> | |
481 | ''' <param name="hWnd"> | |
482 | ''' The handle of the form for which to get the system menu. | |
483 | ''' </param> | |
484 | ''' <param name="bRevert"> | |
485 | ''' Indicates whether the menu should be reset to its original state. | |
486 | ''' </param> | |
487 | ''' <returns> | |
488 | ''' The handle of the system menu of the specified form. | |
489 | ''' </returns> | |
490 | <Runtime.InteropServices. | |
491 | DllImport("user32.dll")> | |
492 | Private Shared Function GetSystemMenu( | |
493 | ByVal hWnd As IntPtr, | |
494 | ByVal bRevert As Integer | |
495 | ) As IntPtr | |
496 | End Function | |
497 | ||
498 | ''' <summary> | |
499 | ''' Sets the state of the specified menu item. | |
500 | ''' </summary> | |
501 | ''' <returns> | |
502 | ''' The previous state of the menu item if it exists, -1 otherwise. | |
503 | ''' </returns> | |
504 | <Runtime.InteropServices. | |
505 | DllImport("user32.dll")> | |
506 | Private Shared Function EnableMenuItem( | |
507 | ByVal hMenu As IntPtr, | |
508 | ByVal wIDEnableItem As UInteger, | |
509 | ByVal wEnable As UInteger | |
510 | ) As IntPtr | |
511 | End Function | |
512 | ||
513 | ''' <summary> | |
514 | ''' Determines the number of items in the specified menu. | |
515 | ''' </summary> | |
516 | <Runtime.InteropServices. | |
517 | DllImport("user32.dll")> | |
518 | Private Shared Function GetMenuItemCount( | |
519 | ByVal hMenu As IntPtr | |
520 | ) As Integer | |
521 | End Function | |
522 | ||
523 | ''' <summary> | |
524 | ''' Associates the specified bitmap with a menu item. | |
525 | ''' Whether the menu item is selected or clear, | |
526 | ''' the system displays the appropriate bitmap next to the menu item. | |
527 | ''' </summary> | |
528 | <Runtime.InteropServices. | |
529 | DllImport("user32.dll")> | |
530 | Private Shared Function SetMenuItemBitmaps( | |
531 | ByVal hMenu As IntPtr, | |
532 | ByVal uPosition As UInteger, | |
533 | ByVal uFlags As UInteger, | |
534 | ByVal hBitmapUnchecked As IntPtr, | |
535 | ByVal hBitmapChecked As IntPtr | |
536 | ) As Boolean | |
537 | End Function | |
538 | ||
539 | ''' <summary> | |
540 | ''' Destroys the specified menu and frees any memory that the menu occupies. | |
541 | ''' </summary> | |
542 | <Runtime.InteropServices. | |
543 | DllImport("user32.dll")> | |
544 | Private Shared Function DestroyMenu( | |
545 | ByVal hMenu As IntPtr | |
546 | ) As Boolean | |
547 | End Function | |
548 | ||
549 | ''' <summary> | |
550 | ''' Determines whether a handle is a menu handle. | |
551 | ''' </summary> | |
552 | <Runtime.InteropServices. | |
553 | DllImport("user32.dll")> | |
554 | Private Shared Function IsMenu( | |
555 | ByVal hMenu As IntPtr | |
556 | ) As Boolean | |
557 | End Function | |
558 | ||
559 | ''' <summary> | |
560 | ''' Insert a menu item into an existing menu. | |
561 | ''' </summary> | |
562 | <Runtime.InteropServices. | |
563 | DllImport("user32.dll", | |
564 | SetLastError:=True, | |
565 | CharSet:=Runtime.InteropServices.CharSet.Auto)> | |
566 | Friend Shared Function InsertMenuItem( | |
567 | ByVal hMenu As IntPtr, ByVal uItem As Integer, | |
568 | ByVal fByPosition As Boolean, | |
569 | ByRef lpmii As MenuItemInfo | |
570 | ) As Boolean | |
571 | End Function | |
572 | ||
573 | ''' <summary> | |
574 | ''' Deletes the specified menu item. | |
575 | ''' </summary> | |
576 | ''' <returns> | |
577 | ''' Non-zero if the function succeeds, | |
578 | ''' zero otherwise. | |
579 | ''' </returns> | |
580 | <Runtime.InteropServices. | |
581 | DllImport("user32.dll")> | |
582 | Private Shared Function DeleteMenu( | |
583 | ByVal hMenu As IntPtr, | |
584 | ByVal uPosition As UInteger, | |
585 | ByVal uFlags As UInteger | |
586 | ) As Boolean | |
587 | End Function | |
588 | ||
589 | ''' <summary> | |
590 | ''' Ends the calling thread's active menu | |
591 | ''' </summary> | |
592 | <Runtime.InteropServices. | |
593 | DllImport("user32.dll")> | |
594 | Private Shared Function EndMenu() As Boolean | |
595 | End Function | |
596 | ||
597 | ''' <summary> | |
598 | ''' Gets the ID of a menu item. | |
599 | ''' </summary> | |
600 | <Runtime.InteropServices. | |
601 | DllImport("user32.dll")> | |
602 | Public Shared Function GetMenuItemID( | |
603 | ByVal hMenu As IntPtr, | |
604 | ByVal nPos As Integer | |
605 | ) As Integer | |
606 | End Function | |
607 | ||
608 | ''' <summary> | |
609 | ''' Gets the text of a menu item. | |
610 | ''' </summary> | |
611 | <Runtime.InteropServices. | |
612 | DllImport("user32.dll")> | |
613 | Private Shared Function GetMenuString( | |
614 | ByVal hMenu As IntPtr, | |
615 | ByVal uIDItem As UInteger, | |
616 | <Runtime.InteropServices.Out, | |
617 | Runtime.InteropServices.MarshalAs( | |
618 | Runtime.InteropServices.UnmanagedType.LPStr)> | |
619 | ByVal lpString As System.Text.StringBuilder, | |
620 | ByVal nMaxCount As Integer, | |
621 | ByVal uFlag As UInteger | |
622 | ) As Integer | |
623 | End Function | |
624 | ||
625 | ''' <summary> | |
626 | ''' Gets the State of a menu item. | |
627 | ''' </summary> | |
628 | <Runtime.InteropServices. | |
629 | DllImport("user32.dll")> | |
630 | Private Shared Function GetMenuState( | |
631 | ByVal hMenu As IntPtr, | |
632 | ByVal uId As UInteger, | |
633 | ByVal uFlags As UInteger | |
634 | ) As UInteger | |
635 | End Function | |
636 | ||
637 | ''' <summary> | |
638 | ''' Gets the handle of the form's system menu. | |
639 | ''' </summary> | |
640 | ''' <param name="hMenu"> | |
641 | ''' The handle to the menu that contains the menu item. | |
642 | ''' </param> | |
643 | ''' <param name="uItem"> | |
644 | ''' The identifier or position of the menu item to get information about. | |
645 | ''' The meaning of this parameter depends on the value of fByPosition. | |
646 | ''' </param> | |
647 | ''' <param name="fByPosition"> | |
648 | ''' The meaning of uItem. | |
649 | ''' If this parameter is FALSE, uItem is a menu item identifier, | |
650 | ''' If this parameter is TRUE, it is a menu item position. | |
651 | ''' </param> | |
652 | ''' <param name="lpmii"> | |
653 | ''' A pointer to a MenuItemInfo structure that specifies the information to retrieve. | |
654 | ''' Note that you must set the cbSize member to sizeof(MENUITEMINFO) before calling this function. | |
655 | ''' </param> | |
656 | <Runtime.InteropServices. | |
657 | DllImport("user32.dll", | |
658 | CharSet:=Runtime.InteropServices.CharSet.Auto)> _ | |
659 | Private Shared Function GetMenuItemInfo( | |
660 | ByVal hMenu As IntPtr, | |
661 | ByVal uItem As UInteger, | |
662 | ByVal fByPosition As Boolean, | |
663 | ByRef lpmii As MenuItemInfo | |
664 | ) As Boolean | |
665 | End Function | |
666 | ||
667 | ''' <summary> | |
668 | ''' Sets information for a specified menu.. | |
669 | ''' </summary> | |
670 | ''' <param name="hMenu"> | |
671 | ''' The handle to the menu that contains the menu item. | |
672 | ''' </param> | |
673 | ''' <param name="lpcmi"> | |
674 | ''' A pointer to a MENUINFO structure that specifies the information to retrieve. | |
675 | ''' </param> | |
676 | <Runtime.InteropServices. | |
677 | DllImport("user32.dll")> | |
678 | Private Shared Function SetMenuInfo( | |
679 | ByVal hmenu As IntPtr, | |
680 | <Runtime.InteropServices.[In]> | |
681 | ByRef lpcmi As MenuInfo | |
682 | ) As Boolean | |
683 | End Function | |
684 | ||
685 | ''' <summary> | |
686 | ''' Creates a logical brush that has the specified solid color. | |
687 | ''' A solid brush is a bitmap that the system uses to paint the interiors of filled shapes. | |
688 | ''' After an application creates a brush by calling CreateSolidBrush, | |
689 | ''' it can select that brush into any device context by calling the "SelectObject" API function. | |
690 | ''' When you no longer need the brush, call the "DeleteObject" API function to delete it. | |
691 | ''' </summary> | |
692 | <Runtime.InteropServices. | |
693 | DllImport("gdi32.dll")> | |
694 | Private Shared Function CreateSolidBrush( | |
695 | ByVal crColor As UInteger | |
696 | ) As IntPtr | |
697 | End Function | |
698 | ||
699 | ''' <summary> | |
700 | ''' Selects an object into a specified device context. | |
701 | ''' The new object replaces the previous object of the same type. | |
702 | ''' </summary> | |
703 | <Runtime.InteropServices. | |
704 | DllImport("gdi32.dll")> | |
705 | Public Shared Function SelectObject( | |
706 | ByVal hdc As IntPtr, | |
707 | ByVal hObject As IntPtr | |
708 | ) As IntPtr | |
709 | End Function | |
710 | ||
711 | ''' <summary> | |
712 | ''' Deletes a logical pen, brush, font, bitmap, region, or palette, | |
713 | ''' freeing all system resources associated with the object. | |
714 | ''' After the object is deleted, the specified handle is no longer valid. | |
715 | ''' </summary> | |
716 | <Runtime.InteropServices. | |
717 | DllImport("gdi32.dll")> | |
718 | Private Shared Function DeleteObject( | |
719 | ByVal hObject As IntPtr | |
720 | ) As <Runtime.InteropServices.MarshalAs( | |
721 | Runtime.InteropServices.UnmanagedType.Bool)> Boolean | |
722 | End Function | |
723 | ||
724 | ''' <summary> | |
725 | ''' Changes information about a menu item. | |
726 | ''' </summary> | |
727 | ''' <param name="hMenu "> | |
728 | ''' A handle to the menu that contains the menu item. | |
729 | ''' </param> | |
730 | ''' <param name="uItem"> | |
731 | ''' The identifier or position of the menu item to change. | |
732 | ''' The meaning of this parameter depends on the value of fByPosition. | |
733 | ''' </param> | |
734 | ''' <param name="fByPosition"> | |
735 | ''' The meaning of "uItem". | |
736 | ''' If this parameter is set to "FALSE", "uItem" is a menu item identifier. | |
737 | ''' Otherwise, it is a menu item position. | |
738 | ''' </param> | |
739 | ''' <param name="lpmii"> | |
740 | ''' A pointer to a MenuItemInfo structure that contains information about the menu item, | |
741 | ''' and specifies which menu item attributes to change. | |
742 | ''' </param> | |
743 | <Runtime.InteropServices. | |
744 | DllImport("user32.dll", | |
745 | SetLastError:=True, | |
746 | CharSet:=Runtime.InteropServices.CharSet.Auto)> | |
747 | Private Shared Function SetMenuItemInfo( | |
748 | ByVal hMenu As IntPtr, | |
749 | ByVal uItem As UInteger, | |
750 | ByVal fByPosition As Boolean, | |
751 | <Runtime.InteropServices.[In]> | |
752 | ByRef lpmii As MenuItemInfo | |
753 | ) As Boolean | |
754 | End Function | |
755 | ||
756 | #End Region ' APIs | |
757 | ||
758 | #Region " Structures " | |
759 | ||
760 | ''' <summary> | |
761 | ''' MenuItemInfo Structure, | |
762 | ''' Contains information about a menu, | |
763 | ''' Is used to set menu information. | |
764 | ''' </summary> | |
765 | <Runtime.InteropServices. | |
766 | StructLayout(Runtime.InteropServices.LayoutKind.Sequential, | |
767 | CharSet:=Runtime.InteropServices.CharSet.Auto)> | |
768 | Public Structure MenuInfo | |
769 | ||
770 | ''' <summary> | |
771 | ''' The size of the structure, in bytes. | |
772 | ''' The caller must set this member to sizeof(MenuInfo). | |
773 | ''' </summary> | |
774 | Public cbSize As UInteger | |
775 | ||
776 | ''' <summary> | |
777 | ''' Indicates the members to be retrieved or set (except for "MenuMask.APPLYTOSUBMENUS"). | |
778 | ''' This member can be one or more of the "MenuMask" Enum values. | |
779 | ''' </summary> | |
780 | Public fMask As UInteger | |
781 | ||
782 | ''' <summary> | |
783 | ''' The menu style. | |
784 | ''' This member can be one or more of the following values. | |
785 | ''' </summary> | |
786 | Public dwStyle As UInteger | |
787 | ||
788 | ''' <summary> | |
789 | ''' The maximum height of the menu in pixels. | |
790 | ''' When the menu items exceed the space available, scroll bars are automatically used. | |
791 | ''' The default (0) is the screen height. | |
792 | ''' </summary> | |
793 | Public cyMax As UInteger | |
794 | ||
795 | ''' <summary> | |
796 | ''' A handle to the brush to be used for the menu's background. | |
797 | ''' </summary> | |
798 | Public hbrBack As IntPtr | |
799 | ||
800 | ''' <summary> | |
801 | ''' The context help identifier. | |
802 | ''' This is the same value used in the "GetMenuContextHelpId" and "SetMenuContextHelpId" API functions. | |
803 | ''' </summary> | |
804 | Public dwContextHelpID As UInteger | |
805 | ||
806 | ''' <summary> | |
807 | ''' An application-defined value. | |
808 | ''' </summary> | |
809 | Public dwMenuData As UIntPtr | |
810 | ||
811 | End Structure | |
812 | ||
813 | ''' <summary> | |
814 | ''' MenuItemInfo Structure, | |
815 | ''' Contains information about a menu item, | |
816 | ''' Is used to set a menu item info, | |
817 | ''' to add a new item or to get an existing item. | |
818 | ''' </summary> | |
819 | <Runtime.InteropServices. | |
820 | StructLayout(Runtime.InteropServices.LayoutKind.Sequential, | |
821 | CharSet:=Runtime.InteropServices.CharSet.Auto)> | |
822 | Public Structure MenuItemInfo | |
823 | ||
824 | ''' <summary> | |
825 | ''' The size of the structure, in bytes. | |
826 | ''' The caller must set this member to sizeof(MenuItemInfo). | |
827 | ''' </summary> | |
828 | Public cbSize As Integer | |
829 | ||
830 | ''' <summary> | |
831 | ''' Indicates the members to be retrieved or set. | |
832 | ''' This member can be one or more of the "ItemMask" Enum values. | |
833 | ''' </summary> | |
834 | Public fMask As Integer | |
835 | ||
836 | ''' <summary> | |
837 | ''' The menu item type. | |
838 | ''' This member can be one or more of the "ItemType" Enum values. | |
839 | ''' The "ItemType.BITMAP", "ItemType.SEPARATOR", and "ItemType.MFT_STRING" values cannot be combined with one another. | |
840 | ''' Set "fMask" member to "ItemMask.TYPE" to use "fType" member. | |
841 | ''' "fType" is used only if "fMask" has a value of "ItemMask.TYPE". | |
842 | ''' </summary> | |
843 | Public fType As Integer | |
844 | ||
845 | ''' <summary> | |
846 | ''' The menu item state. | |
847 | ''' This member can be one or more of the "ItemState" Enum values. | |
848 | ''' Set fMask to "ItemMask.STATE" to use "fState". | |
849 | ''' </summary> | |
850 | Public fState As Integer | |
851 | ||
852 | ''' <summary> | |
853 | ''' An application-defined value that identifies the menu item. | |
854 | ''' Set "fMask" to "ItemMask.ID" to use "wID". | |
855 | ''' </summary> | |
856 | Public wID As Integer | |
857 | ||
858 | ''' <summary> | |
859 | ''' A handle to the drop-down menu or submenu associated with the menu item. | |
860 | ''' If the menu item is not an item that opens a drop-down menu or submenu, this member is NULL. | |
861 | ''' Set "fMask" to "ItemMask.SUBMENU" to use "hSubMenu". | |
862 | ''' </summary> | |
863 | Public hSubMenu As IntPtr | |
864 | ||
865 | ''' <summary> | |
866 | ''' A handle to the bitmap to display next to the item if it is selected. | |
867 | ''' If this member is NULL, a default bitmap is used. | |
868 | ''' If the "ItemType.RADIOCHECK" type value is specified, the default bitmap is a bullet, | |
869 | ''' Otherwise it is a check mark. | |
870 | ''' Set "fMask" to "ItemMask.CHECKMARKS" to use "hbmpChecked". | |
871 | ''' </summary> | |
872 | Public hbmpChecked As IntPtr | |
873 | ||
874 | ''' <summary> | |
875 | ''' A handle to the bitmap to display next to the item if it is not selected. | |
876 | ''' If this member is NULL, no bitmap is used. | |
877 | ''' Set "fMask" to "ItemMask.CHECKMARKS" to use "hbmpUnchecked". | |
878 | ''' </summary> | |
879 | Public hbmpUnchecked As IntPtr | |
880 | ||
881 | ''' <summary> | |
882 | ''' An application-defined value associated with the menu item. | |
883 | ''' Set "fMask" to "ItemMask.DATA" to use "dwItemData". | |
884 | ''' </summary> | |
885 | Public dwItemData As IntPtr | |
886 | ||
887 | ''' <summary> | |
888 | ''' The contents of the menu item. | |
889 | ''' The meaning of this member depends on the value of fType, | |
890 | ''' and is used only if the "ItemMask.TYPE" flag is set in the "fMask" member. | |
891 | ''' </summary> | |
892 | Public dwTypeData As String | |
893 | ||
894 | ''' <summary> | |
895 | ''' The length of the menu item text, in characters, | |
896 | ''' when information is received about a menu item of the "ItemType.TEXT" type. | |
897 | ''' However, "cch" is used only if the "ItemMask.TYPE" flag is set in the "fMask" member and is zero otherwise. | |
898 | ''' Also, "cch" is ignored when the content of a menu item is set by calling "SetMenuItemInfo" API function. | |
899 | ''' The "cch" member is used when the "ItemMask.TEXT" flag is set in the "fMask" member. | |
900 | ''' </summary> | |
901 | Public cch As Integer | |
902 | ||
903 | ''' <summary> | |
904 | ''' A handle to the bitmap to be displayed. | |
905 | ''' It is used when the "ItemMask.BITMAP" flag is set in the "fMask" member. | |
906 | ''' </summary> | |
907 | Public hbmpItem As IntPtr | |
908 | ||
909 | End Structure | |
910 | ||
911 | #End Region ' Structures | |
912 | ||
913 | #Region " New Constructor " | |
914 | ||
915 | ''' <summary> | |
916 | ''' Creates a new SystemMenuManager object for the specified form | |
917 | ''' </summary> | |
918 | ''' <param name="form"> | |
919 | ''' The form for which to manage the system menu. | |
920 | ''' </param> | |
921 | Public Sub New(ByVal form As Form) | |
922 | ||
923 | ' Set the Formulary. | |
924 | Me.form = form | |
925 | ||
926 | ' Set the handle of the form's system menu. | |
927 | MenuHandle = GetSystemMenu(form.Handle, False) | |
928 | ||
929 | ' Assign the form handle. | |
930 | SetFormHandle() | |
931 | ||
932 | End Sub | |
933 | ||
934 | #End Region ' New Constructor | |
935 | ||
936 | #Region " Public Methods " | |
937 | ||
938 | ''' <summary> | |
939 | ''' Set an state for a menu item. | |
940 | ''' </summary> | |
941 | ''' <param name="item"> | |
942 | ''' The system menu item. | |
943 | ''' </param> | |
944 | ''' <param name="state"> | |
945 | ''' The new state for the item. | |
946 | ''' </param> | |
947 | Public Function SetItemState(ByVal item As Item, | |
948 | ByVal state As ItemState) As Boolean | |
949 | ||
950 | ItemStates(item) = state | |
951 | ||
952 | If item = item.Close Then | |
953 | CloseItem_State = state | |
954 | End If | |
955 | ||
956 | If state = ItemState.Removed Then | |
957 | Return DeleteMenu(MenuHandle, item, ItemPosition.ByCommand Or 0) | |
958 | Else | |
959 | Return EnableMenuItem(MenuHandle, item, ItemPosition.ByCommand Or state) | |
960 | End If | |
961 | ||
962 | End Function | |
963 | ||
964 | ''' <summary> | |
965 | ''' Set an state for a menu item at given position. | |
966 | ''' </summary> | |
967 | ''' <param name="position"> | |
968 | ''' The menu item position. | |
969 | ''' </param> | |
970 | ''' <param name="state"> | |
971 | ''' The new state for the item. | |
972 | ''' </param> | |
973 | Public Function SetItemState(ByVal position As Integer, | |
974 | ByVal state As ItemState) As Boolean | |
975 | ||
976 | Try | |
977 | PositionItemStates.Add(position, state) | |
978 | Catch ' ex As ArgumentException | |
979 | PositionItemStates(position) = state | |
980 | End Try | |
981 | ||
982 | If state = ItemState.Removed Then | |
983 | Return DeleteMenu(MenuHandle, position, ItemPosition.ByPosition Or 0) | |
984 | Else | |
985 | Return EnableMenuItem(MenuHandle, position, ItemPosition.ByPosition Or state) | |
986 | End If | |
987 | ||
988 | End Function | |
989 | ||
990 | ''' <summary> | |
991 | ''' Set a custom Bitmap image for a MenuItem. | |
992 | ''' </summary> | |
993 | ''' <param name="item"> | |
994 | ''' The menu item. | |
995 | ''' </param> | |
996 | Public Function SetItemBitmap(ByVal item As Item, | |
997 | ByVal bmp As Bitmap) As Boolean | |
998 | ||
999 | ItemBitmaps(item) = bmp | |
1000 | ||
1001 | Return SetMenuItemBitmaps(MenuHandle, | |
1002 | item, | |
1003 | ItemPosition.ByCommand, | |
1004 | bmp.GetHbitmap, | |
1005 | bmp.GetHbitmap) | |
1006 | ||
1007 | End Function | |
1008 | ||
1009 | ''' <summary> | |
1010 | ''' Set a custom Bitmap image for a MenuItem at given position. | |
1011 | ''' </summary> | |
1012 | ''' <param name="position"> | |
1013 | ''' The menu item position. | |
1014 | ''' </param> | |
1015 | Public Function SetItemBitmap(ByVal position As Integer, | |
1016 | ByVal bmp As Bitmap) As Boolean | |
1017 | ||
1018 | Try | |
1019 | PositionItemBitmaps.Add(position, bmp) | |
1020 | Catch ' ex As System.ArgumentException | |
1021 | PositionItemBitmaps(position) = bmp | |
1022 | End Try | |
1023 | ||
1024 | Return SetMenuItemBitmaps(MenuHandle, | |
1025 | position, | |
1026 | ItemPosition.ByPosition, | |
1027 | bmp.GetHbitmap, | |
1028 | bmp.GetHbitmap) | |
1029 | ||
1030 | End Function | |
1031 | ||
1032 | ''' <summary> | |
1033 | ''' Returns the custom Bitmap image used by a MenuItem. | |
1034 | ''' </summary> | |
1035 | ''' <param name="item"> | |
1036 | ''' The menu item. | |
1037 | ''' </param> | |
1038 | Public Function GetItemBitmap(ByVal item As Item) As Bitmap | |
1039 | Return ItemBitmaps(item) | |
1040 | End Function | |
1041 | ||
1042 | ''' <summary> | |
1043 | ''' Returns the custom Bitmap image used by a MenuItem at given position. | |
1044 | ''' </summary> | |
1045 | ''' <param name="position"> | |
1046 | ''' The menu item position. | |
1047 | ''' </param> | |
1048 | Public Function GetItemBitmap(ByVal position As Integer) As Bitmap | |
1049 | ||
1050 | Return If(Not PositionItemBitmaps.FirstOrDefault(Function(item) item.Key = position).Key = Nothing, | |
1051 | PositionItemBitmaps(position), | |
1052 | Nothing) | |
1053 | ||
1054 | End Function | |
1055 | ||
1056 | ''' <summary> | |
1057 | ''' Removes the custom Bitmap image used by a MenuItem. | |
1058 | ''' </summary> | |
1059 | ''' <param name="item"> | |
1060 | ''' The menu item. | |
1061 | ''' </param> | |
1062 | Public Function RemoveItemBitmap(ByVal item As Item) As Boolean | |
1063 | ||
1064 | ItemBitmaps(item) = Nothing | |
1065 | ||
1066 | Return SetMenuItemBitmaps(MenuHandle, | |
1067 | item, | |
1068 | ItemPosition.ByCommand, | |
1069 | Nothing, | |
1070 | Nothing) | |
1071 | ||
1072 | End Function | |
1073 | ||
1074 | ''' <summary> | |
1075 | ''' Removes the custom Bitmap image used by a MenuItem at given position. | |
1076 | ''' </summary> | |
1077 | ''' <param name="position"> | |
1078 | ''' The menu item position. | |
1079 | ''' </param> | |
1080 | Public Function RemoveItemBitmap(ByVal position As Integer) As Boolean | |
1081 | ||
1082 | If Not PositionItemBitmaps.FirstOrDefault(Function(item) item.Key = position).Key = Nothing Then | |
1083 | PositionItemBitmaps(position) = Nothing | |
1084 | End If | |
1085 | ||
1086 | Return SetMenuItemBitmaps(MenuHandle, | |
1087 | position, | |
1088 | ItemPosition.ByPosition, | |
1089 | Nothing, | |
1090 | Nothing) | |
1091 | ||
1092 | End Function | |
1093 | ||
1094 | ''' <summary> | |
1095 | ''' Gets the amount of menu items. | |
1096 | ''' </summary> | |
1097 | Public Function GetItemCount() As Integer | |
1098 | Return GetMenuItemCount(MenuHandle) ' - 1 | |
1099 | End Function | |
1100 | ||
1101 | ''' <summary> | |
1102 | ''' Enables all the menu items. | |
1103 | ''' </summary> | |
1104 | Public Sub EnableAllItems() | |
1105 | ||
1106 | For i As Integer = 0 To GetItemCount() - 1 | |
1107 | SetItemState(i, ItemState.Enabled) | |
1108 | Next i | |
1109 | ||
1110 | End Sub | |
1111 | ||
1112 | ''' <summary> | |
1113 | ''' Disables all the menu items. | |
1114 | ''' </summary> | |
1115 | Public Sub DisableAllItems() | |
1116 | ||
1117 | For i As Integer = 0 To GetItemCount() - 1 | |
1118 | SetItemState(i, ItemState.Disabled) | |
1119 | Next i | |
1120 | ||
1121 | End Sub | |
1122 | ||
1123 | ''' <summary> | |
1124 | ''' Removes all the menu items. | |
1125 | ''' </summary> | |
1126 | Public Sub RemoveAllItems() | |
1127 | ||
1128 | Do Until Not CBool(GetItemCount()) | |
1129 | DeleteMenu(MenuHandle, 0, ItemPosition.ByPosition Or 0) | |
1130 | Loop | |
1131 | ||
1132 | End Sub | |
1133 | ||
1134 | ''' <summary> | |
1135 | ''' Restores the menu to defaults. | |
1136 | ''' </summary> | |
1137 | Public Sub Restore_Menu() | |
1138 | CloseItem_State = ItemState.Enabled | |
1139 | Me.MenuHandle = GetSystemMenu(Me.form.Handle, True) | |
1140 | End Sub | |
1141 | ||
1142 | ''' <summary> | |
1143 | ''' Add a separator at default position. | |
1144 | ''' </summary> | |
1145 | ''' <param name="position"> | |
1146 | ''' The position where the item will be added. | |
1147 | ''' </param> | |
1148 | ''' <returns> | |
1149 | ''' True if the operation was successful, otherwise False. | |
1150 | ''' </returns> | |
1151 | Public Function AddSeparator(ByVal position As DefaultPositions) As Boolean | |
1152 | ||
1153 | mii = New MenuItemInfo | |
1154 | ||
1155 | With mii | |
1156 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuItemInfo)) | |
1157 | .fMask = ItemMask.ID Or ItemMask.TYPE | |
1158 | .fType = ItemType.SEPARATOR | |
1159 | .wID = -1 | |
1160 | End With | |
1161 | ||
1162 | Return InsertMenuItem(MenuHandle, GetPosition(position), True, mii) | |
1163 | ||
1164 | End Function | |
1165 | ||
1166 | ''' <summary> | |
1167 | ''' Add a separator at given position. | |
1168 | ''' </summary> | |
1169 | ''' <param name="position"> | |
1170 | ''' The position where the item will be added. | |
1171 | ''' </param> | |
1172 | ''' <returns> | |
1173 | ''' True if the operation was successful, otherwise False. | |
1174 | ''' </returns> | |
1175 | Public Function AddSeparator(ByVal position As Integer) As Boolean | |
1176 | ||
1177 | mii = New MenuItemInfo | |
1178 | ||
1179 | With mii | |
1180 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuItemInfo)) | |
1181 | .fMask = ItemMask.ID Or ItemMask.TYPE | |
1182 | .fType = ItemType.SEPARATOR | |
1183 | .wID = -1 | |
1184 | End With | |
1185 | ||
1186 | Return InsertMenuItem(MenuHandle, position, True, mii) | |
1187 | ||
1188 | End Function | |
1189 | ||
1190 | ''' <summary> | |
1191 | ''' Add an Item at default position. | |
1192 | ''' </summary> | |
1193 | ''' <param name="Label"> | |
1194 | ''' The text of the item. | |
1195 | ''' </param> | |
1196 | ''' <param name="ID"> | |
1197 | ''' A Identifier to interact with this item when is clicked. | |
1198 | ''' </param> | |
1199 | ''' <param name="position"> | |
1200 | ''' The position where the item will be added. | |
1201 | ''' </param> | |
1202 | ''' <param name="ImageChecked"> | |
1203 | ''' Image displayed when Item is selected. | |
1204 | ''' </param> | |
1205 | ''' <param name="ImageUnchecked"> | |
1206 | ''' Image displayed when Item is not selected. | |
1207 | ''' </param> | |
1208 | ''' <returns> | |
1209 | ''' True if the operation was successful, otherwise False. | |
1210 | ''' </returns> | |
1211 | Public Function AddItem(ByVal Label As String, | |
1212 | ByVal ID As Integer, | |
1213 | ByVal Position As DefaultPositions, | |
1214 | Optional ByVal ImageChecked As Bitmap = Nothing, | |
1215 | Optional ByVal ImageUnchecked As Bitmap = Nothing) As Boolean | |
1216 | ||
1217 | mii = New MenuItemInfo | |
1218 | ||
1219 | With mii | |
1220 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuItemInfo)) | |
1221 | .fMask = ItemMask.STATE Or ItemMask.ID Or ItemMask.TYPE Or ItemMask.CHECKMARKS | |
1222 | .fType = ItemType.TEXT | |
1223 | .fState = ItemState.Enabled | |
1224 | .wID = ID | |
1225 | .dwTypeData = Label | |
1226 | .hbmpChecked = If(ImageChecked IsNot Nothing, ImageChecked.GetHbitmap, Nothing) | |
1227 | .hbmpUnchecked = If(ImageUnchecked IsNot Nothing, ImageUnchecked.GetHbitmap, Nothing) | |
1228 | .cch = .dwTypeData.Length | |
1229 | End With | |
1230 | ||
1231 | Return InsertMenuItem(MenuHandle, GetPosition(Position), True, mii) | |
1232 | ||
1233 | End Function | |
1234 | ||
1235 | ''' <summary> | |
1236 | ''' Adds an Item at the given position. | |
1237 | ''' </summary> | |
1238 | ''' <param name="Label"> | |
1239 | ''' The text of the item. | |
1240 | ''' </param> | |
1241 | ''' <param name="ID"> | |
1242 | ''' A Identifier to interact with this item when is clicked. | |
1243 | ''' </param> | |
1244 | ''' <param name="position"> | |
1245 | ''' The position where the item will be added. | |
1246 | ''' </param> | |
1247 | ''' <param name="ImageChecked"> | |
1248 | ''' Image displayed when Item is selected. | |
1249 | ''' </param> | |
1250 | ''' <param name="ImageUnchecked"> | |
1251 | ''' Image displayed when Item is not selected. | |
1252 | ''' </param> | |
1253 | ''' <returns> | |
1254 | ''' True if the operation was successful, otherwise False. | |
1255 | ''' </returns> | |
1256 | Public Function AddItem(ByVal Label As String, | |
1257 | ByVal ID As Integer, | |
1258 | ByVal Position As Integer, | |
1259 | Optional ByVal ImageChecked As Bitmap = Nothing, | |
1260 | Optional ByVal ImageUnchecked As Bitmap = Nothing) As Boolean | |
1261 | ||
1262 | mii = New MenuItemInfo | |
1263 | ||
1264 | With mii | |
1265 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuItemInfo)) | |
1266 | .fMask = ItemMask.STATE Or ItemMask.ID Or ItemMask.TYPE Or ItemMask.CHECKMARKS | |
1267 | .fType = ItemType.TEXT | |
1268 | .fState = ItemState.Enabled | |
1269 | .wID = ID | |
1270 | .dwTypeData = Label | |
1271 | .hbmpChecked = If(ImageChecked IsNot Nothing, ImageChecked.GetHbitmap, Nothing) | |
1272 | .hbmpUnchecked = If(ImageUnchecked IsNot Nothing, ImageUnchecked.GetHbitmap, Nothing) | |
1273 | .cch = .dwTypeData.Length | |
1274 | End With | |
1275 | ||
1276 | Return InsertMenuItem(MenuHandle, Position, True, mii) | |
1277 | ||
1278 | End Function | |
1279 | ||
1280 | ''' <summary> | |
1281 | ''' Determines whether a handle is a menu handle. | |
1282 | ''' </summary> | |
1283 | ''' <returns> | |
1284 | ''' True if is a menu handle, otherwise False. | |
1285 | ''' </returns> | |
1286 | Public Function IsMenuHandle(ByVal Handle As IntPtr) As Boolean | |
1287 | Return IsMenu(Handle) | |
1288 | End Function | |
1289 | ||
1290 | ''' <summary> | |
1291 | ''' Gets the ID of a menu item. | |
1292 | ''' </summary> | |
1293 | Public Function GetItemID(ByVal Item As Item) As Integer | |
1294 | Return Item | |
1295 | End Function | |
1296 | ||
1297 | ''' <summary> | |
1298 | ''' Gets the ID of a menu item at given position. | |
1299 | ''' </summary> | |
1300 | Public Function GetItemID(ByVal position As Integer) As Integer | |
1301 | Return GetMenuItemID(MenuHandle, position) | |
1302 | End Function | |
1303 | ||
1304 | ''' <summary> | |
1305 | ''' Gets the text of a menu item. | |
1306 | ''' </summary> | |
1307 | Public Function GetItemText(ByVal Item As Item) As String | |
1308 | ItemText.Clear() | |
1309 | GetMenuString(MenuHandle, Item, ItemText, ItemText.Capacity, ItemPosition.ByCommand) | |
1310 | Return ItemText.ToString | |
1311 | End Function | |
1312 | ||
1313 | ''' <summary> | |
1314 | ''' Gets the text of a menu item at given position. | |
1315 | ''' </summary> | |
1316 | Public Function GetItemText(ByVal position As Integer) As String | |
1317 | ItemText.Clear() | |
1318 | GetMenuString(MenuHandle, position, ItemText, ItemText.Capacity, ItemPosition.ByPosition) | |
1319 | Return ItemText.ToString | |
1320 | End Function | |
1321 | ||
1322 | ''' <summary> | |
1323 | ''' Gets the state of a menu item. | |
1324 | ''' </summary> | |
1325 | Public Function GetItemState(ByVal Item As Item) As ItemState | |
1326 | Return [Enum].Parse(GetType(ItemState), GetMenuState(MenuHandle, Item, ItemPosition.ByCommand)) | |
1327 | End Function | |
1328 | ||
1329 | ''' <summary> | |
1330 | ''' Gets the state of a menu item at given position. | |
1331 | ''' </summary> | |
1332 | Public Function GetItemState(ByVal position As Integer) As ItemState | |
1333 | Return [Enum].Parse(GetType(ItemState), GetMenuState(MenuHandle, position, ItemPosition.ByPosition)) | |
1334 | End Function | |
1335 | ||
1336 | ''' <summary> | |
1337 | ''' Set the background color of a menu. | |
1338 | ''' </summary> | |
1339 | ''' <returns> | |
1340 | ''' True if the operation was successful, otherwise False. | |
1341 | ''' </returns> | |
1342 | Public Function SetMenuBackColor(ByVal color As Color) As Boolean | |
1343 | ||
1344 | MenuBrush = CreateSolidBrush(CUInt(ColorTranslator.ToWin32(color))) | |
1345 | ||
1346 | mi = New MenuInfo | |
1347 | ||
1348 | With mi | |
1349 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuInfo)) | |
1350 | .fMask = MenuMask.BACKGROUND | |
1351 | .hbrBack = MenuBrush | |
1352 | End With | |
1353 | ||
1354 | Return SetMenuInfo(MenuHandle, mi) | |
1355 | ||
1356 | End Function | |
1357 | ||
1358 | ''' <summary> | |
1359 | ''' Set the menu style. | |
1360 | ''' </summary> | |
1361 | ''' <returns> | |
1362 | ''' True if the operation was successful, otherwise False. | |
1363 | ''' </returns> | |
1364 | Public Function SetMenuStyle(ByVal Style As MenuStyle) As Boolean | |
1365 | ||
1366 | mi = New MenuInfo | |
1367 | ||
1368 | With mi | |
1369 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuInfo)) | |
1370 | .fMask = MenuMask.STYLE | |
1371 | .dwStyle = Style | |
1372 | End With | |
1373 | ||
1374 | Return SetMenuInfo(MenuHandle, mi) | |
1375 | ||
1376 | End Function | |
1377 | ||
1378 | ''' <summary> | |
1379 | ''' Set the text of a menu item. | |
1380 | ''' </summary> | |
1381 | ''' <param name="item"> | |
1382 | ''' The menu item. | |
1383 | ''' </param> | |
1384 | ''' <param name="text"> | |
1385 | ''' The new text for the item. | |
1386 | ''' </param> | |
1387 | Public Function SetItemText(ByVal item As Item, | |
1388 | ByVal text As String) As Boolean | |
1389 | ||
1390 | mii = New MenuItemInfo | |
1391 | ||
1392 | With mii | |
1393 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuItemInfo)) | |
1394 | .fMask = ItemMask.TEXT | |
1395 | .dwTypeData = text | |
1396 | End With | |
1397 | ||
1398 | Return SetMenuItemInfo(MenuHandle, item, False, mii) | |
1399 | ||
1400 | End Function | |
1401 | ||
1402 | ''' <summary> | |
1403 | ''' Set the text of a menu item at given position. | |
1404 | ''' </summary> | |
1405 | ''' <param name="position"> | |
1406 | ''' The menu item position. | |
1407 | ''' </param> | |
1408 | ''' <param name="text"> | |
1409 | ''' The new text for the item. | |
1410 | ''' </param> | |
1411 | Public Function SetItemText(ByVal position As Integer, | |
1412 | ByVal text As String) As Boolean | |
1413 | ||
1414 | mii = New MenuItemInfo | |
1415 | ||
1416 | With mii | |
1417 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuItemInfo)) | |
1418 | .fMask = ItemMask.TEXT | |
1419 | .dwTypeData = text | |
1420 | End With | |
1421 | ||
1422 | Return SetMenuItemInfo(MenuHandle, position, True, mii) | |
1423 | ||
1424 | End Function | |
1425 | ||
1426 | #End Region ' Public Methods | |
1427 | ||
1428 | #Region " Private Methods " | |
1429 | ||
1430 | ''' <summary> | |
1431 | ''' Converts a MenuItemPosition value to a menu item position. | |
1432 | ''' </summary> | |
1433 | ''' <param name="position"> | |
1434 | ''' The MenuItemPosition value. | |
1435 | ''' </param> | |
1436 | Private Function GetPosition(ByVal position As ItemPosition) As Integer | |
1437 | ||
1438 | Select Case position | |
1439 | ||
1440 | Case DefaultPositions.First | |
1441 | Return 0 | |
1442 | ||
1443 | Case DefaultPositions.Second | |
1444 | Return 1 | |
1445 | ||
1446 | Case DefaultPositions.Third | |
1447 | Return 2 | |
1448 | ||
1449 | Case DefaultPositions.Middle | |
1450 | Return (GetItemCount() \ 2) | |
1451 | ||
1452 | Case DefaultPositions.Penultimate | |
1453 | Return (GetItemCount() - 1) | |
1454 | ||
1455 | Case DefaultPositions.Last | |
1456 | Return (GetItemCount() + 1) | |
1457 | ||
1458 | Case Else | |
1459 | Return Nothing | |
1460 | ||
1461 | End Select | |
1462 | ||
1463 | End Function | |
1464 | ||
1465 | ''' <summary> | |
1466 | ''' Refreshes the state of the Close menu item. | |
1467 | ''' </summary> | |
1468 | ''' <remarks> | |
1469 | ''' Action is only taken if the state is Disabled or Grayed. | |
1470 | ''' </remarks> | |
1471 | Private Sub Refresh_CloseItem() | |
1472 | ||
1473 | If CloseItem_State = ItemState.Disabled _ | |
1474 | OrElse CloseItem_State = ItemState.Grayed Then | |
1475 | ||
1476 | ' Set the Close menu item state. | |
1477 | EnableMenuItem(MenuHandle, Item.Close, ItemPosition.ByCommand Or CloseItem_State) | |
1478 | ||
1479 | End If | |
1480 | ||
1481 | End Sub | |
1482 | ||
1483 | #End Region ' Private Methods | |
1484 | ||
1485 | #Region " Form Event Handlers " | |
1486 | ||
1487 | ''' <summary> | |
1488 | ''' The Close menu item must have it's state refresehed, | |
1489 | ''' if it is present and not enabled. | |
1490 | ''' </summary> | |
1491 | Private Sub Refresh() _ | |
1492 | Handles form.Load, form.Resize | |
1493 | ||
1494 | Refresh_CloseItem() | |
1495 | ||
1496 | End Sub | |
1497 | ||
1498 | ''' <summary> | |
1499 | ''' SetHandle | |
1500 | ''' Assign the handle of the target form to this NativeWindow, | |
1501 | ''' necessary to override WndProc. | |
1502 | ''' </summary> | |
1503 | Private Sub SetFormHandle() _ | |
1504 | Handles form.HandleCreated, form.Load, form.Shown | |
1505 | ||
1506 | Try | |
1507 | If Not Me.Handle.Equals(Me.form.Handle) Then | |
1508 | Me.AssignHandle(Me.form.Handle) | |
1509 | End If | |
1510 | Catch ' ex As InvalidOperationException | |
1511 | End Try | |
1512 | ||
1513 | End Sub | |
1514 | ||
1515 | ''' <summary> | |
1516 | ''' Releases the Handle. | |
1517 | ''' </summary> | |
1518 | Private Sub OnHandleDestroyed() _ | |
1519 | Handles form.HandleDestroyed | |
1520 | ||
1521 | Me.ReleaseHandle() | |
1522 | ||
1523 | End Sub | |
1524 | ||
1525 | #End Region ' Form Event Handlers | |
1526 | ||
1527 | #Region " Windows Messages " | |
1528 | ||
1529 | ''' <summary> | |
1530 | ''' Intercepts Menu messages. | |
1531 | ''' </summary> | |
1532 | Protected Overrides Sub WndProc(ByRef m As Message) | |
1533 | ||
1534 | Select Case m.Msg | |
1535 | ||
1536 | Case &H116 ' WM_INITMENU message | |
1537 | ' Message is sent when a menu is about to become active. | |
1538 | ' It occurs when the user clicks an item on the menu bar or presses a menu key. | |
1539 | ' This allows the application to modify the menu before it is displayed. | |
1540 | MenuHandle = GetSystemMenu(form.Handle, False) | |
1541 | ||
1542 | Case &H117 ' WM_INITMENUPOPUP | |
1543 | ' Message is sent when a drop-down menu or submenu is about to become active. | |
1544 | ' This allows an application to modify the menu before it is displayed, | |
1545 | ' without changing the entire menu. | |
1546 | ||
1547 | ' Refresh the states of the Items by command. | |
1548 | If ItemStates.FirstOrDefault(Function(item) item.Key).Value <> Nothing Then | |
1549 | ItemStates.ToList(). | |
1550 | ForEach(Function(item) SetItemState(item.Key, item.Value)) | |
1551 | End If | |
1552 | ||
1553 | ' Refresh the states of the Items by position. | |
1554 | If PositionItemStates.FirstOrDefault(Function(item) item.Key).Value <> Nothing Then | |
1555 | PositionItemStates.ToList(). | |
1556 | ForEach(Function(item) SetItemState(CInt(item.Key), item.Value)) | |
1557 | End If | |
1558 | ||
1559 | Case &H112 ' WM_SYSCOMMAND | |
1560 | ' Message is sent when the user chooses a command from the system menu, | |
1561 | ' or when the user chooses the maximize button, minimize button, restore button, or close button. | |
1562 | ||
1563 | ' Begin step to retrieve the item Text | |
1564 | mii = New MenuItemInfo With { | |
1565 | .cbSize = Runtime.InteropServices.Marshal.SizeOf(GetType(MenuItemInfo)), | |
1566 | .fMask = ItemMask.TEXT | |
1567 | } | |
1568 | ||
1569 | ' Retrieve the text length member. | |
1570 | GetMenuItemInfo(MenuHandle, m.WParam, False, mii) | |
1571 | ||
1572 | ' Account for terminating NUL character and allocate String | |
1573 | mii.cch += 1 | |
1574 | mii.dwTypeData = Space(mii.cch) | |
1575 | ||
1576 | ' Retrieve the rest of the information. | |
1577 | mii.fMask = ItemMask.ID Or ItemMask.TEXT Or ItemMask.STATE Or ItemMask.FTYPE | |
1578 | GetMenuItemInfo(MenuHandle, m.WParam, False, mii) | |
1579 | ||
1580 | ' Set the Event arguments | |
1581 | With ItemClickedArgs | |
1582 | .ID = mii.wID | |
1583 | .Text = mii.dwTypeData | |
1584 | .State = [Enum].Parse(GetType(ItemState), mii.fState) | |
1585 | .Type = [Enum].Parse(GetType(ItemType), mii.fType) | |
1586 | End With | |
1587 | ||
1588 | RaiseEvent ItemClicked(MenuHandle, ItemClickedArgs) | |
1589 | ||
1590 | End Select | |
1591 | ||
1592 | ' Return control to base message handler. | |
1593 | MyBase.WndProc(m) | |
1594 | ||
1595 | End Sub | |
1596 | ||
1597 | #End Region ' Windows Messages | |
1598 | ||
1599 | #Region " IDisposable " | |
1600 | ||
1601 | ''' <summary> | |
1602 | ''' Disposes the objects generated by this instance. | |
1603 | ''' </summary> | |
1604 | Public Sub Dispose() Implements IDisposable.Dispose | |
1605 | Dispose(True) | |
1606 | GC.SuppressFinalize(Me) | |
1607 | End Sub | |
1608 | ||
1609 | Protected Overridable Sub Dispose(IsDisposing As Boolean) | |
1610 | ||
1611 | Static IsBusy As Boolean = False ' To detect redundant calls. | |
1612 | ||
1613 | If Not IsBusy AndAlso IsDisposing Then | |
1614 | ||
1615 | DeleteObject(MenuBrush) | |
1616 | ||
1617 | Restore_Menu() | |
1618 | EndMenu() | |
1619 | ||
1620 | Me.form = Nothing | |
1621 | MenuHandle = IntPtr.Zero | |
1622 | ||
1623 | Me.ReleaseHandle() | |
1624 | Me.DestroyHandle() | |
1625 | ||
1626 | End If | |
1627 | ||
1628 | IsBusy = True | |
1629 | ||
1630 | End Sub | |
1631 | ||
1632 | #End Region ' IDisposable | |
1633 | ||
1634 | #Region " ToDO?: " | |
1635 | ||
1636 | ' función "AppendMenu"? | |
1637 | ' usar HotKeys? (&) | |
1638 | ' Alguna cosa interesante con los submenus? | |
1639 | ||
1640 | #End Region ' ToDo | |
1641 | ||
1642 | End Class | |
1643 | ||
1644 | #End Region |