forked from coddec/Classic-Shell
- Notifications
You must be signed in to change notification settings - Fork 452
/
Copy pathMenuContainer.h
1143 lines (1036 loc) · 44.1 KB
/
MenuContainer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Classic Shell (c) 2009-2017, Ivo Beltchev
// Open-Shell (c) 2017-2018, The Open-Shell Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include"SkinManager.h"
#include"JumpLists.h"
#include"ItemManager.h"
#include"SearchManager.h"
#include"DragDrop.h"
#include"TouchHelper.h"
#include<vector>
#include<map>
#include<ctxtcall.h>
//#define PREVENT_CLOSING // define this to prevent the menu from closing when it is deactivated (useful for debugging)
//#define REPEAT_ITEMS 10 // define this to repeat each menu item (useful to simulate large menus)
//#define REPEAT_JUMPLIST_ITEMS 2 // define this to repeat jumplist items (useful to simulate large menus)
#ifdef BUILD_SETUP
#undef PREVENT_CLOSING // make sure it is defined in Setup
#undef REPEAT_ITEMS
#undef REPEAT_JUMPLIST_ITEMS
#endif
enum TRecentPrograms;
enum TMenuID
{
MENU_NO=0,
MENU_LAST=0,
MENU_SEPARATOR,
MENU_EMPTY,
MENU_EMPTY_TOP,
MENU_RECENT,
MENU_JUMPITEM,
MENU_COLUMN_PADDING,
MENU_COLUMN_BREAK,
MENU_PROGRAMS_TREE,
// standard menu items
MENU_PROGRAMS,
MENU_APPS,
MENU_COMPUTER,
MENU_FAVORITES,
MENU_DOCUMENTS,
MENU_USERFILES,
MENU_USERDOCUMENTS,
MENU_USERPICTURES,
MENU_SETTINGS,
MENU_CONTROLPANEL,
MENU_PCSETTINGS,
MENU_NETWORK,
MENU_SECURITY,
MENU_PRINTERS,
MENU_TASKBAR,
MENU_FEATURES,
MENU_CLASSIC_SETTINGS,
MENU_SEARCH,
MENU_SEARCH_FILES,
MENU_SEARCH_PRINTER,
MENU_SEARCH_COMPUTERS,
MENU_SEARCH_PEOPLE,
MENU_HELP,
MENU_RUN,
MENU_LOGOFF,
MENU_DISCONNECT,
MENU_UNDOCK,
MENU_MONITOROFF,
MENU_SHUTDOWN_BOX,
MENU_SHUTDOWN_BUTTON,
// additional commands
MENU_CUSTOM, // used for any custom item
MENU_SLEEP,
MENU_HIBERNATE,
MENU_RESTART,
MENU_SHUTDOWN,
MENU_SWITCHUSER,
MENU_LOCK,
MENU_RECENT_PROGRAMS,
MENU_SEARCH_BOX,
MENU_SEARCH_CATEGORY,
MENU_SEARCH_EXECUTE,
MENU_SEARCH_EMPTY,
MENU_MORE_RESULTS,
MENU_SEARCH_INTERNET,
MENU_SEARCH_PROVIDER,
// internal commands
MENU_SEARCH_FILES_CUSTOM,
MENU_LOGOFF_CONFIRM,
MENU_RESTART_ADVANCED,
MENU_RESTART_UPDATE,
MENU_SHUTDOWN_UPDATE,
MENU_RESTART_NOUPDATE,
MENU_SHUTDOWN_NOUPDATE,
MENU_SHUTDOWN_HYBRID,
MENU_IGNORE=1024, // ignore this item
};
structStdMenuItem
{
constwchar_t *command;
TMenuID id;
const KNOWNFOLDERID *folder1; // NULL if not used
const KNOWNFOLDERID *folder2; // NULL if not used
constwchar_t *label; // localization key
constwchar_t *tip; // default tooltip
constwchar_t *iconPath;
constwchar_t *link;
unsignedint settings;
const StdMenuItem *submenu;
CString labelString, tipString; // additional storage for the strings
// user settings
enum
{
MENU_OPENUP = 0x000001, // prefer to open up
MENU_OPENUP_REC = 0x000002, // children prefer to open up
MENU_SORTZA = 0x000004, // sort backwards
MENU_SORTZA_REC = 0x000008, // children sort backwards
MENU_SORTONCE = 0x000010, // save the sort order the first time the menu is opened
MENU_ITEMS_FIRST = 0x000020, // place the custom items before the folder items
MENU_TRACK = 0x000040, // track shortcuts from this menu
MENU_NOTRACK = 0x000080, // don't track shortcuts from this menu
MENU_NOEXPAND = 0x000100, // don't expand this link item
MENU_SINGLE_EXPAND = 0x000200, // expand only one level
MENU_MULTICOLUMN = 0x000400, // make this item a multi-column item
MENU_NOEXTENSIONS = 0x000800, // hide extensions
MENU_INLINE = 0x001000, // inline sub-items in the parent menu
MENU_SPLIT_BUTTON = 0x002000, // the item is drawn as a split button
MENU_ITEM_DISABLED = 0x004000, // the item is disabled
MENU_NORECENT = 0x008000, // don't show recent items in the root menu (because a sub-menu uses MENU_RECENT_ITEMS)
// style
MENU_STYLE_CLASSIC1 = 0x100000,
MENU_STYLE_CLASSIC2 = 0x200000,
MENU_STYLE_MASK = MENU_STYLE_CLASSIC1|MENU_STYLE_CLASSIC2,
};
};
structSpecialFolder
{
const KNOWNFOLDERID *folder;
unsignedint settings;
wchar_t PATH[_MAX_PATH];
enum
{
FOLDER_NOSUBFOLDERS=1, // don't show the subfolders of this folder
FOLDER_NONEWFOLDER=2, // don't show the "New Folder" command
FOLDER_NODROP=4, // don't allow reordering, don't show "Sort" and "Auto Arrange" (also implies FOLDER_NONEWFOLDER)
FOLDER_NOPATH=8, // don't trust the child parsing names
};
};
extern SpecialFolder g_SpecialFolders[];
voidInitializeSpecialFolders( void );
classCMenuAccessible;
classCProgramsTree;
classCMenuContainer;
#ifndef __IFrameworkInputPane_INTERFACE_DEFINED__
MIDL_INTERFACE("226C537B-1E76-4D9E-A760-33DB29922F18")
IFrameworkInputPaneHandler : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE Showing( RECT *prcInputPaneScreenLocation, BOOL fEnsureFocusedElementInView ) = 0;
virtual HRESULT STDMETHODCALLTYPE Hiding( BOOL fEnsureFocusedElementInView ) = 0;
};
MIDL_INTERFACE("5752238B-24F0-495A-82F1-2FD593056796")
IFrameworkInputPane: public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE Advise( IUnknown *pWindow, IFrameworkInputPaneHandler *pHandler, DWORD *pdwCookie ) = 0;
virtual HRESULT STDMETHODCALLTYPE AdviseWithHWND( HWND hwnd, IFrameworkInputPaneHandler *pHandler, DWORD *pdwCookie ) = 0;
virtual HRESULT STDMETHODCALLTYPE Unadvise( DWORD dwCookie ) = 0;
virtual HRESULT STDMETHODCALLTYPE Location( RECT *prcInputPaneScreenLocation ) = 0;
};
#endif
// CUserWindow - implementation for the user picture window
classCUserWindow: publicCWindowImpl<CUserWindow>
{
public:
CUserWindow( void ) { m_pOwner=NULL; m_Bits=NULL; m_bDefaultImage=true; m_Bitmap=m_UserBitmap=m_TimerBitmap=NULL; m_Timer=0; m_Size.cx=m_Size.cy=0; }
DECLARE_WND_CLASS_EX(L"OpenShell.CUserWindow",0,COLOR_MENU)
// message handlers
BEGIN_MSG_MAP( CUserWindow )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER( WM_MOUSEACTIVATE, OnMouseActivate )
MESSAGE_HANDLER( WM_NCHITTEST, OnNcHitTest )
MESSAGE_HANDLER( WM_LBUTTONDOWN, OnLButtonDown )
MESSAGE_HANDLER( WM_SETCURSOR, OnSetCursor )
MESSAGE_HANDLER( WM_TIMER, OnTimer )
END_MSG_MAP()
voidInit( CMenuContainer *pOwner );
voidUpdate( int alpha=255 );
voidUpdatePartial( POINT pos, const RECT *pClipRect );
voidSetImage( HBITMAP bmp, bool bAnimate );
voidStartImageTimer( HBITMAP bmp );
protected:
LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return MA_NOACTIVATE; }
LRESULT OnNcHitTest( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return HTCLIENT; }
LRESULT OnLButtonDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetCursor( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnEraseBkgnd( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return1; }
LRESULT OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
private:
CMenuContainer *m_pOwner;
std::vector<unsignedint> m_Source;
unsignedint *m_Bits;
bool m_bDefaultImage;
HBITMAP m_UserBitmap;
HBITMAP m_Bitmap;
SIZE m_Size;
int m_Timer;
HBITMAP m_TimerBitmap;
bool m_bUserBitmapMask;
enum
{
TIMER_BLEND=1,
TIMER_SET=2,
};
};
// sound events
enum TMenuSound
{
SOUND_MAIN,
SOUND_POPUP,
SOUND_COMMAND,
SOUND_DROP,
SOUND_BUTTON_HOVER,
};
// CMenuContainer - implementation of a single menu box.
classCMenuContainer: publicIDropTarget, publicIFrameworkInputPaneHandler, publicCWindowImplBaseT<CWindow>
{
public:
virtual ATL::CWndClassInfo &GetWndClassInfo( void )
{
static ATL::CWndClassInfo wc =
{
{sizeof(WNDCLASSEX),CS_DROPSHADOW|CS_DBLCLKS,StartWindowProc,0,0,NULL,NULL,NULL,(HBRUSH)(COLOR_MENU+1),NULL,L"OpenShell.CMenuContainer",NULL},
NULL,NULL,IDC_ARROW,TRUE,0,_T("")
};
return wc;
}
HWND Create( HWND hWndParent, RECT *pRect, DWORD dwStyle, DWORD dwExStyle )
{
ATOM atom=GetWndClassInfo().Register(&m_pfnSuperWindowProc);
return CWindowImplBaseT<CWindow>::Create(hWndParent,pRect,NULL,dwStyle,dwExStyle,0u,atom,NULL);
}
// message handlers
BEGIN_MSG_MAP( CMenuContainer )
// forward all messages to m_pMenu2 and m_pMenu3 to ensure the context menu functions properly
if (m_pMenu3)
{
if (m_pMenu3->HandleMenuMsg2(uMsg,wParam,lParam,&lResult)==S_OK)
returnTRUE;
}
elseif (m_pMenu2)
{
m_pMenu2->HandleMenuMsg(uMsg,wParam,lParam);
}
MESSAGE_HANDLER( WM_CREATE, OnCreate )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER( WM_SHOWWINDOW, OnShowWindow )
MESSAGE_HANDLER( WM_PAINT, OnPaint )
MESSAGE_HANDLER( WM_PRINTCLIENT, OnPaint )
MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBkgnd )
MESSAGE_HANDLER( WM_ACTIVATE, OnActivate )
MESSAGE_HANDLER( WM_MOUSEACTIVATE, OnMouseActivate )
MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
MESSAGE_HANDLER( WM_MOUSEWHEEL, OnMouseWheel )
MESSAGE_HANDLER( WM_LBUTTONDOWN, OnLButtonDown )
MESSAGE_HANDLER( WM_LBUTTONDBLCLK, OnLButtonDblClick )
MESSAGE_HANDLER( WM_LBUTTONUP, OnLButtonUp )
MESSAGE_HANDLER( WM_RBUTTONDOWN, OnRButtonDown )
MESSAGE_HANDLER( WM_RBUTTONUP, OnRButtonUp )
MESSAGE_HANDLER( WM_SETCURSOR, OnSetCursor )
MESSAGE_HANDLER( WM_CONTEXTMENU, OnContextMenu )
MESSAGE_HANDLER( WM_VSCROLL, OnVScroll )
MESSAGE_HANDLER( WM_KEYDOWN, OnKeyDown )
MESSAGE_HANDLER( WM_SYSKEYDOWN, OnSysKeyDown )
MESSAGE_HANDLER( WM_CHAR, OnChar )
MESSAGE_HANDLER( WM_SYSCHAR, OnChar )
MESSAGE_HANDLER( WM_TIMER, OnTimer )
MESSAGE_HANDLER( WM_SYSCOMMAND, OnSysCommand )
MESSAGE_HANDLER( WM_SETTINGCHANGE, OnSettingChange )
MESSAGE_HANDLER( WM_DISPLAYCHANGE, OnDisplayChange )
MESSAGE_HANDLER( WM_GETOBJECT, OnGetAccObject )
MESSAGE_HANDLER( WM_CTLCOLOREDIT, OnColorEdit )
MESSAGE_HANDLER( WM_GESTURE, OnGesture )
MESSAGE_HANDLER( WM_GESTURENOTIFY, OnGestureNotify )
MESSAGE_HANDLER( MCM_REFRESH, OnRefresh )
MESSAGE_HANDLER( MCM_SETCONTEXTITEM, OnSetContextItem )
MESSAGE_HANDLER( MCM_REDRAWEDIT, OnRedrawEdit )
MESSAGE_HANDLER( MCM_REFRESHICONS, OnRefreshIcons )
MESSAGE_HANDLER( MCM_SETHOTITEM, OnSetHotItem )
MESSAGE_HANDLER( MCM_WORKAREACHANGED, OnWorkAreaChanged )
MESSAGE_HANDLER( s_StartMenuMsg, OnStartMenuMsg )
MESSAGE_HANDLER( WM_POINTERDOWN, OnPointerDown )
MESSAGE_HANDLER( WM_POINTERUPDATE, OnPointerUpdate )
MESSAGE_HANDLER( WM_POINTERUP, OnPointerUp )
COMMAND_CODE_HANDLER( EN_CHANGE, OnEditChange )
REFLECT_NOTIFICATIONS()
END_MSG_MAP()
staticboolCloseStartMenu( void );
staticboolIsMenuOpened( void ) { return !s_Menus.empty(); }
staticboolHasInputHandler( void ) { return s_pFrameworkInputPane!=NULL; }
staticboolCanShowMenu( void ) { return s_Menus.empty() || !s_bPreventClosing; }
staticboolIsMenuWindow( HWND hWnd );
staticboolIgnoreTaskbarTimers( void ) { return !s_Menus.empty() && (s_TaskbarState&ABS_AUTOHIDE); }
static HWND ToggleStartMenu( int taskbarId, bool bKeyboard, bool bAllPrograms );
staticboolProcessMouseMessage( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
staticvoidRefreshIcons( void );
staticvoidRefreshSearch( void );
staticvoidPlayMenuSound( TMenuSound sound );
protected:
// IUnknown
virtual STDMETHODIMP QueryInterface( REFIID riid, void **ppvObject );
virtual ULONG STDMETHODCALLTYPE AddRef( void )
{
returnInterlockedIncrement(&m_RefCount);
}
virtual ULONG STDMETHODCALLTYPE Release( void )
{
long nTemp=InterlockedDecrement(&m_RefCount);
if (!nTemp) deletethis;
return nTemp;
}
// IDropTarget
virtual HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragLeave( void );
virtual HRESULT STDMETHODCALLTYPE Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
// IFrameworkInputPaneHandler
virtual HRESULT STDMETHODCALLTYPE Showing( RECT *prcInputPaneScreenLocation, BOOL fEnsureFocusedElementInView );
virtual HRESULT STDMETHODCALLTYPE Hiding( BOOL fEnsureFocusedElementInView );
LRESULT OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnShowWindow( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnRefresh( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnEraseBkgnd( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return1; }
LRESULT OnActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseMove( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseLeave( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseWheel( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnLButtonDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnLButtonDblClick( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnLButtonUp( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnRButtonDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnRButtonUp( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetCursor( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnContextMenu( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnVScroll( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSysKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnChar( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSysCommand( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSettingChange( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnDisplayChange( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnWorkAreaChanged( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnGetAccObject( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetContextItem( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnColorEdit( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnGesture( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnGestureNotify( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnPointerDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnPointerUpdate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnPointerUp( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnRedrawEdit( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnRefreshIcons( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetHotItem( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnStartMenuMsg( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnEditChange( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled );
virtualvoidOnFinalMessage( HWND ) { Release(); }
protected:
CMenuContainer( CMenuContainer *pParent, int index, int options, const StdMenuItem *pStdItem, PIDLIST_ABSOLUTE path1, PIDLIST_ABSOLUTE path2 );
~CMenuContainer( void );
private:
// options when creating a container
enum
{
CONTAINER_MULTICOLUMN = 0x0000001, // use multiple columns instead of a single scrolling column
CONTAINER_MULTICOL_REC = 0x0000002, // the children will be multi-column
CONTAINER_CONTROLPANEL = 0x0000004, // this is the control panel, don't go into subfolders
CONTAINER_PROGRAMS = 0x0000008, // this is a folder from the Start Menu hierarchy (drop operations prefer link over move)
CONTAINER_DOCUMENTS = 0x0000010, // sort by time, limit the count (for recent documents)
CONTAINER_ALLPROGRAMS = 0x0000020, // this is the main menu of All Programs (combines the Start Menu and Programs folders)
CONTAINER_RECENT = 0x0000040, // insert recent programs (sorted by time)
CONTAINER_LINK = 0x0000080, // this is an expanded link to a folder (always scrolling)
CONTAINER_ITEMS_FIRST = 0x0000100, // put standard items at the top
CONTAINER_DRAG = 0x0000200, // allow items to be dragged out
CONTAINER_DROP = 0x0000400, // allow dropping of items
CONTAINER_LEFT = 0x0000800, // the window is aligned on the left
CONTAINER_TOP = 0x0001000, // the window is aligned on the top
CONTAINER_AUTOSORT = 0x0002000, // the menu is always in alphabetical order
CONTAINER_OPENUP_REC = 0x0004000, // the container's children will prefer to open up instead of down
CONTAINER_SORTZA = 0x0008000, // the container will sort backwards by default
CONTAINER_SORTZA_REC = 0x0010000, // the container's children will sort backwards by default
CONTAINER_SORTONCE = 0x0020000, // the container will save the sort order the first time the menu is opened
CONTAINER_TRACK = 0x0040000, // track shortcuts from this menu
CONTAINER_NOSUBFOLDERS = 0x0080000, // don't go into subfolders
CONTAINER_NONEWFOLDER = 0x0100000, // don't show the "New Folder" command
CONTAINER_NOPATH = 0x0200000, // don't trust the child parsing names
CONTAINER_SEARCH = 0x0400000, // this is he search results submenu
CONTAINER_NOEXTENSIONS = 0x0800000, // hide extensions
CONTAINER_JUMPLIST = 0x1000000, // this is a jumplist menu
CONTAINER_APPS = 0x2000000, // this is the folder for Metro apps
};
// description of a menu item
structMenuItem
{
MenuItem( TMenuID _id=MENU_NO )
{
id=_id;
pStdItem=NULL;
nameHash=0;
pItemInfo=NULL;
drawType=MenuSkin::COLUMN1_ITEM;
column=row=0;
memset(&itemRect,0,sizeof(itemRect));
bFolder=bLink=bPrograms=bAlignBottom=bBreak=bInline=bInlineFirst=bInlineLast=bSplit=bHasJumpList=bMetroLink=bMetroApp=bBlankSeparator=bNew=bStartScreen=bCustomAccelerator=false;
priority=0;
pItem1=pItem2=NULL;
mfuHash=0;
categoryHash=0;
jumpIndex=-1;
accelerator=0;
drive=0;
textStart=textEnd=0;
mruOrder=-1;
nameOffset=0;
}
TMenuID id; // if pStdItem!=NULL, this is pStdItem->id. otherwise it can only be MENU_NO, MENU_SEPARATOR, MENU_EMPTY or MENU_EMPTY_TOP
const StdMenuItem *pStdItem; // NULL if not a standard menu item
CString name;
unsignedint nameHash;
const CItemManager::ItemInfo *pItemInfo;
MenuSkin::TItemDrawType drawType;
int column;
int row;
RECT itemRect;
bool bFolder:1; // this is a folder - draw arrow
bool bLink:1; // this is a link (if a link to a folder is expanded it is always single-column)
bool bPrograms:1; // this item is part of the Start Menu folder hierarchy
bool bAlignBottom:1; // two-column menu: this item is aligned to the bottom
bool bBreak:1; // two-column menu: this item starts the second column
bool bInline:1; // this item is inlined in the parent menu
bool bInlineFirst:1; // this item is the first from the inlined group
bool bInlineLast:1; // this item is the last from the inlined group
bool bSplit:1; // split button item
bool bHasJumpList:1; // this item has a jump list
bool bMetroLink:1; // this is a Windows 8 Metro shortcut
bool bMetroApp:1; // this is a Windows 10 Metro app item
bool bBlankSeparator:1; // this is a blank separator that is the same size as normal items
bool bNew:1; // this is a highlighted new item
bool bStartScreen:1; // this is the start screen shortcut item
bool bCustomAccelerator:1; // the accelerator is specified explicitly
char priority; // used for sorting of the All Programs menu (0 for Start Menu, 1 for the separator, 2 for the Programs)
char drive;
wchar_t accelerator; // accelerator character, 0 if none
// pair of shell items. 2 items are used to combine a user folder with a common folder (I.E. user programs/common programs)
PIDLIST_ABSOLUTE pItem1;
PIDLIST_ABSOLUTE pItem2;
unsignedint mfuHash; // MENU_RECENT
short mruOrder; // MENU_RECENT
short nameOffset; // MENU_RECENT
unsignedint categoryHash; // search item (lower 4 bits correspond to category)
short textStart, textEnd; // start and end horizontal offset of the text
int jumpIndex; // MENU_JUMPITEM: MAKELONG(group,item)
booloperator<( const MenuItem &item ) const
{
if (priority<item.priority) returntrue;
if (priority>item.priority) returnfalse;
if (row<item.row) returntrue;
if (row>item.row) returnfalse;
if ((bFolder && !bHasJumpList) && !(item.bFolder && !item.bHasJumpList)) returntrue;
if (!(bFolder && !bHasJumpList) && (item.bFolder && !item.bHasJumpList)) returnfalse;
if (drive && !item.drive) returntrue;
if (!drive && item.drive) returnfalse;
if (drive && item.drive) return drive<item.drive;
returnCompareMenuString(name,item.name)<0;
}
voidSetName( constwchar_t *_name, bool bNoExtensions )
{
if (bNoExtensions)
{
constwchar_t *end=wcsrchr(_name,'.');
if (end)
{
name=CString(_name,(int)(end-_name));
return;
}
}
name=_name;
}
voidSetName( const CString &_name, bool bNoExtensions )
{
if (bNoExtensions)
{
constwchar_t *start=_name;
constwchar_t *end=wcsrchr(start,'.');
if (end)
{
name=CString(start,(int)(end-start));
return;
}
}
name=_name;
}
voidClone( const MenuItem &item )
{
*this=item;
if (pItem1) pItem1=ILCloneFull(pItem1);
if (pItem2) pItem2=ILCloneFull(pItem2);
}
structMruNameComparator
{
booloperator()( const MenuItem &item1, const MenuItem &item2 ) const
{
returnCompareMenuString((constwchar_t*)item1.name+item1.nameOffset,(constwchar_t*)item2.name+item2.nameOffset)<0;
}
};
structMruOrderComparator
{
booloperator()( const MenuItem &item1, const MenuItem &item2 ) const
{
return item1.mruOrder<item2.mruOrder;
}
};
};
structSortMenuItem
{
CString name;
unsignedint nameHash;
bool bFolder;
bool bHasJumpList;
char priority;
char drive;
SortMenuItem( const CString &_name, unsigned _nameHash, bool _bFolder, bool _bHasJumpList, char _priority ,char _drive) { name=_name; nameHash=_nameHash; bFolder=_bFolder; bHasJumpList=_bHasJumpList; priority=_priority; drive=_drive; }
SortMenuItem( const MenuItem &item ) { name=item.name; nameHash=item.nameHash; bFolder=item.bFolder; bHasJumpList=item.bHasJumpList; priority=item.priority; drive=item.drive; }
booloperator<( const SortMenuItem &x ) const
{
if (priority<x.priority) returntrue;
if (priority>x.priority) returnfalse;
if ((bFolder && !bHasJumpList) && !(x.bFolder && !x.bHasJumpList)) returntrue;
if (!(bFolder && !bHasJumpList) && (x.bFolder && !x.bHasJumpList)) returnfalse;
if (drive && !x.drive) returntrue;
if (!drive && x.drive) returnfalse;
if (drive && x.drive) return drive<x.drive;
returnCompareMenuString(name,x.name)<0;
}
};
// Recent document item (sorts by time, newer first)
structDocument
{
CString name;
FILETIME time;
Document( void ) { time.dwHighDateTime=time.dwLowDateTime=0; }
booloperator<( const Document &x ) const { returnCompareFileTime(&time,&x.time)>0; }
};
LONG m_RefCount;
bool m_bSubMenu;
bool m_bDestroyed; // the menu is destroyed but not yet deleted
bool m_bTrackMouse;
bool m_bRefreshItems;
bool m_bWorkAreaPosted;
volatile DWORD m_RefreshPosted;
int m_Options;
const StdMenuItem *m_pStdItem; // the first item
CMenuContainer *m_pParent; // parent menu
int m_ParentIndex; // the index of this menu in the parent (usually matches m_pParent->m_Submenu)
int m_Submenu; // the item index of the opened submenu
int m_SubShowTime; // the time when the submenu was shown
int m_HotItem;
int m_InsertMark;
bool m_bInsertAfter;
bool m_bHotArrow;
unsignedint m_FolderHash[2]; // hash of the path to use for per-menu settings
CAbsolutePidl m_Path1[2];
CAbsolutePidl m_Path2[2];
CComPtr<IShellItem> m_pDropFolder[2]; // the primary folder (used only as a drop target)
CComPtr<IShellView> m_pShellView; // keep the view alive because some buggy namespace extensions clean up if there is no view
CComPtr<IContextCallback> m_pAccessibleContext;
CComPtr<IAccessible> m_pAccessible;
CComPtr<CDropTargetProxy> m_pDropTargetProxy;
DWORD m_InputCookie;
std::vector<int> m_ColumnOffsets;
std::vector<MenuItem> m_Items; // all items in the menu (including separators)
CComQIPtr<IContextMenu2> m_pMenu2; // additional interfaces used when a context menu is displayed
CComQIPtr<IContextMenu3> m_pMenu3;
int m_DragHoverTime;
int m_DragHoverItem;
int m_DragIndex; // the index of the item being dragged
CComPtr<IDropTargetHelper> m_pDropTargetHelper; // to show images while dragging
CComPtr<IDragSourceHelper2> m_pDragSourceHelper;
CComPtr<IDataObject> m_pDragObject;
CComPtr<IDropTarget> m_pDropTarget;
const CItemManager::ItemInfo *m_pDropTargetInfo;
int m_DropTargetIndex;
int m_DragTime;
int m_ClickIndex; // the index of the last clicked item (-2 until the mouse enters the menu for the first time)
bool m_bClickArrow;
int m_HoverItem; // item under the mouse (used for opening a submenu when the mouse hovers over an item)
bool m_bHoverArrow;
int m_ContextItem; // force this to be the hot item while a context menu is up
HBITMAP m_Bitmap; // the background bitmap
int m_BitmapOffset; // the horizontal offset of the main menu background from the window
HRGN m_Region; // the outline region
POINT m_PaintOffset;
int m_MaxWidth;
bool m_bTwoColumns;
RECT m_rMenu;
RECT m_rContent;
RECT m_rContent2;
RECT m_rUser1; // the user image (0,0,0,0 if the user image is not shown)
RECT m_rUser2; // the user name (0,0,0,0 if the user name is not shown)
RECT m_rPadding; // padding in the menu where right-click is possible
int m_ExtraTop, m_ExtraBottom; // amount of padding that the menu background virtually extends beyond the screen (not actually drawn)
int m_ExtraBorder; // hight of the border by which the menu extends beyond the screen (solid background with window border)
int m_ScrollCount; // number of items to scroll in the pager
int m_ScrollHeight; // 0 - don't scroll
int m_ScrollOffset;
int m_ScrollButtonSize;
int m_MouseWheel;
bool m_bScrollUp, m_bScrollDown;
bool m_bScrollUpHot, m_bScrollDownHot;
bool m_bScrollTimerMouse;
bool m_bScrollTimerTouch;
bool m_bNoSearchDraw;
bool m_bSearchDrawn;
bool m_bInSearchUpdate;
bool m_bDisableProgHover;
bool m_bClosing;
int m_SearchIndex;
int m_SearchProvidersCount;
int m_SearchItemCount;
CWindow m_SearchBox;
unsignedint m_SearchHash;
HBITMAP m_SearchIcons;
structSearchItem
{
SearchItem( const CString &_name, const CItemManager::ItemInfo *_info ) { name=_name; info=_info; }
SearchItem( const CItemManager::ItemInfo *_info ) { info=_info; }
CString name;
const CItemManager::ItemInfo *info;
};
intAddSearchItems( const std::vector<SearchItem> &items, const CString &categoryName, unsignedint categoryHash, int originalCount );
voidGetRecentPrograms( std::vector<MenuItem> &items, int maxCount );
// additional commands for the context menu
enum
{
CMD_OPEN=1,
CMD_OPEN_ALL,
CMD_SORT,
CMD_AUTOSORT,
CMD_NEWFOLDER,
CMD_NEWSHORTCUT,
CMD_DELETEMRU,
CMD_DELETEALL,
CMD_EXPLORE,
CMD_PIN,
CMD_PINSETTING,
CMD_TOGGLE,
CMD_DELETE,
CMD_RENAME,
CMD_MARKOLD,
CMD_UNINSTALL,
CMD_LAST,
CMD_MAX=32767
};
// ways to activate a menu item
enum TActivateType
{
ACTIVATE_SELECT, // just selects the item
ACTIVATE_OPEN, // opens the submenu or selects if not a menu
ACTIVATE_OPEN_KBD, // same as above, but when done with a keyboard
ACTIVATE_OPEN_SEARCH, // opens the search results submenu
ACTIVATE_EXECUTE, // executes the item
ACTIVATE_MENU, // shows context menu
ACTIVATE_MENU_BACKGROUND, // shows context menu for the menu itself
ACTIVATE_RENAME, // renames the item
ACTIVATE_DELETE, // deletes the item
ACTIVATE_PROPERTIES, // shows the properties of the item
};
// search state
enum TSearchState
{
SEARCH_NONE, // the search is inactive
SEARCH_BLANK, // the search box has the focus but is blank
SEARCH_TEXT, // the search box has the focus and is not blank
};
TSearchState m_SearchState;
unsignedint m_SearchCategoryHash;
enum
{
// timer ID
TIMER_HOVER=1,
TIMER_SCROLL_MOUSE=2,
TIMER_SCROLL_TOUCH=3,
TIMER_TOOLTIP_SHOW=4,
TIMER_TOOLTIP_HIDE=5,
TIMER_BALLOON_HIDE=6,
TIMER_SEARCH=7,
TIMER_DRAG=8,
MCM_REFRESH=WM_USER+10, // posted to force the container to refresh its contents
MCM_SETCONTEXTITEM=WM_USER+11, // sets the item for the context menu. wParam is the nameHash of the item
MCM_REDRAWEDIT=WM_USER+12, // redraw the search edit box
MCM_REFRESHICONS=WM_USER+13, // refreshes the icon list and redraws all menus
MCM_SETHOTITEM=WM_USER+14, // sets the hot item
MCM_WORKAREACHANGED=WM_USER+15, // when the working area is changed
// some constants
MIN_SCROLL_HEIGHT=13, // the scroll buttons are at least this tall
MAX_MENU_ITEMS=2000,
MENU_ANIM_SPEED=200,
MENU_ANIM_SPEED_SUBMENU=100,
MENU_FADE_SPEED=400,
MRU_PROGRAMS_COUNT=40,
};
voidAddFirstFolder( IShellItem *pFolder, std::vector<MenuItem> &items, int options );
voidAddSecondFolder( IShellItem *pFolder, std::vector<MenuItem> &items, int options );
structActivateData
{
ActivateData( void ) { bNoModifiers=bProgramsTree=bExpanded=bArrow=bAutoSort=bApps=false; command=0; pNewItemInfo=NULL; hTreeItem=NULL; }
bool bNoModifiers;
bool bProgramsTree; // this is an item from the tree
bool bExpanded; // for tree items
bool bArrow; // the arrow was clicked
bool bAutoSort; // the programs folder is auto-sort
bool bApps;
HTREEITEM hTreeItem;
CAbsolutePidl parent; // parent folder
int command; // menu command
const CItemManager::ItemInfo *pNewItemInfo; // returns the new item created by a rename or new folder
};
voidInitItems( void );
boolInitSearchItems( void );
voidInitWindow( bool bDontShrink=false );
voidInitWindowInternal( bool bDontShrink, const POINT &corner, RECT &menuRect );
voidInitWindowFinalize( const RECT &menuRect );
// pPt - optional point in screen space (used only by ACTIVATE_EXECUTE and ACTIVATE_MENU)
voidActivateItem( int index, TActivateType type, const POINT *pPt, ActivateData *pData=NULL );
voidActivateTreeItem( constvoid *treeItem, RECT &itemRect, TActivateType type, const POINT *pPt, ActivateData *pData=NULL );
voidDragTreeItem( constvoid *treeItem, bool bApps );
voidShowKeyboardCues( bool alt );
voidSetActiveWindow( void );
voidCreateBackground( int width1, int width2, int height1, int height2, int &totalWidth, int &totalHeight, bool bCreateRegion ); // width1/2, height1/2 - the first and second content area
voidBlendPatterns( unsignedint *bits, int width, int height );
voidCreateContentRects( int width1, int width2, int height1, int height2, int &totalWidth, int &totalHeight );
voidCreateSubmenuRegion( int width, int height ); // width, height - the content area
voidApplyRegion( BOOL bRedraw );
voidPostRefreshMessage( void );
voidSaveItemOrder( const std::vector<SortMenuItem> &items );
voidLoadItemOrder( void );
voidRemoveMFUShortcut( unsignedint hash, bool bAppId );
voidFadeOutItem( int index );
boolGetItemRect( int index, RECT &rc );
intHitTest( const POINT &pt, bool *bArrow, bool bDrop=false );
boolDragOut( int index, bool bApp );
boolDragOutApps( const CItemManager::ItemInfo *pInfo );
CComPtr<IDataObject> CreateMetroDataObject( const CItemManager::ItemInfo *pInfo );
voidGetDragEffect( DWORD &grfKeyState, DWORD *pdwEffect );
voidInvalidateItem( int index );
voidSetHotItem( int index, bool bArrow=false, bool bShowTip=false );
voidSetSubmenu( int index );
voidSetContextItem( int index );
voidSetClickItem( int index );
voidUpdateUserPicture( void );
voidSetInsertMark( int index, bool bAfter );
boolGetInsertRect( RECT &rc );
voidDrawBackground( HDC hdc, const RECT &drawRect );
boolGetDescription( int index, wchar_t *text, int size );
voidUpdateScroll( void );
voidUpdateScroll( const POINT *pt, bool bTouch );
boolCanSelectItem( int index, bool bKeyboard=true );
voidSetSearchState( TSearchState state );
voidUpdateSearchResults( bool bForceShowAll );
voidAddInternetSearch( size_t index );
voidAddStandardItems( void );
voidUpdateAccelerators( int first, int last );
voidExecuteCommand( constwchar_t *command, bool bElevated, bool bEnvSubst );
voidRunUserCommand( bool bPicture );
voidOpenSubMenu( int index, TActivateType type, bool bShift );
voidUpdateAutoComplete( constwchar_t *text );
boolHasMoreResults( void );
RECT CalculateWorkArea( const RECT &taskbarRect );
POINT CalculateCorner( void );
voidNotifyDisplayChange( void );
#defineAW_TOPMOST0x00100000
voidAnimateMenu( int flags, int speed, const RECT &rect );
enum
{
COLLECT_RECURSIVE = 1, // go into subfolders
COLLECT_PROGRAMS = 2, // only collect programs (.exe, .com, etc)
COLLECT_FOLDERS = 4, // include folder items
COLLECT_METRO = 8, // check for metro links (non-recursive)
COLLECT_KEYWORDS =16, // include the keywords
};
staticint s_MaxRecentDocuments; // limit for the number of recent documents
staticint s_ScrollMenus; // global scroll menus setting
staticbool s_bRTL; // RTL layout
staticbool s_bKeyboardCues; // show keyboard cues
staticbool s_bOverrideFirstDown; // the first down key from the search box will select the top item
staticbool s_bExpandRight; // prefer expanding submenus to the right
staticbool s_bBehindTaskbar; // the main menu is behind the taskbar (when the taskbar is horizontal)
staticbool s_bShowTopEmpty; // shows the empty item on the top menu so the user can drag items there
staticbool s_bNoDragDrop; // disables drag/drop
staticbool s_bNoContextMenu; // disables the context menu
staticbool s_bExpandLinks; // expand links to folders
staticbool s_bSingleClickFolders; // open links to folders with one click instead of two
staticbool s_bLogicalSort; // use StrCmpLogical instead of CompareString
staticbool s_bExtensionSort; // sort file names by extension
staticbool s_bAllPrograms; // this is the All Programs menu of the Windows start menu
staticbool s_bNoCommonFolders; // don't show the common folders (start menu and programs)
staticbool s_bNoRun; // don't show run, disable autocomplete
staticbool s_bNoClose; // don't show shutdown, restart, sleep and hibernate
staticbool s_bHasTouch; // the device has integrated touch digitizer
staticchar s_bActiveDirectory; // the Active Directory services are available (-1 - uninitialized)
staticbool s_bPreventClosing; // prevents the menus from closing even if they lose focus
staticbool s_bDragClosed; // the menu was closed during a drag operation
staticbool s_bTempHidden; // the menu windows are temporarily hidden
staticbool s_bDisableHover; // disable hovering while the search box has the focus
staticbool s_bHasUpdates; // the OS wants to install updates
static CMenuContainer *s_pDragSource; // the source of the current drag operation
staticbool s_bDragFromTree; // the source is the programs tree
staticbool s_bDragMovable; // the dragged item is normal original item
staticbool s_bRightDrag; // dragging with the right mouse button
staticbool s_bLockWorkArea; // changes to the work area are ignored
staticbool s_bPendingSearchEnter; // Enter was pressed before the search results were ready
static RECT s_MenuLimits; // area of the main monitor accessible to all menus
static RECT s_MainMenuLimits; // area of the main monitor accessible by the main menu
static DWORD s_TaskbarState; // the state of the taskbar (ABS_AUTOHIDE and ABS_ALWAYSONTOP)
static DWORD s_HoverTime;
static DWORD s_SplitHoverTime;
static DWORD s_ProgramsHoverTime;
static DWORD s_XMouse;
static DWORD s_SubmenuStyle;
staticint s_TaskBarId;
static HWND s_TaskBar, s_StartButton; // the current taskbar and start button
static UINT s_TaskBarEdge;
static RECT s_StartRect; // the bounds of the start button
static HWND s_LastFGWindow; // stores the foreground window to restore later when the menu closes
static HMONITOR s_MenuMonitor;
static HTHEME s_Theme;
static HTHEME s_PagerTheme;
static CWindow s_Tooltip;
static CWindow s_TooltipBalloon;
staticint s_TipShowTime;
staticint s_TipHideTime;
staticint s_TipShowTimeFolder;
staticint s_TipHideTimeFolder;
static DWORD s_HotPos; // last mouse position over a hot item (used to ignore WM_MOUSEMOVE when the mouse didn't really move)
staticint s_HotItem;
static CMenuContainer *s_pHotMenu; // the menu with the hot item
staticint s_TipItem; // the item that needs a tooltip
static CMenuContainer *s_pTipMenu;
static HBITMAP s_ArrowsBitmap;
staticunsignedint s_LastArrowColor;
static CComPtr<IFrameworkInputPane> s_pFrameworkInputPane;
static CString s_PinFolder;
static CLIPFORMAT s_ShellFormat; // CFSTR_SHELLIDLIST
static CLIPFORMAT s_ShellUrlFormat; // CFSTR_INETURL
static CLIPFORMAT s_DescriptorFormat; // CFSTR_FILEDESCRIPTOR
static CLIPFORMAT s_ContentsFormat; // CFSTR_FILECONTENTS
static CLIPFORMAT s_PreferredEffectFormat;
static CLIPFORMAT s_MetroLinkFormat;
static CLIPFORMAT s_DropDescriptionFormat;
static TRecentPrograms s_RecentPrograms; // show and track recent items
static std::vector<CMenuContainer*> s_Menus; // all menus, in cascading order
staticvolatile HWND s_FirstMenu, s_SearchMenu;
static CSearchManager::SearchResults s_SearchResults;
static std::map<unsignedint,int> s_MenuScrolls; // scroll offset for each sub menu
staticchar s_HasMoreResults; // -1 - uninitialized
staticint s_ProgramsWidth, s_JumplistWidth;
static CString s_MRUShortcuts[MRU_PROGRAMS_COUNT];
staticbool s_bMRULoaded;
staticconst CItemManager::ItemInfo *s_JumpAppInfo;
static CJumpList s_JumpList;
static MenuSkin s_Skin;
friendclassCMetroDataObject;
friendclassCOwnerWindow;
friendclassCMenuAccessible;
friend LRESULT CALLBACK SubclassTopMenuProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData );
friend HRESULT CreatePinLink( PCIDLIST_ABSOLUTE sourcePidl, constwchar_t *name, constwchar_t *iconPath, int iconIndex );
staticvoidAddMRUShortcut( constwchar_t *path );
staticvoidAddMRUAppId( constwchar_t *appid );
staticvoidDeleteMRUShortcut( constwchar_t *path );
staticvoidDeleteMRUAppId( constwchar_t *appid );
staticvoidSaveMRUShortcuts( void );
staticvoidLoadMRUShortcuts( void );
static HBITMAP LoadUserImage( int size, HBITMAP hMask );
staticintCompareMenuString( constwchar_t *str1, constwchar_t *str2 );
static LRESULT CALLBACK SubclassSearchBox( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData );
static LRESULT CALLBACK SubclassScrollbar( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData );
voidClearItems( const std::vector<MenuItem>::iterator &begin, const std::vector<MenuItem>::iterator &end );
voidAddJumpListItems( std::vector<MenuItem> &items );
static HBITMAP GetArrowsBitmap( unsignedint color );
staticboolCloseProgramsMenu( void );
staticvoidHideStartMenu( void );
staticvoidSetDropTip( IDataObject *pDataObj, bool bPin );
enum
{
CLOSE_POST =1,
CLOSE_SKIP_LAST =2,
CLOSE_SKIP_SEARCH =4,
CLOSE_ONLY_SEARCH =8,
CLOSE_KEEP_MODE =16,
};
staticvoidCloseSubMenus( int flags, CMenuContainer *pAfter );
structCreateAccessibleData
{
CMenuContainer *pMenu;
IStream *pStream;
};
static HRESULT __stdcall CreateAccessible( ComCallData *pData );
static HRESULT __stdcall ReleaseAccessible( ComCallData *pData );
// To control the placement of the start menu, send OpenShellMenu.StartMenuMsg message right after the start menu is created but before it is displayed
// The lParam must point to StartMenuParams
// monitorRect - the entire area available to the start menu (sub-menus will use it). It is usually the monitor area but can be less if the Desktop app is docked in Win8
// uEdge - the location of the taskbar - ABE_BOTTOM, ABE_LEFT, etc
// taskbarRect - the bounding box of the taskbar. When the taskbar is at the top or bottom, the main menu will try to not overlap that rect. When the taskbar is on the side the behavior depends on the ShowNextToTaskbar setting