xoblite™ / Blackbox for Windows bb5 | RC6 preview | 0.25.2.14
http://xoblite.net/
Menu Class Reference

#include <Menu.h>

Public Member Functions

 Menu (HINSTANCE hInstance)
 
 ~Menu ()
 
void UpdateMenuWindow ()
 
void DrawMenuItem (HDC hdc, MenuItem *i, bool active)
 
void Show ()
 
void Show (int x, int y)
 
bool Hide (int h)
 
void Mouse (UINT nMsg, int x, int y)
 
void MouseLeave ()
 
void AddMenuItem (MenuItem *m)
 
void DeleteMenuItems ()
 
void TogglePinned ()
 
bool IsPinned ()
 
LRESULT NcHitTest (int x, int y)
 
void Timer (int nTimer)
 
HWND GetWindow ()
 
void SetParent (Menu *pParent)
 
MenuGetParent ()
 
void AddChild (Menu *pChild)
 
void RemoveChild (Menu *pChild)
 
bool IsChildWindow (HWND hWnd)
 
void SetMenuFolderPath (char *pszFolderPath)
 
void Moving ()
 
virtual bool OnUser (int nMessage, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
 
LRESULT Command (WPARAM wParam, LPARAM lParam)
 
virtual void OnShow (bool fShow)
 
virtual void OnTimer (int nTimer)
 
void Activate (int fActive, HWND hWnd)
 
bool IsActive ()
 
void Sort (int beginOffset, int endOffset)
 
void Invalidate ()
 
void Validate ()
 
void ClearSelectionGroup (int group)
 

Static Public Member Functions

static void CALLBACK TrackMouseProc (HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
 

Public Attributes

HINSTANCE hMenuInstance
 
WIN32_FIND_DATA data
 
HWND hMenuWnd
 
Menum_pParent
 
vector< MenuItem * > m_MenuItems
 
vector< Menu * > m_Children
 
char * m_pszTitle
 
bool isValidated
 
bool isPinned
 
bool mouseIsHovering
 
bool keyboardNavigationInProgress
 
bool m_bMoved
 
char * m_pszFolderPath
 
HDC menuHDC
 
HDC cachedMenuBackground
 
HDC cachedMenuActive
 
bool cachedMenuGradientsExist
 
RECT menuRect
 
RECT menuTitleRect
 
RECT menuFrameRect
 
RECT menuActiveRect
 
RECT menuGripRect
 
int menuX
 
int menuY
 
int menuWidth
 
int menuHeight
 
int menuActiveWidth
 
int menuActiveHeight
 

Static Public Attributes

static int m_nInstances = 0
 

Friends

LRESULT CALLBACK MenuWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 

Constructor & Destructor Documentation

◆ Menu()

Menu::Menu ( HINSTANCE hInstance)
55{
56 hMenuInstance = hInstance;
57
58 isValidated = false;
59 m_pParent = NULL;
60 hMenuWnd = NULL;
61 m_pszFolderPath = NULL;
62 ZeroMemory(&data, sizeof(data));
63
64 isPinned = false;
65 m_bMoved = false;
66 mouseIsHovering = false;
68
71
72 //====================
73
74 // If this is the first menu instance created, we also create a common
75 // window class to be used by this and all future menu instances...
76 if (m_nInstances == 0)
77 {
78 WNDCLASS wc;
79 ZeroMemory(&wc, sizeof(wc));
80 wc.hInstance = hMenuInstance;
81 wc.lpfnWndProc = MenuWindowProc;
82 wc.lpszClassName = szMenuName;
83 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
84 wc.hbrBackground = NULL;
85 wc.style = CS_DBLCLKS;
86
87 if (!RegisterClass(&wc))
88 {
89 MessageBox(0, "Error registering menu window class!", szMenuName, MB_OK | MB_ICONERROR | MB_TOPMOST);
90 Log("Menu", "Error registering window class!");
91 return;
92 }
93 }
94
95 // Add the new menu instance to the global list of menues...
96 g_Menues.push_back(this);
97
98 //====================
99
100 // Create a window for this particular menu instance...
101 hMenuWnd = CreateWindowEx(
102 WS_EX_TOOLWINDOW | WS_EX_ACCEPTFILES | WS_EX_TOPMOST | WS_EX_LAYERED, // window style
103 szMenuName, // window class
104 NULL, // window name
105 WS_POPUP, // window parameters
106 0, // x position
107 0, // y position
108 0, // window width
109 0, // window height
110 GetBBWnd(), // owner window
111 NULL, // no menu
112 hMenuInstance, // hInstance
113 NULL // no window creation data
114 );
115
116 if (!hMenuWnd)
117 {
118 MessageBox(0, "Error creating menu window!", szMenuName, MB_OK | MB_ICONERROR | MB_TOPMOST);
119 Log("Menu", "Error creating window!");
120 return;
121 }
122
123 m_nInstances++;
124
125 // Hide the menu window... (nb. menues are not shown until opened/navigated to by the user)
126 ShowWindow(hMenuWnd, SW_HIDE);
127 // Make the menu window sticky...
129
130 // Subscribe to Blackbox messages applicable to menus...
131 SendMessage(GetBBWnd(), BB_REGISTERMESSAGE, (WPARAM)hMenuWnd, (LPARAM)menuMessageSubscription);
132}
void MakeSticky(HWND window)
Definition BBApi.cpp:2965
#define WS_EX_LAYERED
Definition BBApi.cpp:61
void Log(LPCSTR des, LPCSTR line)
Definition BBApi.cpp:638
HWND GetBBWnd()
Definition BBApi.cpp:128
#define BB_REGISTERMESSAGE
Definition BBApi.h:142
const char szMenuName[]
Definition Menu.cpp:40
int menuMessageSubscription[]
Definition Menu.cpp:50
vector< Menu * > g_Menues
Definition Menu.cpp:47
bool isValidated
Definition Menu.h:151
bool isPinned
Definition Menu.h:152
HINSTANCE hMenuInstance
Definition Menu.h:136
bool keyboardNavigationInProgress
Definition Menu.h:154
static int m_nInstances
Definition Menu.h:137
char * m_pszFolderPath
Definition Menu.h:158
bool m_bMoved
Definition Menu.h:156
Menu * m_pParent
Definition Menu.h:145
HDC cachedMenuBackground
Definition Menu.h:164
friend LRESULT CALLBACK MenuWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition Menu.cpp:1521
HDC menuHDC
Definition Menu.h:163
HDC cachedMenuActive
Definition Menu.h:165
bool mouseIsHovering
Definition Menu.h:153
bool cachedMenuGradientsExist
Definition Menu.h:166
HWND hMenuWnd
Definition Menu.h:143
WIN32_FIND_DATA data
Definition Menu.h:139

◆ ~Menu()

Menu::~Menu ( )
137{
138 // Unsubscribe to previously subscribed Blackbox messages...
139 SendMessage (GetBBWnd(), BB_UNREGISTERMESSAGE, (WPARAM)hMenuWnd, (LPARAM)menuMessageSubscription);
140
141 // Remove this menu instance to the global list of menues...
142 for (unsigned int i=0; i<g_Menues.size(); i++)
143 {
144 if (g_Menues[i] == this)
145 {
146 g_Menues.erase(g_Menues.begin()+i);
147 break;
148 }
149 }
150
151 // Destroy the menu window...
152 if (hMenuWnd) DestroyWindow(hMenuWnd);
153 hMenuWnd = NULL;
154
155 // Delete the cached gradients...
157 if (cachedMenuActive) DeleteDC(cachedMenuActive);
158 if (menuHDC) DeleteDC(menuHDC);
159
160 // Delete all menu items belonging to this menu...
162
163 // Decrease the global count of menu instances...
164 m_nInstances--;
165 if (m_nInstances == 0)
166 {
167 // This is the last menu instance,
168 // so we can unregister the common window class...
169 UnregisterClass(szMenuName, hMenuInstance);
170 }
171
172 // ...and finally, clean up some miscellaneous stuff...
174}
#define BB_UNREGISTERMESSAGE
Definition BBApi.h:143
void DeleteMenuItems()
Definition Menu.cpp:1095

Member Function Documentation

◆ UpdateMenuWindow()

void Menu::UpdateMenuWindow ( )
182{
183 if (!isValidated) return;
184
185 //====================
186
187 // Get the bounding rect of the entire menu...
188 GetClientRect(hMenuWnd, &menuRect);
189 menuWidth = menuRect.right - menuRect.left;
190 menuHeight = menuRect.bottom - menuRect.top;
191
192 // Get the bounding rect of the menu title...
193 CopyRect(&menuTitleRect, &menuRect);
195
197 {
198 // Offset the menu title according to a bbLean bug/feature... (see further below)
201 // ##### WORK IN PROGRESS - COMMENTED OUT EQUIVALENT CODE IN THE "Draw menu title" SECTION BELOW #####
202 }
203
204 // Get the bounding rect of the menu grip... (drawn only if defined in the style file)
206 {
207 CopyRect(&menuGripRect, &menuRect);
209
211 {
212 // Offset the menu grip according to a bbLean bug/feature... (see further below)
214 }
215 }
216
217 // Get the bounding rect of the menu frame...
218 CopyRect(&menuFrameRect, &menuRect);
219// if (!pMenuCommon->m_nTitleDisabled) menuFrameRect.top = pMenuCommon->m_nTitleHeight - pSettings->MenuFrame->borderWidth;
221 else menuFrameRect.top = 0;
222// if (!pSettings->MenuGrip->parentRelative) menuFrameRect.bottom = menuFrameRect.bottom - pMenuCommon->m_nGripHeight + pSettings->MenuFrame->borderWidth;
224 else menuFrameRect.bottom = menuRect.bottom;
225
226 // Get the dimensions of the menu hilite/active...
231
232 //====================
233
234 if (menuHDC == NULL) menuHDC = CreateCompatibleDC(NULL);
235
236 HDC hdc = GetWindowDC(hMenuWnd);
237 HBITMAP bufbmp = CreateCompatibleBitmap(hdc, menuWidth, menuHeight);
238 DeleteObject(SelectObject(menuHDC, bufbmp));
239 ReleaseDC(hMenuWnd, hdc);
240
241 //====================
242
243 // If we have not yet created cached menu gradients, let's do that...
245 {
246 RECT r;
247 HBITMAP tempBitmap, oldBitmap;
248
249 int menuTitleWidth = menuTitleRect.right - menuTitleRect.left;
250 int menuTitleHeight = menuTitleRect.bottom - menuTitleRect.top;
251 int menuFrameWidth = menuFrameRect.right - menuFrameRect.left;
252 int menuFrameHeight = menuFrameRect.bottom - menuFrameRect.top;
253
254 //====================
255
256 // The menu title, frame and (if enabled) grip do not move,
257 // so we can draw them directly onto the same bitmap...
259 cachedMenuBackground = CreateCompatibleDC(NULL);
260
261 tempBitmap = CreateCompatibleBitmap(menuHDC, menuWidth, menuHeight);
262 oldBitmap = (HBITMAP)SelectObject(cachedMenuBackground, tempBitmap);
263 DeleteObject(oldBitmap);
264
265 // Draw menu frame...
268
269 // Draw menu title...
271 {
273 {
274 // A bug/feature (?) in bbLean draws the menu.frame border along the entire menu edge, i.e. the
275 // menu.title border is only visible in between the title and the frame, not along the edges
276 // of the menu. As long as the menu.title and menu.frame borders are the same width and colour,
277 // this does not make any difference. But if they are not, drawing the menu border this way will
278 // create a distinct change in appearance of the menu that is often used by bbLean stylists,
279 // e.g. "Urban Tower" by Shawan -> http://www.boxshots.org/style/3889 . This is not the way the
280 // menu is rendered in our "baseline" bb4nix, but... Let's call this a Request For Comments! ;)
281 // ---------------------------------------------------------------------------------------------
282 // A variant of this bug/feature is when there is a menu.frame border but no menu.title border,
283 // e.g. cthu1hu's "ridge" style -> http://www.boxshots.org/style/4335
284
285 RECT tempTitleRect;
286 CopyRect(&tempTitleRect, &menuTitleRect);
288 {
289// InflateRect(&tempTitleRect, -pSettings->MenuFrame->borderWidth, -pSettings->MenuFrame->borderWidth);
290// tempTitleRect.bottom += pSettings->MenuFrame->borderWidth;
291 }
292
293 // Draw the menu title gradient, or image (stretch resized as applicable to fit the x/y dimensions of the menu item), as applicable...
296
297 // Draw the menu.frame border along the entire menu edge...
299 }
300 else
301 {
302 // Draw the menu title gradient, or image (stretch resized as applicable to fit the x/y dimensions of the menu item), as applicable...
305 }
306 }
307
308 // Draw menu grip...
310 {
312 {
313 // Using the same bug/feature approach for the grip as described above for the title...
314
315 RECT tempGripRect;
316 CopyRect(&tempGripRect, &menuGripRect);
317 if (pSettings->MenuGrip->borderWidth == 0)
318 {
319 InflateRect(&tempGripRect, -pSettings->MenuFrame->borderWidth, -pSettings->MenuFrame->borderWidth);
320 tempGripRect.top -= pSettings->MenuFrame->borderWidth;
321 }
322
323 // Draw the menu grip gradient, or image (stretch resized as applicable to fit the x/y dimensions of the menu item), as applicable...
326
327 // Draw the menu.frame border along the menu edge, but this time only for the bottom part
328 // of the menu to avoid messing up any menu title/frame border overlaps... (see above)
329 RECT borderRect;
330 CopyRect(&borderRect, &menuRect);
331 int top = menuFrameRect.top + pSettings->MenuFrame->borderWidth + 1;
332
333 HPEN borderPen = CreatePen(PS_SOLID, 1, pSettings->MenuFrame->borderColor);
334 HPEN oldPen = (HPEN) SelectObject(cachedMenuBackground, borderPen);
335 for (int i = 0; i < pSettings->MenuFrame->borderWidth; i++)
336 {
337 // Draw border...
338 MoveToEx(cachedMenuBackground, borderRect.left, top, NULL);
339 LineTo(cachedMenuBackground, borderRect.left, borderRect.bottom-1);
340 LineTo(cachedMenuBackground, borderRect.right-1, borderRect.bottom-1);
341 LineTo(cachedMenuBackground, borderRect.right-1, top);
342
343 InflateRect(&borderRect, -1, -1); // Shrink rectangle by 1 pixel...
344 }
345 SelectObject(cachedMenuBackground, oldPen);
346 DeleteObject(borderPen);
347 }
348 else
349 {
350 // Draw the menu grip gradient, or image (stretch resized as applicable to fit the x/y dimensions of the menu item), as applicable...
353 }
354 }
355
356 // ##################################################################################################
357 // ##### BELOW: EXPERIMENTAL SUPPORT FOR GRADIENT BORDERS, NOT YET MEANT FOR PUBLIC CONSUMPTION #####
358 // ##################################################################################################
362 {
364 }
365
366 DeleteObject(tempBitmap);
367
368 //====================
369
370 // Should the menu's corners be rounded off? If so, we need to perform some related pixel re-shuffling
371 // *before* any subsequent per pixel alpha operations... (see further below; these in turn affect pixel data)
373 {
375 {
378 }
380
382 {
385 }
387 }
388
389 //====================
390
391 // We can also draw all menu items in their *non-active* state onto the same bitmap...
392 SetBkMode(cachedMenuBackground, TRANSPARENT);
393
394 MENUITERATOR i;
395 for (i = m_MenuItems.begin(); i != m_MenuItems.end(); i++)
396 {
397 DrawMenuItem(cachedMenuBackground, (MenuItem*)(*i), false);
398 }
399
400 //====================
401
402 // The menu hilite/active follows the mouse pointer,
403 // so we need to be able to draw it separately from
404 // the menu title and frame, i.e. it needs its own bitmap...
405 if (cachedMenuActive) DeleteDC(cachedMenuActive);
406
407 cachedMenuActive = CreateCompatibleDC(NULL);
408 tempBitmap = CreateCompatibleBitmap(menuHDC, menuActiveWidth, menuActiveHeight);
409 oldBitmap = (HBITMAP)SelectObject(cachedMenuActive, tempBitmap);
410 DeleteObject(oldBitmap);
411
412 // Draw the menu active gradient, or image (stretch resized as applicable to fit the x/y dimensions of the menu item), as applicable...
413 SetRect(&r, 0, 0, menuActiveWidth, menuActiveHeight);
416
417 DeleteObject(tempBitmap);
418
419 //====================
420
421 // Finally, we set the "cached menu gradients created" indicator...
423 }
424
425 //====================
426
427 // Copy the cached menu background into the display buffer...
428 BitBlt(menuHDC, 0, 0, menuWidth, menuHeight, cachedMenuBackground, 0, 0, SRCCOPY);
429
430 //====================
431
432 // Draw the active menu item and some dynamically updating things
433 // (e.g. boolean indicators etc) on top of the copied menu background...
434 MENUITERATOR i;
435 for (i = m_MenuItems.begin(); i != m_MenuItems.end(); i++)
436 {
437 // Is this the currently active menu item?
438 if ((*i)->IsActive())
439 {
440 SetBkMode(menuHDC, TRANSPARENT);
441
443 {
444 // Unless it is parentRelative, we first copy the
445 // cached menu.active gradient into the display buffer...
446 RECT itemRect;
447 (*i)->GetItemRect(&itemRect);
448 menuActiveRect.top = itemRect.top;
449 menuActiveRect.bottom = itemRect.top + menuActiveHeight;
451 }
452
453 // ...and then draw text, glyphs etc as applicable on top of it...
454 DrawMenuItem(menuHDC, (MenuItem*)(*i), true);
455 }
456
457 //====================
458
459 if ((*i)->itemType == MENUITEM_EDITSTRING)
460 {
461 StringItem* si = (StringItem*)(*i);
462 if (si->editboxActive)
463 {
464 // Draw the "OK?" button...
465 RECT itemRect;
466 (*i)->GetItemRect(&itemRect);
468 InflateRect(&itemRect, -padding, 0);
470 if (pMenuCommon->m_hFrameFont != NULL) SelectObject(menuHDC, pMenuCommon->m_hFrameFont);
471 DrawTextWithEffects(menuHDC, itemRect, "OK?", DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOCLIP, pSettings->MenuActive->TextColor, pSettings->MenuActive->FontOutline, pSettings->MenuActive->OutlineColor, pSettings->MenuActive->FontShadow, pSettings->MenuActive->ShadowColor, pSettings->MenuActive->ShadowX, pSettings->MenuActive->ShadowY);
472 }
473 }
474
475 //====================
476
477 if ((*i)->m_isSelected) pMenuCommon->DrawMenuIndicator((*i), menuHDC, (*i)->m_nTop);
478 }
479
480 //====================
481
482 // Apply per pixel alpha transparency selectively per menu element...
484
485 RECT r;
486
488 {
490 {
493 }
494 }
495
497 {
499 {
502 }
503 else
504 {
507 }
509 }
510
512 {
514 {
517 }
518 }
519
520 for (i = m_MenuItems.begin(); i != m_MenuItems.end(); i++)
521 {
522 if ((*i)->m_bActive)
523 {
524// (*i)->GetItemRect(&r);
525// if (!pSettings->MenuActive->parentRelative) AlphaRect(menuHDC, r, pSettings->menuActiveTransparencyAlpha);
527 }
528 }
529
531 {
536 }
537
539
540 //====================
541
542 if (bufbmp) DeleteObject(bufbmp);
543
544 POINT pt;
545 pt.x = menuX, pt.y = menuY;
546 POINT ptSrc;
547 ptSrc.x = 0, ptSrc.y = 0;
548
549 BLENDFUNCTION bf;
550 bf.BlendOp = AC_SRC_OVER;
551 bf.BlendFlags = 0;
552 bf.AlphaFormat = AC_SRC_ALPHA;
553 bf.SourceConstantAlpha = (unsigned char)255;
554
555 SIZE windowSize = { menuWidth, menuHeight };
556 BOOL result = UpdateLayeredWindow(hMenuWnd, NULL, &pt, &windowSize, menuHDC, &ptSrc, 0, &bf, ULW_ALPHA);
557/*
558 if (!menuHDC) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"xoblite -> Menu -> Invalid menuHDC!");
559
560 if (result == 0)
561 {
562 int error = GetLastError();
563 char msg[255];
564 sprintf(msg, "xoblite -> Menu -> UpdateLayeredWindow failed! [error code %d]", error);
565 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)msg);
566 }
567*/
568}
void DrawImageIntoRect(HDC hdc, RECT r, StyleItem *styleItem, bool useAlpha, bool drawBorder)
Definition BBApi.cpp:2333
void AlphaApply(HDC hdc, RECT rect)
Definition BBApi.cpp:2449
void AlphaCorner(HDC hdc, RECT rect, int corner, int bevelStyle, int bevelPosition, int bevelWidth, int borderWidth, unsigned char minAlpha, unsigned char maxAlpha)
Definition BBApi.cpp:2431
void MakeGradientSuper(HDC hdc, RECT rect, int type, COLORREF color1, COLORREF color2, COLORREF color3, COLORREF color4, COLORREF color5, COLORREF color6, COLORREF color7, COLORREF color8, bool bInterlaced, int bevelStyle, int bevelPosition, int bevelWidth, COLORREF borderColour, int borderWidth)
Definition BBApi.cpp:2127
MenuCommon * pMenuCommon
Definition Blackbox.cpp:41
void PrepareCorner(HDC hdc, RECT rect, int corner, int bevelStyle, int bevelPosition, int bevelWidth, int borderWidth)
Definition BBApi.cpp:2462
void AlphaRect(HDC hdc, RECT rect, unsigned char alpha)
Definition BBApi.cpp:2419
void CreateBorderSuper(HDC hdc, RECT rect, int type, COLORREF color1, COLORREF color2, COLORREF color3, COLORREF color4, COLORREF color5, COLORREF color6, COLORREF color7, COLORREF color8, int borderWidth)
Definition BBApi.cpp:2250
void DrawTextWithEffects(HDC hdc, RECT r, LPSTR text, unsigned int format, COLORREF textColor, bool outline, COLORREF outlineColor, bool shadow, COLORREF shadowColor, int shadowX, int shadowY)
Definition BBApi.cpp:3519
Settings * pSettings
Definition Blackbox.cpp:46
void CreateBorder(HDC hdc, RECT *rect, int borderColour, int borderWidth)
Definition BBApi.cpp:2243
#define CORNER_BOTTOMRIGHT
Definition BBApi.h:128
#define CORNER_BOTTOMLEFT
Definition BBApi.h:127
#define CORNER_TOPLEFT
Definition BBApi.h:125
#define B_IMAGEFROMFILE
Definition BBApi.h:83
#define B_PARENTRELATIVE
Definition BBApi.h:69
#define CORNER_TOPRIGHT
Definition BBApi.h:126
vector< MenuItem * >::iterator MENUITERATOR
Definition Menu.h:53
#define MENUITEM_EDITSTRING
Definition MenuItem.h:43
int m_nTitleHeight
Definition MenuCommon.h:102
int m_nGripHeight
Definition MenuCommon.h:107
bool m_nTitleDisabled
Definition MenuCommon.h:103
void DrawMenuIndicator(MenuItem *item, HDC hDC, int nTop)
Definition MenuCommon.cpp:2297
int m_nSubmenuHeight
Definition MenuCommon.h:104
bool m_nGripDisabled
Definition MenuCommon.h:108
HFONT m_hFrameFont
Definition MenuCommon.h:125
RECT menuRect
Definition Menu.h:169
RECT menuFrameRect
Definition Menu.h:171
int menuX
Definition Menu.h:176
int menuWidth
Definition Menu.h:177
RECT menuTitleRect
Definition Menu.h:170
vector< MenuItem * > m_MenuItems
Definition Menu.h:146
int menuActiveHeight
Definition Menu.h:178
void DrawMenuItem(HDC hdc, MenuItem *i, bool active)
Definition Menu.cpp:575
int menuY
Definition Menu.h:176
int menuHeight
Definition Menu.h:177
RECT menuGripRect
Definition Menu.h:173
RECT menuActiveRect
Definition Menu.h:172
int menuActiveWidth
Definition Menu.h:178
BYTE menuActiveTransparencyAlpha
Definition Settings.h:181
BYTE menuTitleTransparencyAlpha
Definition Settings.h:178
StyleItem * MenuFrame
Definition Settings.h:434
BYTE menuFrameTransparencyAlpha
Definition Settings.h:179
StyleItem * MenuTitle
Definition Settings.h:433
BYTE menuGripTransparencyAlpha
Definition Settings.h:180
bool menuRoundedCorners
Definition Settings.h:176
StyleItem * MenuFrameBorder
Definition Settings.h:441
BYTE menuTransparencyAlpha
Definition Settings.h:177
int bevelWidth
Definition Settings.h:564
StyleItem * MenuGrip
Definition Settings.h:436
StyleItem * MenuActive
Definition Settings.h:435
bool editboxActive
Definition StringItem.h:59
int borderWidth
Definition BBApi.h:417
COLORREF Color5
Definition BBApi.h:436
int bevelstyle
Definition BBApi.h:400
COLORREF Color4
Definition BBApi.h:434
bool parentRelative
Definition BBApi.h:403
COLORREF TextColor
Definition BBApi.h:408
bool FontOutline
Definition BBApi.h:430
COLORREF Color6
Definition BBApi.h:437
int type
Definition BBApi.h:402
char ShadowX
Definition BBApi.h:426
int bevelposition
Definition BBApi.h:401
COLORREF Color7
Definition BBApi.h:438
char ShadowY
Definition BBApi.h:426
COLORREF Color8
Definition BBApi.h:439
COLORREF OutlineColor
Definition BBApi.h:431
bool FontShadow
Definition BBApi.h:423
bool interlaced
Definition BBApi.h:404
COLORREF ShadowColor
Definition BBApi.h:429
COLORREF Color3
Definition BBApi.h:433
COLORREF borderColor
Definition BBApi.h:418
int marginWidth
Definition BBApi.h:416

◆ DrawMenuItem()

void Menu::DrawMenuItem ( HDC hdc,
MenuItem * i,
bool active )
576{
577 if (i->itemType == MENUITEM_MARGINPAD) return;
578
579 SetBkMode(hdc, TRANSPARENT);
580
581 RECT itemRect, textRect;
582 i->GetItemRect(&itemRect);
583 i->GetTitleRect(&textRect);
584
585 //====================
586
587 if (i->itemType == MENUITEM_FOLDER)
588 {
589 pMenuCommon->DrawMenuBullet((FolderItem*)i, hdc, itemRect.top, pMenuCommon->m_nBulletStyle);
590 }
591
592 //====================
593
594 if (i->itemType == MENUITEM_HEADER)
595 {
597 {
598 // Is the menu pinned? If so, let's draw the menu pinned indicator on the title item...
599 if (IsPinned())
600 {
601 int indentText = pMenuCommon->DrawMenuPinned(i, hdc, itemRect);
602 if (pSettings->MenuTitle->Justify == DT_CENTER)
603 {
604 textRect.left = itemRect.left + indentText;
605 textRect.right = itemRect.right - indentText;
606 }
607 else if (pMenuCommon->m_nBulletPosition == DT_LEFT) textRect.right = itemRect.right - indentText;
608 else textRect.left = itemRect.left + indentText;
609 }
610
611 // Draw the menu title text...
612 if (pMenuCommon->m_hTitleFont != NULL) SelectObject(hdc, pMenuCommon->m_hTitleFont);
615 }
616 }
617
618 //====================
619
620 else if (i->itemType == MENUITEM_FOOTER)
621 {
623 {
624 if ((pSettings->MenuGrip->FontHeight > 0) && strlen(i->m_pszTitleANSI))
625 {
626 // Draw the menu grip text...
627 if (pMenuCommon->m_hGripFont != NULL) SelectObject(hdc, pMenuCommon->m_hGripFont);
630 }
631 }
632 }
633
634 //====================
635
636 else if (i->itemType == MENUITEM_SEPARATOR)
637 {
638 RECT sepRect;
639 sepRect.left = itemRect.left + pSettings->MenuFrame->borderWidth + pSettings->MenuFrame->marginWidth + 3;
640 sepRect.right = itemRect.left + i->GetWidth() - pSettings->MenuFrame->borderWidth - pSettings->MenuFrame->marginWidth - 3;
641 if (pSettings->MenuSeparator->ShadowX < 0) sepRect.left -= pSettings->MenuSeparator->ShadowX;
642 else sepRect.right -= pSettings->MenuSeparator->ShadowX;
643
644 sepRect.top = itemRect.top + (2 * pSettings->scalingFactorHiDPI);
645 sepRect.bottom = sepRect.top + (1 * pSettings->scalingFactorHiDPI);
646
648 {
650 if (pSettings->MenuSeparator->type == B_MIRRORHORIZONTAL) MakeGradientSuper(hdc, sepRect, B_SPLITHORIZONTAL, GetPixel(hdc, sepRect.left, sepRect.top), pSettings->MenuSeparator->ShadowColor, pSettings->MenuSeparator->ShadowColor, GetPixel(hdc, sepRect.right, sepRect.bottom), 0, 0, 0, 0, false, BEVEL_FLAT, BEVEL1, 0, 0, 0);
651 else MakeGradientSuper(hdc, sepRect, B_SOLID, pSettings->MenuSeparator->ShadowColor, 0, 0, 0, 0, 0, 0, 0, false, BEVEL_FLAT, BEVEL1, 0, 0, 0);
652 OffsetRect(&sepRect, -pSettings->MenuSeparator->ShadowX, -pSettings->MenuSeparator->ShadowY);
653 }
654
655// MakeGradientSuper(hdc, sepRect, B_MIRRORHORIZONTAL, pSettings->MenuFrame->Color, pSettings->MenuSeparator->Color, 0, 0, 0, 0, 0, 0, false, BEVEL_FLAT, BEVEL1, 0, 0, 0);
657 }
658
659 //====================
660
661 else if (i->itemType == MENUITEM_NOP)
662 {
663 if (pMenuCommon->m_hFrameFont != NULL) SelectObject(hdc, pMenuCommon->m_hFrameFont);
664// DrawTextWithEffects(hdc, textRect, i->m_pszTitleANSI, i->GetDrawTextFormat(), pSettings->MenuFrame->disabledColor, pSettings->MenuFrame->FontOutline, pSettings->MenuFrame->OutlineColor, pSettings->MenuFrame->FontShadow, pSettings->MenuFrame->ShadowColor, pSettings->MenuFrame->ShadowX, pSettings->MenuFrame->ShadowY);
667 }
668
669 //====================
670
671 else if (i->itemType == MENUITEM_EDITSTRING)
672 {
673 StringItem* si = (StringItem*)i;
674 if (!si->editboxActive)
675 {
676 // Draw the regular string item text... (i.e. OK button hidden)
677 if (pMenuCommon->m_hFrameFont != NULL) SelectObject(hdc, pMenuCommon->m_hFrameFont);
678
679 if (wcslen(i->m_pszTitleUnicode) > 0)
680 {
683 }
684 else
685 {
688 }
689
690// if (i->m_isSelected) pMenuCommon->DrawMenuIndicator(i, hdc, i->m_nTop);
691 }
692 }
693
694 //====================
695
696 else // MENUITEM_COMMAND, MENUITEM_EDITINT, etc
697 {
698
699 if (pMenuCommon->m_hFrameFont != NULL) SelectObject(hdc, pMenuCommon->m_hFrameFont);
700
701 if (wcslen(i->m_pszTitleUnicode) > 0)
702 {
705 }
706 else
707 {
710 }
711
712// if (i->m_isSelected) pMenuCommon->DrawMenuIndicator(i, hdc, i->m_nTop);
713 }
714}
void DrawTextWithEffectsUnicode(HDC hdc, RECT r, LPWSTR text, unsigned int format, COLORREF textColor, bool outline, COLORREF outlineColor, bool shadow, COLORREF shadowColor, int shadowX, int shadowY)
Definition BBApi.cpp:3528
#define BEVEL1
Definition BBApi.h:108
#define B_MIRRORHORIZONTAL
Definition BBApi.h:95
#define B_SOLID
Definition BBApi.h:80
#define BEVEL_FLAT
Definition BBApi.h:105
#define B_SPLITHORIZONTAL
Definition BBApi.h:86
#define MENUITEM_HEADER
Definition MenuItem.h:38
#define MENUITEM_MARGINPAD
Definition MenuItem.h:39
#define MENUITEM_NOP
Definition MenuItem.h:46
#define MENUITEM_SEPARATOR
Definition MenuItem.h:47
#define MENUITEM_FOOTER
Definition MenuItem.h:40
#define MENUITEM_FOLDER
Definition MenuItem.h:48
void DrawMenuBullet(FolderItem *item, HDC hDC, int nTop, int type)
Definition MenuCommon.cpp:1845
HFONT m_hTitleFont
Definition MenuCommon.h:124
int DrawMenuPinned(MenuItem *item, HDC hDC, RECT itemRect)
Definition MenuCommon.cpp:2384
int m_nBulletStyle
Definition MenuCommon.h:115
HFONT m_hGripFont
Definition MenuCommon.h:126
int m_nBulletPosition
Definition MenuCommon.h:114
bool IsPinned()
Definition Menu.cpp:1497
virtual void GetTitleRect(RECT *r)
Definition MenuItem.cpp:414
virtual int GetWidth()
Definition MenuItem.h:120
wchar_t * m_pszTitleUnicode
Definition MenuItem.h:94
virtual UINT GetDrawTextFormat()
Definition MenuItem.cpp:437
virtual void GetItemRect(RECT *r)
Definition MenuItem.cpp:404
char * m_pszTitleANSI
Definition MenuItem.h:93
int itemType
Definition MenuItem.h:95
int scalingFactorHiDPI
Definition Settings.h:327
StyleItem * MenuSeparator
Definition Settings.h:440
COLORREF disabledColor
Definition BBApi.h:420
int Justify
Definition BBApi.h:411
int FontHeight
Definition BBApi.h:409

◆ Show() [1/2]

void Menu::Show ( )
722{
723 POINT p;
724 GetCursorPos(&p);
725
726 if (m_pParent != NULL)
727 {
728 RECT r;
729 GetWindowRect(m_pParent->GetWindow(), &r);
730 int width = r.right - r.left;
731 p.x -= width / 2;
732 p.y -= pMenuCommon->m_nTitleHeight / 2;
733 Show(r.right - 5, p.y - 5);
734 }
735 else
736 {
737 RECT r;
738 GetWindowRect(GetWindow(), &r);
739 int width = r.right - r.left;
740 p.x -= width / 2;
741 p.y -= pMenuCommon->m_nTitleHeight / 2;
742 Show(p.x, p.y);
743 }
744}
void Show()
Definition Menu.cpp:721
HWND GetWindow()
Definition Menu.cpp:1183

◆ Show() [2/2]

void Menu::Show ( int x,
int y )
749{
750 OnShow(true);
751
752 GetClientRect(hMenuWnd, &menuRect);
753 menuWidth = menuRect.right - menuRect.left;
754 menuHeight = menuRect.bottom - menuRect.top;
755
756 //====================
757
758 RECT screenRect;
759 POINT pt = { x ,y };
760
761 HMONITOR hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
762
763 MONITORINFO mi;
764 mi.cbSize = sizeof(mi);
765
766 if (GetMonitorInfo(hMon, &mi))
767 {
768 screenRect.left = mi.rcMonitor.left;
769 screenRect.top = mi.rcMonitor.top;
770 screenRect.right = mi.rcMonitor.right;
771 screenRect.bottom = mi.rcMonitor.bottom;
772 }
773 else
774 {
775 screenRect.left = 0;
776 screenRect.top = 0;
777 screenRect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
778 screenRect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
779 }
780
781 if ((pt.x + menuWidth) > screenRect.right) pt.x = screenRect.right - menuWidth;
782 if ((pt.y + menuHeight) > screenRect.bottom) pt.y = screenRect.bottom - menuHeight;
783
784 if (pt.x < screenRect.left) pt.x = screenRect.left;
785 if (pt.y < screenRect.top) pt.y = screenRect.top;
786
787 menuX = pt.x;
788 menuY = pt.y;
789
790 //====================
791
793
794 SetWindowPos(hMenuWnd, HWND_TOP, menuX, menuY, 0, 0, SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOSIZE);
795// ShowWindow(hMenuWnd, SW_SHOWNOACTIVATE);
796 ShowWindow(hMenuWnd, SW_SHOWNORMAL);
797
798 if (m_pParent == NULL) SetForegroundWindow(hMenuWnd); // Note: Submenus set focus themselves, see FolderItem.cpp
799}
void UpdateMenuWindow()
Definition Menu.cpp:181
virtual void OnShow(bool fShow)
Definition Menu.h:117

◆ Hide()

bool Menu::Hide ( int h)
807{
808 bool menusHaveBeenHidden = false;
809
810 if (h != HIDE_OTHERS) // Hide this menu?
811 {
812 if (!IsPinned())
813 {
814 if (IsWindowVisible(hMenuWnd))
815 {
816 if (m_pParent != NULL) SetForegroundWindow(m_pParent->GetWindow());
817
818 ShowWindow(hMenuWnd, SW_HIDE);
819 OnShow(false);
820
821 // Destroy the cached menu gradients to save GDI objects + memory...
824 if (cachedMenuActive) DeleteDC(cachedMenuActive);
826
828
829 menusHaveBeenHidden = true;
830 }
831 }
832
833 MENUITERATOR item;
834 for (item = m_MenuItems.begin(); item != m_MenuItems.end(); item++)
835 {
836 (*item)->Active(false);
837
838 if ((*item)->itemType == MENUITEM_EDITSTRING)
839 {
840 StringItem* si = (StringItem*)*item;
841 if (si->editboxActive) // Any open string editor window belonging to the menu item?
842 {
843 // If so, we destroy the string editor window and
844 // clear the global "menu item editbox open" flag...
845 si->DestroyEditWindow();
847 si->editboxActive = false;
848 }
849 }
850 }
851 }
852
853 //====================
854
855 if (h == HIDE_CHILDREN || h == HIDE_OTHERS) // Hide child menus?
856 {
857 for (unsigned int i = 0; i < m_Children.size(); i++)
858 {
859 // Hide all child menus of this menu...
860 if (IsWindowVisible(m_Children[i]->GetWindow()) && !m_Children[i]->IsPinned())
861 {
862 ShowWindow(m_Children[i]->GetWindow(), SW_HIDE);
863 menusHaveBeenHidden = true;
864 }
865 // Hide any lower level child menus... (i.e. children of children and downwards)
866 if (m_Children[i]->Hide(HIDE_CHILDREN)) menusHaveBeenHidden = true;
867 }
868 }
869
870 //====================
871
872 if (h == HIDE_PARENTS || h == HIDE_OTHERS) // Hide parent menus?
873 {
874 if (m_pParent)
875 {
876 // Hide parent menu...
877 if (IsWindowVisible(m_pParent->GetWindow()) && !m_pParent->IsPinned())
878 {
879 ShowWindow(m_pParent->GetWindow(), SW_HIDE);
880 menusHaveBeenHidden = true;
881 }
882 // Hide any higher level parent menus... (i.e. parent of parent and upwards)
883 if (m_pParent->Hide(HIDE_PARENTS)) menusHaveBeenHidden = true;
884 }
885 }
886
887 //====================
888
889 return menusHaveBeenHidden;
890}
#define HIDE_OTHERS
Definition Menu.h:38
#define HIDE_PARENTS
Definition Menu.h:41
#define HIDE_CHILDREN
Definition Menu.h:39
bool Hide(int h)
Definition Menu.cpp:806
vector< Menu * > m_Children
Definition Menu.h:147
bool menuEditboxAlreadyActive
Definition Settings.h:388
void DestroyEditWindow()
Definition StringItem.cpp:125

◆ Mouse()

void Menu::Mouse ( UINT nMsg,
int x,
int y )
898{
899 if (!isValidated) return;
900
901 MENUITERATOR item;
902 POINT pt = {x, y};
903
904 //====================
905
906 if (!m_bMoved)
907 {
908 for (item = m_MenuItems.begin(); item != m_MenuItems.end() && !m_MenuItems.empty(); item++) // Note: By checking for the empty list we keep the core shell from crashing if a message box is opened, the shell reconfigured, and the message box closed... / Tres`ni
909 {
910 (*item)->Mouse(nMsg, pt);
911 }
912 }
913
914 //====================
915
916 if (nMsg == WM_MOUSEMOVE)
917 {
918 RECT r;
919 m_bMoved = false;
920 GetWindowRect(hMenuWnd, &r);
921 ClientToScreen(hMenuWnd, &pt);
922
923 int screenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
924 int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
925
926 if ((r.bottom > screenHeight) && (pt.y + 1 >= screenHeight))
927 {
928 // The popup is larger than the screen and the
929 // cursor is at the bottom -> scroll down a bit...
930// r.top -= pSettings->scrollSpeed;
932 m_bMoved = true;
933 }
934 else if ((r.top < screenTop) && (pt.y <= screenTop))
935 {
936 // The popup is larger than the screen and the
937 // cursor is at the top -> scroll up at bit...
938// r.top += pSettings->scrollSpeed;
940 m_bMoved = true;
941 }
942
943 if (m_bMoved)
944 {
947 menuX = r.left;
948 menuY = r.top;
949 SetWindowPos(hMenuWnd, NULL, menuX, menuY, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOSENDCHANGING);
950 }
951
952 // Track the mouse...
953 if (!mouseIsHovering)
954 {
955 mouseIsHovering = true;
957 }
958 }
959
960 //====================
961
962 else if (nMsg == WM_MOUSEWHEEL)
963 {
965
966 RECT r;
967 GetWindowRect(hMenuWnd, &r);
968
969 // Only allow mousewheel scrolling if the menu is taller than the screen...
970 int height = r.bottom - r.top;
971 int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
972 if (height < screenHeight) return;
973
974 //====================
975
976 if (x > 0) // Scrolling upwards...
977 {
978// r.top += pSettings->wheelSpeed;
980 r.bottom = r.top + height;
981
982 if (r.top > 0)
983 {
984 r.top = 0;
985 r.bottom = height;
986 }
987 }
988 else // Scrolling downwards...
989 {
990// r.top -= pSettings->wheelSpeed;
992 r.bottom = r.top + height;
993
994 if (r.bottom < screenHeight)
995 {
996 r.top = screenHeight - height;
997 r.bottom = screenHeight;
998 }
999 }
1000
1001 //====================
1002
1003 menuX = r.left;
1004 menuY = r.top;
1005 SetWindowPos(hMenuWnd, NULL, menuX, menuY, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOSENDCHANGING);
1006 }
1007}
PreviewItem * pPreviewItem
Definition Blackbox.cpp:45
#define MENU_TRACK_MOUSE_TIMER
Definition Menu.h:49
bool FindActiveAndDeactivate(Menu *m, bool repaint)
Definition MenuCommon.cpp:2459
static void CALLBACK TrackMouseProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition Menu.cpp:1011
void Hide()
Definition PreviewItem.cpp:316

◆ TrackMouseProc()

void Menu::TrackMouseProc ( HWND hWnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime )
static
1012{
1014
1015 POINT pt;
1016 HWND hWndNew;
1017
1018 GetCursorPos(&pt);
1019 hWndNew = WindowFromPoint(pt);
1020
1021// if (hWnd != GetForegroundWindow()) SetForegroundWindow(hWnd);
1022
1023 if (::GetParent(hWndNew) != hWnd)
1024 {
1025 RECT rect;
1026
1027 GetClientRect(hWnd, &rect);
1028 MapWindowPoints(hWnd, NULL, (LPPOINT)&rect,2);
1029
1030 if (!PtInRect(&rect, pt) || (hWndNew != hWnd))
1031 {
1032 KillTimer(hWnd, idEvent);
1033 PostMessage(hWnd, WM_MOUSELEAVE, 0, 0);
1034 }
1035 }
1036}
Menu * GetParent()
Definition Menu.cpp:1201

◆ MouseLeave()

void Menu::MouseLeave ( )
1041{
1042 if (!isValidated) return;
1043
1044 POINT p;
1045 HWND hWnd;
1046
1047 GetCursorPos(&p);
1048 hWnd = WindowFromPoint(p);
1049
1050 if (!IsChildWindow(hWnd)) pMenuCommon->FindActiveAndDeactivate(this, true);
1052
1053 mouseIsHovering = false;
1054}
bool IsChildWindow(HWND hWnd)
Definition Menu.cpp:1231

◆ AddMenuItem()

void Menu::AddMenuItem ( MenuItem * m)
1062{
1063 m_MenuItems.push_back(m);
1064
1065 // Notify the menu item that it has been attached...
1066 m->Attached(this);
1067}
virtual void Attached(Menu *pMenu)
Definition MenuItem.cpp:465

◆ DeleteMenuItems()

void Menu::DeleteMenuItems ( )
1096{
1097 // Block access to the menu structure until validated again...
1098 Invalidate();
1099
1100 // Remove the menu from the set of global menues...
1101 MENUITERATOR item;
1102 for (item = m_MenuItems.begin(); item != m_MenuItems.end(); ++item)
1103 {
1104 delete *item;
1105 }
1106 m_MenuItems.clear();
1107}
void Invalidate()
Definition Menu.cpp:1318

◆ TogglePinned()

void Menu::TogglePinned ( )
1464{
1465 Menu* pParent = this;
1466 while (pParent->m_pParent != NULL) pParent = pParent->m_pParent;
1467 // For the time being, we do not allow pinning of plugin menus... (tbd)
1468// if (pParent == pMenuCommon->m_pPluginMenu) return;
1469 // ...and there's no use pinning the themes menu since clicking
1470 // on a [theme] menu item will restart the core elements anyway...
1471 if (pParent == pMenuCommon->m_pThemesMenu) return;
1472
1473 //====================
1474
1475 if (isPinned)
1476 {
1477 // Unpin and hide the menu...
1478 isPinned = false;
1480 pMenuCommon->Hide();
1481 }
1482 else
1483 {
1484 // Pin the menu...
1485 isPinned = true;
1487 }
1488
1489 Invalidate();
1490 Validate();
1491
1493}
bool Hide(int index=0)
Definition MenuCommon.cpp:1028
Menu * m_pThemesMenu
Definition MenuCommon.h:119
Menu * m_pStylesMenu
Definition MenuCommon.h:118
int stylesMenusPinned
Definition MenuCommon.h:130
Menu(HINSTANCE hInstance)
Definition Menu.cpp:54
void Validate()
Definition Menu.cpp:1325

◆ IsPinned()

bool Menu::IsPinned ( )
1498{
1499 return isPinned;
1500};

◆ NcHitTest()

LRESULT Menu::NcHitTest ( int x,
int y )
1164{
1165 if (!isValidated) return 0;
1166
1167 LRESULT r;
1168 MENUITERATOR item;
1169
1170 for (item=m_MenuItems.begin(); item != m_MenuItems.end(); item++)
1171 {
1172 if ((r = (*item)->NcHitTest(x, y)) != 0) return r;
1173 }
1174
1175 return 0;
1176}

◆ Timer()

void Menu::Timer ( int nTimer)
1135{
1136 if (!isValidated) return;
1137
1138 MENUITERATOR item;
1139 for (item = m_MenuItems.begin(); item != m_MenuItems.end(); item++)
1140 {
1141 (*item)->Timer(nTimer);
1142 }
1143
1144 OnTimer(nTimer);
1145}
virtual void OnTimer(int nTimer)
Definition Menu.h:118

◆ GetWindow()

HWND Menu::GetWindow ( )
1184{
1185 return hMenuWnd;
1186}

◆ SetParent()

void Menu::SetParent ( Menu * pParent)
1195{
1196 m_pParent = pParent;
1197}

◆ GetParent()

Menu * Menu::GetParent ( )
1202{
1203 return m_pParent;
1204}

◆ AddChild()

void Menu::AddChild ( Menu * pChild)
1212{
1213 m_Children.push_back(pChild);
1214}

◆ RemoveChild()

void Menu::RemoveChild ( Menu * pChild)
1219{
1220 for (unsigned int i=0; i<m_Children.size(); i++)
1221 {
1222 if (m_Children[i] == pChild) m_Children.erase(m_Children.begin()+i);
1223 }
1224}

◆ IsChildWindow()

bool Menu::IsChildWindow ( HWND hWnd)
1232{
1233 for (unsigned int i = 0; i < m_Children.size(); i++)
1234 {
1235 if (hWnd == m_Children[i]->hMenuWnd) return true;
1236 else if (m_Children[i]->IsChildWindow(hWnd)) return true;
1237 }
1238
1239 return false;
1240}

◆ SetMenuFolderPath()

void Menu::SetMenuFolderPath ( char * pszFolderPath)
1153{
1155 m_pszFolderPath = pszFolderPath ? _strdup(pszFolderPath) : _strdup("");
1156}

◆ Moving()

void Menu::Moving ( )
1248{
1249 if (!isValidated) return;
1250
1252
1253 MENUITERATOR item;
1254 HCURSOR hCurs = LoadCursor(NULL, IDC_SIZEALL);
1255
1256 for (item=m_MenuItems.begin(); item != m_MenuItems.end(); item++)
1257 {
1258 (*item)->Moving();
1259 SetCursor(hCurs);
1260 }
1261}

◆ OnUser()

bool Menu::OnUser ( int nMessage,
WPARAM wParam,
LPARAM lParam,
LRESULT & lResult )
virtual

Reimplemented in WorkspacesMenu.

1269{
1270 if (!isValidated) return false;
1271
1272 for (MENUITERATOR i = m_MenuItems.begin(); i != m_MenuItems.end(); i++)
1273 {
1274 if ((*i)->OnUser(nMessage, wParam, lParam, lResult)) return true;
1275 }
1276
1277 return false;
1278}

◆ Command()

LRESULT Menu::Command ( WPARAM wParam,
LPARAM lParam )
1286{
1287 if (!isValidated) return 0;
1288
1289 LRESULT l=0;
1290 MENUITERATOR item;
1291
1292 for (item = m_MenuItems.begin(); item != m_MenuItems.end(); ++item)
1293 {
1294 l = (*item)->Command(wParam, lParam);
1295 if (l != 0) break;
1296 }
1297
1298 return l;
1299}

◆ OnShow()

virtual void Menu::OnShow ( bool fShow)
virtual

Reimplemented in ConfigMenu, StylesMenu, ThemesMenu, and WorkspacesMenu.

117{ } // Respond to the WM_SHOWWINDOW message

◆ OnTimer()

virtual void Menu::OnTimer ( int nTimer)
virtual
118{ } // Respond to the WM_TIMER message

◆ Activate()

void Menu::Activate ( int fActive,
HWND hWnd )
1115{
1116 // Nothing to do here... :)
1117}

◆ IsActive()

bool Menu::IsActive ( )
1125{
1126 return GetActiveWindow() == hMenuWnd;
1127}

◆ Sort()

void Menu::Sort ( int beginOffset,
int endOffset )
1307{
1308 // Sort the menu items...
1309 sort(m_MenuItems.begin()+beginOffset, m_MenuItems.end()-endOffset, MenuItem::Compare);
1310}
static bool Compare(MenuItem *pM1, MenuItem *pM2)
Definition MenuItem.cpp:491

◆ Invalidate()

void Menu::Invalidate ( )
1319{
1320 isValidated = false;
1321}

◆ Validate()

void Menu::Validate ( )
1326{
1327 if (isValidated) return;
1328
1329 //====================
1330
1331 // Calculate width padding for the menu title, frame and grip items...
1332
1333 int titleWidthPadding;
1335 {
1336 titleWidthPadding = (2 * pSettings->MenuTitle->borderWidth) + (2 * pSettings->MenuTitle->marginWidth);
1337 }
1338 else // "Legacy fallback"
1339 {
1340 titleWidthPadding = (2 * pSettings->MenuTitle->borderWidth) + (2 * pSettings->bevelWidth) + 4;
1341 }
1342 if (pSettings->MenuTitle->FontOutline) titleWidthPadding += 2;
1343
1344 int frameWidthPadding;
1346 if (pSettings->MenuFrame->FontOutline || pSettings->MenuActive->FontOutline) frameWidthPadding += 2;
1347
1348 int gripWidthPadding;
1349 if (pSettings->MenuGrip->marginWidth > 0)
1350 {
1351 gripWidthPadding = (2 * pSettings->MenuGrip->borderWidth) + (2 * pSettings->MenuGrip->marginWidth);
1352 }
1353 else // "Legacy fallback"
1354 {
1355 gripWidthPadding = (2 * pSettings->MenuGrip->borderWidth) + (2 * pSettings->bevelWidth) + 4;
1356 }
1357 if (pSettings->MenuGrip->FontOutline) gripWidthPadding += 2;
1358
1359 //====================
1360
1361 MENUITERATOR i;
1362 HDC hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
1363 HFONT hFontSaved = NULL;
1364 SIZE size;
1365 int tempMenuWidth = 0;
1366
1367 for (i = m_MenuItems.begin(); i != m_MenuItems.end(); i++)
1368 {
1369 if ((strlen((*i)->m_pszTitleANSI) > 0) || (wcslen((*i)->m_pszTitleUnicode) > 0))
1370 {
1371 // Get the non-truncated width of this menu item's text...
1372 if ((*i)->itemType == MENUITEM_HEADER) hFontSaved = (HFONT) SelectObject(hDC, pMenuCommon->m_hTitleFont);
1373 else if ((*i)->itemType == MENUITEM_FOOTER) hFontSaved = (HFONT) SelectObject(hDC, pMenuCommon->m_hGripFont);
1374 else hFontSaved = (HFONT) SelectObject(hDC, pMenuCommon->m_hFrameFont);
1375
1376 if (wcslen((*i)->m_pszTitleUnicode) > 0) GetTextExtentPoint32W(hDC, (*i)->m_pszTitleUnicode, wcslen((*i)->m_pszTitleUnicode), &size);
1377 else GetTextExtentPoint32(hDC, (*i)->m_pszTitleANSI, strlen((*i)->m_pszTitleANSI), &size);
1378
1379 SelectObject(hDC, hFontSaved);
1380
1381 if ((*i)->itemType == MENUITEM_HEADER)
1382 {
1384 {
1385 (*i)->SetWidth(size.cx + 2 + titleWidthPadding);
1386 }
1387 else (*i)->SetWidth(0); // menu.title disabled, do not include it when calculating the menu width...
1388 }
1389 else if ((*i)->itemType == MENUITEM_FOOTER)
1390 {
1392 {
1393 (*i)->SetWidth(size.cx + 2 + gripWidthPadding);
1394 }
1395 else (*i)->SetWidth(0); // menu.grip disabled, do not include it when calculating the menu width...
1396 }
1397 else (*i)->SetWidth(size.cx + 2 + frameWidthPadding);
1398
1399 // Find the widest menu item belonging to this menu...
1400 tempMenuWidth = max((*i)->GetWidth(), tempMenuWidth);
1401 }
1402 }
1403
1404 DeleteDC(hDC);
1405
1406 //====================
1407
1408 // Make sure that no menu item is wider than the maximum... (-> 300 pixels multiplied by the HiDPI scaling factor)
1409 tempMenuWidth = min((tempMenuWidth + (pSettings->MenuFrame->borderWidth * 2)), (300 * pSettings->scalingFactorHiDPI));
1410
1411 //====================
1412
1413 int tempMenuHeight = 0;
1414
1416 {
1417 // Offset menu title according to bbLean bug/feature... (see above)
1419 }
1420 else tempMenuHeight = 0;
1421/*
1422 if (!pSettings->MenuTitle->parentRelative && ((pSettings->MenuTitle->FontHeight > 0) || (pSettings->MenuTitle->marginWidth > 0)))
1423 {
1424 if (pSettings->MenuFrame->borderWidth > pSettings->MenuTitle->borderWidth) tempMenuHeight += (pSettings->MenuFrame->borderWidth - pSettings->MenuTitle->borderWidth);
1425 }
1426*/
1427 for (i = m_MenuItems.begin(); i != m_MenuItems.end(); i++)
1428 {
1429 (*i)->SetWidth(tempMenuWidth);
1430 (*i)->SetPosition(0, tempMenuHeight);
1431
1432 tempMenuHeight += (*i)->GetHeight();
1433 }
1434/*
1435 if (!pSettings->MenuGrip->parentRelative && ((pSettings->MenuGrip->FontHeight > 0) || (pSettings->MenuGrip->marginWidth > 0)))
1436 {
1437 if (pSettings->MenuFrame->borderWidth > pSettings->MenuGrip->borderWidth) tempMenuHeight -= (pSettings->MenuFrame->borderWidth - pSettings->MenuGrip->borderWidth);
1438 }
1439*/
1440 //====================
1441
1442 SetWindowPos(hMenuWnd, HWND_TOPMOST, 0, 0, tempMenuWidth, tempMenuHeight, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOCOPYBITS|SWP_NOSENDCHANGING);
1443
1444// HRGN menuRegion = CreateRoundRectRgn(0,0,tempMenuWidth+1,tempMenuHeight+1,12,12);
1445// SetWindowRgn(hMenuWnd, menuRegion, true);
1446// DeleteObject(menuRegion);
1447
1448 // Refresh menu gradients cache and repaint the window...
1451 if (cachedMenuActive) DeleteDC(cachedMenuActive);
1453// UpdateMenuWindow();
1454
1455 isValidated = true;
1456}
int m_nRightIndent
Definition MenuCommon.h:111
int m_nLeftIndent
Definition MenuCommon.h:110

◆ ClearSelectionGroup()

void Menu::ClearSelectionGroup ( int group)
1508{
1509 MENUITERATOR i;
1510 for (i = m_MenuItems.begin(); i != m_MenuItems.end(); i++)
1511 {
1512 if ((*i)->m_selectionGroup == group) (*i)->m_isSelected = false;
1513 }
1514}

Friends And Related Symbol Documentation

◆ MenuWindowProc

LRESULT CALLBACK MenuWindowProc ( HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam )
friend
1522{
1523 POINT point;
1524 Menu* p = NULL;
1525 LRESULT ret = 0;
1526
1527 //====================
1528
1529 // Find the menu that should receive the message...
1530 for (unsigned int i=0; i < g_Menues.size(); i++)
1531 {
1532 if (hwnd == g_Menues[i]->GetWindow())
1533 {
1534 p = g_Menues[i];
1535 break;
1536 }
1537 }
1538
1539 // Return DefWindowProc if no matching menu could be found...
1540 if (p == NULL) return DefWindowProc(hwnd, uMsg, wParam, lParam);
1541 // ...or if the receiving menu is not validated...
1542// if (!p->isValidated) return DefWindowProc(hwnd, uMsg, wParam, lParam);
1543
1544 //====================
1545
1546 if (uMsg >= WM_USER) // Nb. this includes messages such as BB_DESKTOPINFO etc
1547 {
1548 LRESULT lResult = 0;
1549
1550 if (p->OnUser((int) uMsg, wParam, lParam, lResult)) return lResult;
1551 }
1552
1553 //====================
1554
1555 switch (uMsg)
1556 {
1557 case WM_NCHITTEST:
1558 {
1559/*
1560 point.x = GET_X_LPARAM(lParam);
1561 point.y = GET_Y_LPARAM(lParam);
1562 ScreenToClient(hwnd, &point);
1563 ret = p->NcHitTest(point.x, point.y);
1564 if (ret == 0) ret = HTCLIENT;
1565*/
1566 if (!p->isValidated) return HTCLIENT;
1567
1568 GetCursorPos(&point);
1569 ScreenToClient(hwnd, &point);
1570 RECT r;
1571 GetClientRect(hwnd, &r);
1572 r.top += pMenuCommon->m_nTitleHeight;
1573 r.bottom -= pMenuCommon->m_nGripHeight;
1574 r.left += pSettings->MenuFrame->borderWidth;
1575 r.right -= pSettings->MenuFrame->borderWidth;
1576
1577 if (!PtInRect(&r, point))
1578 {
1579// if (!p->GetParent() || p->IsPinned()) return HTCAPTION;
1580 return HTCAPTION; // -> PRELIMINARY: Allow dragging away submenus from its parent without prior pinning == subject to change/reversal pending any negative side-effects
1581 }
1582
1583 return HTCLIENT;
1584 }
1585 break;
1586
1587 //====================
1588
1589 case WM_NCMOUSEMOVE:
1590 {
1592 {
1593 point.x = GET_X_LPARAM(lParam);
1594 point.y = GET_Y_LPARAM(lParam);
1595 ScreenToClient(hwnd, &point);
1596 p->Mouse(WM_MOUSEMOVE, point.x, point.y);
1597 }
1598
1599 return 0;
1600 }
1601 break;
1602
1603 //====================
1604
1605 case WM_NCLBUTTONUP:
1606 case WM_NCRBUTTONUP:
1607 case WM_NCMBUTTONUP: // Midclick on title items -> Pin/Unpin menu
1608 case WM_NCLBUTTONDBLCLK: // Doubleclick on title items -> Pin/Unpin menu
1609 {
1610 point.x = GET_X_LPARAM(lParam);
1611 point.y = GET_Y_LPARAM(lParam);
1612 ScreenToClient(hwnd, &point);
1613 p->Mouse(uMsg, point.x, point.y);
1614 return 0;
1615 }
1616 break;
1617/*
1618 case WM_NCLBUTTONDOWN:
1619 case WM_NCRBUTTONDOWN:
1620 case WM_NCMBUTTONDOWN:
1621 {
1622 return DefWindowProc(hwnd, uMsg, wParam, lParam);
1623 }
1624 break;
1625*/
1626 //====================
1627
1628 case WM_MOUSEMOVE:
1629 {
1631 {
1632 // Hack to make keyboard navigation work
1633 // when the mouse is above the window...
1634 static int lastX = 0;
1635 static int lastY = 0;
1636
1637 if (lastX == GET_X_LPARAM(lParam) && lastY == GET_Y_LPARAM(lParam))
1638 return 0;
1639
1640 lastX = GET_X_LPARAM(lParam);
1641 lastY = GET_Y_LPARAM(lParam);
1642
1643 p->Mouse(uMsg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
1644 }
1645
1646 return 0;
1647 }
1648 break;
1649
1650 //====================
1651
1652 case WM_LBUTTONUP:
1653 case WM_RBUTTONUP:
1654 case WM_MBUTTONUP:
1655 case WM_LBUTTONDOWN:
1656 case WM_RBUTTONDOWN:
1657 case WM_MBUTTONDOWN:
1658 case WM_LBUTTONDBLCLK:
1659 {
1660 p->Mouse(uMsg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
1661 return 0;
1662 }
1663 break;
1664
1665 //====================
1666
1667 case WM_EXITSIZEMOVE:
1668 {
1669 RECT r;
1670 GetWindowRect(p->GetWindow(), &r);
1671 p->menuX = r.left;
1672 p->menuY = r.top;
1673 return 0;
1674 }
1675 break;
1676
1677 //====================
1678
1679 case WM_MOUSEWHEEL:
1680 {
1681 if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) p->Mouse(uMsg, 0, 0);
1682 else p->Mouse(uMsg, 1, 0);
1683 return 0;
1684 }
1685 break;
1686
1687 // case WM_MOUSEHWHEEL: { } break;
1688
1689 //====================
1690
1691 case WM_KEYDOWN: // -> Allow keyboard navigation when the menu is the foreground window...
1692 {
1694 KillTimer(p->GetWindow(), MENU_TRACK_MOUSE_TIMER);
1695
1696 switch(wParam)
1697 {
1698 case VK_DOWN: // Move to the next menu item
1699 case VK_UP: // Move to the previous menu item
1700 case VK_RIGHT: // Enter submenu (if the menu item is a folder item)
1701 case VK_LEFT: // Return from submenu (moving back to the parent menu)
1702 case VK_HOME: // Jump to the first menu item
1703 case VK_END: // Jump to the last menu item
1704 case VK_SPACE: // Simulate a *right* click on command, boolean or string editing items, keeping the menu open.
1705 case VK_RETURN: // Simulate a *left* click on command items, closing the menu.
1706 case VK_PRIOR: // (PageUp) Increase the value of integer editing menu items
1707 case VK_ADD: // (NumPad Add) ...
1708 case VK_NEXT: // (PageDown) Decrease the value of integer editing menu items
1709 case VK_SUBTRACT: // (NumPad Subtract) ...
1710 {
1711 MENUITERATOR i1, i2;
1712 Menu* m = NULL;
1713
1714 if (wParam == VK_HOME) // -> Jump to the first menu item!
1715 {
1718
1719 int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
1720 int screenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
1721 if (p->menuHeight > screenHeight) p->menuY = screenY; // -> Scroll to the top if the menu is taller than the screen...
1722
1723 i1 = p->m_MenuItems.begin() + 2; // -> Skip MENUITEM_HEADER (i.e. menu title item) and first MENUITEM_MARGINPAD (i.e. padding in between the menu title and frame)
1724 (*i1)->Active(true);
1725
1726 if ((*i1)->itemType != MENUITEM_FOLDER) PlaySoundFX(SFX_MENU_NAVIGATE);
1727 }
1728 else if (wParam == VK_END) // -> Jump to the last menu item!
1729 {
1732
1733 int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
1734 if (p->menuHeight > screenHeight) p->menuY = screenHeight - p->menuHeight; // -> Scroll to the bottom if the menu is taller than the screen...
1735
1736 i1 = p->m_MenuItems.end() - 3; // -> Skip MENUITEM_FOOTER (i.e. menu grip or non-visible footer item) and last MENUITEM_MARGINPAD (i.e. padding in between the menu frame and footer/grip)
1737 (*i1)->Active(true);
1738
1739 if ((*i1)->itemType != MENUITEM_FOLDER) PlaySoundFX(SFX_MENU_NAVIGATE);
1740 }
1741 else
1742 {
1743 bool activeFound = false;
1744 for (i1 = p->m_MenuItems.begin(); i1 != p->m_MenuItems.end(); i1++)
1745 {
1746 if ((*i1)->IsActive())
1747 {
1748 m = (*i1)->m_pParent;
1749 activeFound = true;
1750 break;
1751 }
1752 }
1753
1754 if (!activeFound)
1755 {
1756 i1 = p->m_MenuItems.begin();
1757 i1++; // Skip MENUITEM_HEADER (i.e. menu title item)
1758 i1++; // Skip first MENUITEM_MARGINPAD (i.e. padding in between the menu title and frame)
1759 (*i1)->Active(true);
1760 }
1761 else
1762 {
1763 i2 = i1;
1764
1765 if (wParam == VK_DOWN)
1766 {
1767 while (i2 < p->m_MenuItems.end()-2)
1768 {
1769 i2++;
1770 if ((*i2)->m_pParent == m)
1771 {
1772 if ((*i2)->itemType != MENUITEM_SEPARATOR && (*i2)->itemType != MENUITEM_MARGINPAD && (*i2)->itemType != MENUITEM_FOOTER)
1773 {
1774 (*i1)->Active(false);
1776
1777 // Allow menu scrolling if the menu is taller than the screen...
1778 int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
1779 if (p->menuHeight > screenHeight)
1780 {
1782 if ((p->menuY + p->menuHeight) < screenHeight) p->menuY = screenHeight - p->menuHeight;
1783 }
1784
1785 (*i2)->Active(true);
1786
1787 if ((*i2)->itemType != MENUITEM_FOLDER) PlaySoundFX(SFX_MENU_NAVIGATE);
1788 break;
1789 }
1790 }
1791 }
1792 }
1793 else if (wParam == VK_UP)
1794 {
1795 while (i2 > p->m_MenuItems.begin()+2)
1796 {
1797 i2--;
1798 if ((*i2)->m_pParent == m)
1799 {
1800 if ((*i2)->itemType != MENUITEM_SEPARATOR && (*i2)->itemType != MENUITEM_MARGINPAD && (*i2)->itemType != MENUITEM_HEADER)
1801 {
1802 (*i1)->Active(false);
1804
1805 // Allow menu scrolling if the menu is taller than the screen...
1806 int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
1807 if (p->menuHeight > screenHeight)
1808 {
1810 int screenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
1811 if (p->menuY > screenY) p->menuY = screenY;
1812 }
1813
1814 (*i2)->Active(true);
1815
1816 if ((*i2)->itemType != MENUITEM_FOLDER) PlaySoundFX(SFX_MENU_NAVIGATE);
1817 break;
1818 }
1819 }
1820 }
1821 }
1822 else if (wParam == VK_RIGHT)
1823 {
1824 if ((*i1)->itemType == MENUITEM_FOLDER)
1825 {
1826 FolderItem* item = (FolderItem*)*i1;
1827 item->ShowSubMenu();
1828 SetForegroundWindow((*i1)->m_pSubMenu->GetWindow());
1829 SendMessage((*i1)->m_pSubMenu->GetWindow(), WM_KEYDOWN, VK_HOME, NULL);
1830 return 0;
1831 }
1832 }
1833 else if (wParam == VK_LEFT)
1834 {
1835 if ((*i1)->m_pParent->GetParent() != NULL)
1836 {
1837 (*i1)->Active(false);
1838 (*i1)->m_pParent->Hide(HIDE_THIS);
1840 Menu* parentMenu = (*i1)->m_pParent->GetParent();
1841 SetForegroundWindow(parentMenu->GetWindow());
1843 }
1844 }
1845 else if (wParam == VK_SPACE)
1846 {
1847 if (((*i1)->itemType == MENUITEM_COMMAND) || ((*i1)->itemType == MENUITEM_BOOLEAN) || ((*i1)->itemType == MENUITEM_EDITSTRING)) (*i1)->Invoke(2); // -> Simulating a *right* click on command, boolean or string editing items, keeping the menu open...
1848 return 0;
1849 }
1850 else if (wParam == VK_RETURN)
1851 {
1852 if (((*i1)->itemType == MENUITEM_COMMAND)) (*i1)->Invoke(1); // -> Simulating a *left* click on command items, closing the menu.
1853 return 0;
1854 }
1855 else if ((wParam == VK_PRIOR) || (wParam == VK_ADD))
1856 {
1857 if ((*i1)->itemType == MENUITEM_EDITINT)
1858 {
1859 POINT pt;
1860 pt.x = (*i1)->m_nLeft + (*i1)->m_nWidth - 1; // Simulating a mouse click on the right hand side of the menu item -> Increase value!
1861 pt.y = (*i1)->m_nTop;
1862 (*i1)->Mouse(WM_LBUTTONUP, pt);
1863 return 0;
1864 }
1865 }
1866 else if ((wParam == VK_NEXT) || (wParam == VK_SUBTRACT))
1867 {
1868 if ((*i1)->itemType == MENUITEM_EDITINT)
1869 {
1870 POINT pt;
1871 pt.x = (*i1)->m_nLeft + 1; // Simulating a mouse click on the left hand side of the menu item -> Decrease value!
1872 pt.y = (*i1)->m_nTop;
1873 (*i1)->Mouse(WM_LBUTTONUP, pt);
1874 return 0;
1875 }
1876 }
1877 }
1878 }
1879
1880// p->UpdateMenuWindow();
1881 return 0;
1882 }
1883 break;
1884
1885 case VK_INSERT: // Toggle menu pinned
1886 {
1887// if (!p->isPinned) p->isPinned = true;
1888// else p->isPinned = false;
1889// p->UpdateMenuWindow();
1890 p->TogglePinned();
1891 return 0;
1892 }
1893 break;
1894
1895 case VK_ESCAPE: // Close the menu
1896 case VK_DELETE:
1897 {
1900 return 0;
1901 }
1902 break;
1903
1904 default: { return 0; }
1905 }
1906 }
1907 break;
1908
1909 //====================
1910
1911 case WM_CHAR: // -> Allow keyboard search on the *first* character of menu item titles when the menu is the foreground window...
1912 {
1914 KillTimer(p->GetWindow(), MENU_TRACK_MOUSE_TIMER);
1915
1916 char typeAhead = tolower((char)wParam); // If applicable, use the lowercase version of the character...
1917
1918 MENUITERATOR i;
1919 bool activeFound = false, searchFound = false;
1920
1921 for (i = p->m_MenuItems.begin()+2; i != p->m_MenuItems.end()-2; i++) // Skip MENUITEM_HEADER/MARGINPAD/FOOTER items...
1922 {
1923 if (!activeFound)
1924 {
1925 // Skip up to the currently active menu item... (i.e. accept any *following* match)
1926 if ((*i)->IsActive()) activeFound = true;
1927 continue;
1928 }
1929
1930 if (((tolower((*i)->m_pszTitleANSI[0]) == typeAhead)))
1931 {
1932 searchFound = true;
1933 pMenuCommon->ScrollToItem(p, (*i));
1934 break;
1935 }
1936 }
1937
1938 if (!searchFound)
1939 {
1940 for (i = p->m_MenuItems.begin()+2; i != p->m_MenuItems.end()-2; i++) // Skip MENUITEM_HEADER/MARGINPAD/FOOTER items...
1941 {
1942 if (((tolower((*i)->m_pszTitleANSI[0]) == typeAhead))) // Accept *any* match...
1943 {
1944 pMenuCommon->ScrollToItem(p, (*i));
1945 break;
1946 }
1947 }
1948 }
1949
1950 return 0;
1951 }
1952
1953 //====================
1954
1955 case WM_CLOSE:
1956 return 0;
1957
1958 //====================
1959
1960 case WM_ACTIVATE:
1961 {
1962 p->Activate(LOWORD(wParam), (HWND)lParam);
1963 }
1964 break;
1965
1966 //====================
1967
1968 case WM_TIMER:
1969 {
1970 p->Timer(wParam);
1971 return 0;
1972 }
1973 break;
1974
1975 //====================
1976
1977 case WM_MOVING:
1978 {
1979 p->Moving();
1980 }
1981 break;
1982
1983 //====================
1984/*
1985 case WM_WINDOWPOSCHANGING:
1986 {
1987 if (IsWindowVisible(hwnd)) SnapWindowToEdge((WINDOWPOS*)lParam, pSettings->edgeSnapThreshold, true);
1988 }
1989 break;
1990*/
1991 //====================
1992/*
1993 case WM_ERASEBKGND:
1994 return true;
1995*/
1996 //====================
1997
1998 case WM_COMMAND:
1999 {
2001 {
2002// char msg[300];
2003// if (HIWORD(wParam) == EN_CHANGE) sprintf(msg, "Menu -> WM_COMMAND -> EN_CHANGE received...");
2004// else if (HIWORD(wParam) == EN_UPDATE) sprintf(msg, "Menu -> WM_COMMAND -> EN_UPDATE received...");
2005// else sprintf(msg, "Menu -> WM_COMMAND -> Unknown message received... -> 0x%x", (int)wParam);
2006// SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
2007 return 0;
2008 }
2009 else p->Command(wParam, lParam);
2010 }
2011 break;
2012
2013 //====================
2014
2015 case WM_MOUSELEAVE:
2016 {
2017 p->MouseLeave();
2018 }
2019 break;
2020
2021 //====================
2022/*
2023 case WM_DROPFILES:
2024 {
2025 static TCHAR source[MAX_LINE_LENGTH];
2026 DragQueryFile((HDROP)wParam, 0, source, sizeof(source));
2027 DragFinish((HDROP)wParam);
2028
2029 RECT r;
2030 MENUITERATOR item;
2031 for (item = p->m_MenuItems.begin(); item != p->m_MenuItems.end() && !p->m_MenuItems.empty(); item++)
2032 {
2033 POINT mousepos;
2034 GetCursorPos(&mousepos);
2035 ScreenToClient(hwnd, &mousepos);
2036 (*item)->GetItemRect(&r);
2037
2038 if (PtInRect(&r, mousepos) && (*item)->itemType == MENUITEM_COMMAND)
2039 {
2040 if (!strlen((*item)->m_pszArgument)) break;
2041
2042 char destination[MAX_PATH];
2043 strcpy(destination, (*item)->m_pszArgument);
2044 if (destination[0] == '\"') StrRemoveEncap(destination);
2045 if (destination[1] == ':')
2046 {
2047 if (source[0] == '\"') StrRemoveEncap(source);
2048 char tempSource[MAX_PATH];
2049 strcpy(tempSource, source);
2050 int n = GetParentFolder(tempSource);
2051
2052 GetParentFolder(destination);
2053 strcat(destination, &source[n]);
2054
2055 // Move file from the source folder to the destination folder...
2056 MoveFile(source, destination);
2057
2058 // Look for a line that should "always" exist in a style file; if it
2059 // does we create a [style] menu item, otherwise an [exec] menu item...
2060 char cmd[8];
2061 if (strlen(ReadString(destination, "menu.frame", ""))) strcpy(cmd, "[style]");
2062 else strcpy(cmd, "[exec]");
2063
2064 // Create a new menu item for the moved file in the destination menu...
2065 // (note that this new menu item gets added *after* the bottom items,
2066 // so we need to sort the menu items afterwards)...
2067 pMenuCommon->CreateMenuItem(p, MENUITEM_COMMAND, cmd, destination, &source[n], false);
2068 p->Sort(2,0); // Skip the header item and top marginWidth padding item...
2069
2070 // Recalculate menu dimensions and redraw window...
2071 p->Invalidate();
2072 p->Validate();
2073 }
2074 break;
2075 }
2076 }
2077
2078 return 0;
2079 }
2080 break;
2081*/
2082 //====================
2083
2084 case BB_RECONFIGURE:
2085 case BB_REDRAWGUI:
2086 {
2087 if ((uMsg == BB_REDRAWGUI) && !(wParam & BBRG_MENU)) break;
2088
2089 // Block access to the menu...
2090 p->Invalidate();
2091
2092 // Set new menu item dimensions based on values calculated in MenuCommon...
2093 MENUITERATOR m;
2094 for (m = p->m_MenuItems.begin(); m != p->m_MenuItems.end(); m++)
2095 {
2096 if ((*m)->itemType == MENUITEM_HEADER) (*m)->SetHeight(pMenuCommon->m_nTitleHeight);
2097 else if ((*m)->itemType == MENUITEM_SEPARATOR) (*m)->SetHeight(pMenuCommon->m_nSeparatorHeight);
2098 else if ((*m)->itemType == MENUITEM_MARGINPAD) (*m)->SetHeight(pMenuCommon->m_nMarginHeight);
2099 else if ((*m)->itemType == MENUITEM_FOOTER) (*m)->SetHeight(pMenuCommon->m_nGripHeight);
2100 else (*m)->SetHeight(pMenuCommon->m_nSubmenuHeight);
2101 }
2102
2103 // Recalculate the menu dimensions...
2104 p->Validate();
2105 // ...and update the menu window if its currently visible...
2106 if (IsWindowVisible(p->hMenuWnd)) p->UpdateMenuWindow();
2107 }
2108 break;
2109
2110 //====================
2111
2112 case BB_MENU:
2113 {
2114 Menu* pMenu = NULL;
2115
2116 if (wParam == 0) // Main menu
2117 {
2118 WIN32_FIND_DATA oldData = p->data;
2119 HANDLE hFind = FindFirstFile(pSettings->menuFile, &p->data);
2120 FindClose(hFind);
2121 if (CompareFileTime(&p->data.ftLastWriteTime, &oldData.ftLastWriteTime) == 1)
2122 {
2123 pMenuCommon->Hide();
2125 }
2126
2128 }
2129 else if (wParam == 1) // Workspaces menu
2130 {
2132 }
2133 else if (wParam == 2 || wParam == 3 || wParam == 4) // Configuration menu (nb. previously used for the legacy Toolbar/Systembar/Dock menus, now replaced with the common Configuration menu)
2134 {
2136 }
2137 else if (wParam == 5) // Styles menu
2138 {
2140 }
2141 else if (wParam == 6) // Themes menu
2142 {
2144 }
2145
2146 if (pMenu != NULL)
2147 {
2148 pMenuCommon->Hide();
2149 pMenu->Show();
2150 }
2151 }
2152 break;
2153
2154 //====================
2155
2156 case BB_HIDEMENU:
2157 {
2158 pMenuCommon->Hide();
2159// p->Hide(HIDE_PARENTS);
2160// p->Hide(HIDE_CHILDREN);
2161 }
2162 break;
2163
2164 //====================
2165
2166 case WM_CTLCOLOREDIT: // -> Used by StringItem editor popup dialog windows
2167 {
2168 // SetTextColor((HDC)wParam, pSettings->MenuFrame->TextColor);
2169 // SetBkColor((HDC)wParam, pSettings->MenuFrame->Color);
2170 SetTextColor((HDC)wParam, 0x000000);
2171 SetBkColor((HDC)wParam, 0xffffff);
2172 return (LRESULT)GetStockObject(NULL_BRUSH);
2173 }
2174 break;
2175
2176 //====================
2177
2178 default:
2179 {
2180 ret = DefWindowProc(hwnd, uMsg, wParam, lParam);
2181 }
2182
2183 //====================
2184 }
2185
2186 return ret;
2187}
Menu * pMenu
Definition Blackbox.cpp:40
#define BB_HIDEMENU
Definition BBApi.h:161
#define BB_REDRAWGUI
Definition BBApi.h:220
#define BB_MENU
Definition BBApi.h:160
#define BB_RECONFIGURE
Definition BBApi.h:147
#define BBRG_MENU
Definition BBApi.h:222
#define GET_Y_LPARAM(lp)
Definition Menu.h:60
#define HIDE_THIS
Definition Menu.h:40
#define GET_X_LPARAM(lp)
Definition Menu.h:56
#define MENUITEM_EDITINT
Definition MenuItem.h:44
#define MENUITEM_COMMAND
Definition MenuItem.h:42
#define MENUITEM_BOOLEAN
Definition MenuItem.h:45
void PlaySoundFX(int sound)
Definition Sounds.cpp:40
@ SFX_MENU_NAVIGATE
Definition Sounds.h:43
void ShowSubMenu()
Definition FolderItem.cpp:119
void UpdateMainMenu(bool createAllMenus)
Definition MenuCommon.cpp:451
Menu * m_pMainMenu
Definition MenuCommon.h:117
Menu * m_pConfigMenu
Definition MenuCommon.h:121
Menu * m_pWorkspacesMenu
Definition MenuCommon.h:120
void ScrollToItem(Menu *m, MenuItem *item)
Definition MenuCommon.cpp:2504
int m_nMarginHeight
Definition MenuCommon.h:105
int m_nSeparatorHeight
Definition MenuCommon.h:106
virtual bool OnUser(int nMessage, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
Definition Menu.cpp:1268
void Activate(int fActive, HWND hWnd)
Definition Menu.cpp:1114
void MouseLeave()
Definition Menu.cpp:1040
void Mouse(UINT nMsg, int x, int y)
Definition Menu.cpp:897
void Timer(int nTimer)
Definition Menu.cpp:1134
LRESULT Command(WPARAM wParam, LPARAM lParam)
Definition Menu.cpp:1285
void TogglePinned()
Definition Menu.cpp:1463
void Moving()
Definition Menu.cpp:1247
char menuFile[MAX_LINE_LENGTH]
Definition Settings.h:174

Member Data Documentation

◆ hMenuInstance

HINSTANCE Menu::hMenuInstance

◆ m_nInstances

int Menu::m_nInstances = 0
static

◆ data

WIN32_FIND_DATA Menu::data

◆ hMenuWnd

HWND Menu::hMenuWnd

◆ m_pParent

Menu* Menu::m_pParent

◆ m_MenuItems

vector<MenuItem*> Menu::m_MenuItems

◆ m_Children

vector<Menu*> Menu::m_Children

◆ m_pszTitle

char* Menu::m_pszTitle

◆ isValidated

bool Menu::isValidated

◆ isPinned

bool Menu::isPinned

◆ mouseIsHovering

bool Menu::mouseIsHovering

◆ keyboardNavigationInProgress

bool Menu::keyboardNavigationInProgress

◆ m_bMoved

bool Menu::m_bMoved

◆ m_pszFolderPath

char* Menu::m_pszFolderPath

◆ menuHDC

HDC Menu::menuHDC

◆ cachedMenuBackground

HDC Menu::cachedMenuBackground

◆ cachedMenuActive

HDC Menu::cachedMenuActive

◆ cachedMenuGradientsExist

bool Menu::cachedMenuGradientsExist

◆ menuRect

RECT Menu::menuRect

◆ menuTitleRect

RECT Menu::menuTitleRect

◆ menuFrameRect

RECT Menu::menuFrameRect

◆ menuActiveRect

RECT Menu::menuActiveRect

◆ menuGripRect

RECT Menu::menuGripRect

◆ menuX

int Menu::menuX

◆ menuY

int Menu::menuY

◆ menuWidth

int Menu::menuWidth

◆ menuHeight

int Menu::menuHeight

◆ menuActiveWidth

int Menu::menuActiveWidth

◆ menuActiveHeight

int Menu::menuActiveHeight