@@ -411,6 +411,177 @@ public void ShowContextMenu(Control control, Point pos, CMF aditionalFlags = 0,
411411 Marshal . Release ( this . _Result ) ;
412412 this . _Result = IntPtr . Zero ;
413413 }
414+ public void ShowContextMenu ( Point pos , CMF aditionalFlags , bool IsOnEmpty = false ) {
415+ using ( ContextMenu mnu = new ContextMenu ( ) ) {
416+ this . Populate ( mnu , aditionalFlags ) ;
417+ this . _Timer . Interval = 2 ;
418+ this . _Timer . Tick += TimerOnTick ;
419+ this . _Timer . Stop ( ) ;
420+
421+ var view = new ContextMenu ( ) ;
422+ var sortMenu = new ContextMenu ( ) ;
423+ var groupMenu = new ContextMenu ( ) ;
424+ var count = User32 . GetMenuItemCount ( mnu . Handle ) ;
425+
426+ var itemInfo = new MENUITEMINFO ( ) ;
427+
428+ itemInfo . fMask = MIIM . MIIM_FTYPE | MIIM . MIIM_DATA | MIIM . MIIM_STRING | MIIM . MIIM_SUBMENU | MIIM . MIIM_ID ;
429+ if ( User32 . GetMenuItemInfo ( mnu . Handle , count - 1 , true , ref itemInfo ) ) {
430+ if ( ( itemInfo . fType & MFT . MFT_SEPARATOR ) != 0 ) {
431+ User32 . DeleteMenu ( mnu . Handle , count - 1 , MF . MF_BYPOSITION ) ;
432+ }
433+ }
434+
435+ User32 . GetMenuItemInfo ( mnu . Handle , User32 . GetMenuItemCount ( mnu . Handle ) - 3 , true , ref itemInfo ) ;
436+ if ( itemInfo . hSubMenu == IntPtr . Zero ) {
437+ User32 . GetMenuItemInfo ( mnu . Handle , User32 . GetMenuItemCount ( mnu . Handle ) - 1 , true , ref itemInfo ) ;
438+ }
439+
440+ this . _NewMenuPtr = itemInfo . hSubMenu ;
441+
442+ if ( IsOnEmpty ) {
443+ this . GenerateExplorerBackgroundMenuItems ( view , mnu , sortMenu , groupMenu ) ;
444+ } else {
445+ if ( this . _Items . FirstOrDefault ( ) ? . IsFolder == true ) {
446+ this . GenerateMenuItem ( mnu , System . Windows . Application . Current ? . FindResource ( "mnuOpenNewTab" ) ? . ToString ( ) , 301 , false , 1 ) ;
447+ }
448+ }
449+
450+ this . RemoveDuplicatedSeparators ( mnu ) ;
451+
452+
453+
454+ var command = User32 . TrackPopupMenuEx ( mnu . Handle , TPM . TPM_RETURNCMD , pos . X , pos . Y , m_MessageWindow . Handle , IntPtr . Zero ) ;
455+ if ( command > 0 && command < m_CmdFirst ) {
456+ switch ( command ) {
457+ case 245 :
458+ this . _ShellView . SetGroupOrder ( false ) ;
459+ break ;
460+ case 246 :
461+ this . _ShellView . SetGroupOrder ( ) ;
462+ break ;
463+ case 247 :
464+ var colasc = this . _ShellView . Collumns . FirstOrDefault ( w => w . ID == this . _ShellView . LastSortedColumnId ) ;
465+ this . _ShellView . SetSortCollumn ( true , colasc , SortOrder . Ascending ) ;
466+ break ;
467+ case 248 :
468+ var coldesc = this . _ShellView . Collumns . FirstOrDefault ( w => w . ID == this . _ShellView . LastSortedColumnId ) ;
469+ this . _ShellView . SetSortCollumn ( true , coldesc , SortOrder . Descending ) ;
470+ break ;
471+ case 249 :
472+ this . _ShellView . PasteAvailableFiles ( ) ;
473+ break ;
474+ case 250 :
475+ this . _ShellView . RefreshContents ( ) ;
476+ break ;
477+ case 251 :
478+ this . _ShellView . View = ShellViewStyle . ExtraLargeIcon ;
479+ break ;
480+ case 252 :
481+ this . _ShellView . View = ShellViewStyle . LargeIcon ;
482+ break ;
483+ case 253 :
484+ this . _ShellView . View = ShellViewStyle . Medium ;
485+ break ;
486+ case 254 :
487+ this . _ShellView . View = ShellViewStyle . SmallIcon ;
488+ break ;
489+ case 255 :
490+ this . _ShellView . View = ShellViewStyle . List ;
491+ break ;
492+ case 256 :
493+ this . _ShellView . View = ShellViewStyle . Details ;
494+ break ;
495+ case 257 :
496+ this . _ShellView . View = ShellViewStyle . Tile ;
497+ break ;
498+ case 258 :
499+ this . _ShellView . View = ShellViewStyle . Content ;
500+ break ;
501+ case 259 :
502+ this . _ShellView . View = ShellViewStyle . Thumbstrip ;
503+ break ;
504+ case 260 :
505+ if ( this . _ShellView . IsGroupsEnabled ) {
506+ this . _ShellView . DisableGroups ( ) ;
507+ }
508+ break ;
509+ case 301 :
510+ this . _ShellView . RaiseMiddleClickOnItem ( this . _Items . First ( ) ) ;
511+ break ;
512+ default :
513+ break ;
514+ }
515+
516+ if ( command >= 262 && command <= 262 + this . _ShellView . Collumns . Count ) {
517+ this . _ShellView . SetSortCollumn ( true , this . _ShellView . Collumns [ command - 262 ] , SortOrder . Ascending ) ;
518+ } else if ( command > 260 && command != 301 ) {
519+ if ( ! this . _ShellView . IsGroupsEnabled )
520+ this . _ShellView . EnableGroups ( ) ;
521+ this . _ShellView . GenerateGroupsFromColumn ( this . _ShellView . Collumns [ command - ( 262 + this . _ShellView . Collumns . Count ) - 1 ] , false ) ;
522+ }
523+ }
524+
525+ if ( command > m_CmdFirst ) {
526+ var info = string . Empty ;
527+ var bytes = new byte [ 256 ] ;
528+ IntPtr pszName = Marshal . AllocHGlobal ( 256 ) ;
529+ this . m_ComInterface3 . GetCommandString ( command - ( int ) m_CmdFirst , 4 , 0 , pszName , 260 ) ;
530+
531+ //var index = 0;
532+ //while (index < bytes.Length - 1 && (bytes[index] != 0 || bytes[index + 1] != 0)) { index += 2; }
533+
534+ //if (index < bytes.Length - 1) { info = Encoding.Unicode.GetString(bytes, 0, index); }
535+ info = Marshal . PtrToStringAuto ( pszName ) ;
536+
537+ switch ( info ) {
538+ case "open" :
539+ //(control as ShellView)?.OpenOrNavigateItem();
540+ break ;
541+ case "rename" :
542+ //(control as ShellView)?.RenameSelectedItem();
543+ break ;
544+ case "cut" :
545+ //(control as ShellView)?.CutSelectedFiles();
546+ break ;
547+ case "copy" :
548+ //(control as ShellView)?.CopySelectedFiles();
549+ break ;
550+ default :
551+ CMINVOKECOMMANDINFOEX cminvokecommandinfoex = new CMINVOKECOMMANDINFOEX {
552+ lpVerb = ( IntPtr ) ( command - m_CmdFirst ) ,
553+ lpVerbW = ( IntPtr ) ( command - m_CmdFirst )
554+ } ;
555+ cminvokecommandinfoex . cbSize = Marshal . SizeOf ( cminvokecommandinfoex ) ;
556+
557+ //cminvokecommandinfoex.lpDirectory = this._ShellView.CurrentFolder.ParsingName;
558+ //cminvokecommandinfoex.lpDirectoryW = this._ShellView.CurrentFolder.ParsingName;
559+
560+ cminvokecommandinfoex . fMask = ( ( CMIC . Asyncok | CMIC . PtInvoke | CMIC . Unicode | CMIC . FlagNoUi ) | ( ( ( Control . ModifierKeys & Keys . Control ) > Keys . None ) ? CMIC . ControlDown : ( ( CMIC ) 0 ) ) ) | ( ( ( Control . ModifierKeys & Keys . Shift ) > Keys . None ) ? CMIC . ShiftDown : ( ( CMIC ) 0 ) ) ;
561+ cminvokecommandinfoex . ptInvoke = pos ;
562+ cminvokecommandinfoex . nShow = 1 ;
563+ //cminvokecommandinfoex.hwnd = this._ShellView.LVHandle;
564+ this . m_ComInterface3 . InvokeCommand ( ref cminvokecommandinfoex ) ;
565+ //this.InvokeCommand((IntPtr)(command - m_CmdFirst), pos, (IntPtr)(command - m_CmdFirst));
566+ break ;
567+ }
568+ }
569+
570+ User32 . DestroyMenu ( mnu . Handle ) ;
571+ view . Dispose ( ) ;
572+ User32 . DestroyMenu ( view . Handle ) ;
573+ sortMenu . Dispose ( ) ;
574+ User32 . DestroyMenu ( sortMenu . Handle ) ;
575+ groupMenu . Dispose ( ) ;
576+ User32 . DestroyMenu ( groupMenu . Handle ) ;
577+ }
578+
579+ Marshal . ReleaseComObject ( this . m_ComInterface ) ;
580+ Marshal . ReleaseComObject ( this . m_ComInterface2 ) ;
581+ Marshal . ReleaseComObject ( this . m_ComInterface3 ) ;
582+ Marshal . Release ( this . _Result ) ;
583+ this . _Result = IntPtr . Zero ;
584+ }
414585 private void TimerOnTick ( Object sender , EventArgs e ) {
415586 this . _Timer . Stop ( ) ;
416587 User32 . SendMessage ( this . m_MessageWindow . Handle , 0x001F , 0 , 0 ) ;
0 commit comments