Explorer-Kontextmenü öffnen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
silbersurfer
Beiträge: 174
Registriert: 06.07.2014 12:21

Explorer-Kontextmenü öffnen

Beitrag von silbersurfer »

Hallo leute,

Edit:
ich habe eine frage bezüglich des Kontextmenü, welches ja wenn man mit der rechten Maustaste auf Dateien klickt im Explorer
erscheint.
Kann man dieses auch unter Purebasic einrichten / erreichen ?

gruß Silbersurfer

__________________________________________________
Thread-Titel umbenannt
System Pupup Menü aufrufen ?>Explorer-Kontextmenü öffnen
11.03.2018
RSBasic
Zuletzt geändert von silbersurfer am 11.03.2018 12:15, insgesamt 1-mal geändert.
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Explorer-Kontextmenü öffnen

Beitrag von RSBasic »

Ich habe den Titel deines Thread geändert, weil System-Menü ist was ganz anders. Das kann bei der Suche etwas verwirrend sein. Was du suchst, nennt sich Kontextmenü im Explorer.
Und hier die Lösung: http://www.rsbasic.de/winapi-library/ > Dateien > Datei-Kontextmenü öffnen
Die Zeile:

Code: Alles auswählen

*pldMap.l
einfach ändern in:

Code: Alles auswählen

*pldMap
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
silbersurfer
Beiträge: 174
Registriert: 06.07.2014 12:21

Re: Explorer-Kontextmenü öffnen

Beitrag von silbersurfer »

Ja danke RSBasic,
das war genau was ich gesucht habe funzt tadellos :allright:

Edit:
Habe den code etwas anwenderfreundlich in Proceduren verpackt danke noch einmal RSBasic

Code: Alles auswählen

;Autor: freak
;http://www.purebasic.fr/english/viewtopic.php?p=284528#p284528

Structure CMINVOKECOMMANDINFOEX
  cbSize.l
  fMask.l
  hwnd.i
  lpVerb.i
  lpParameters.i
  lpDirectory.i
  nShow.l
  dwHotKey.l
  hIcon.i
  lpTitle.i
  lpVerbW.i
  lpParametersW.i
  lpDirectoryW.i
  lpTitleW.i
  ptInvoke.POINT
EndStructure

Structure QCMINFO
  hmenu.i
  indexMenu.l
  idCmdFirst.l
  idCmdLast.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    _alignment.l
  CompilerEndIf
*pldMap
EndStructure

#GCS_VERBA = 0
#CMF_NORMAL = 0
#CMF_CANRENAME = 16

#DFM_MERGECONTEXTMENU   = 1
#DFM_INVOKECOMMAND      = 2
#DFM_GETDEFSTATICID     = 14
#DFM_CMD_PROPERTIES     = -5

; Win2k and newer only!
;
Prototype CDefFolderMenu_Create2(a, b, c, d, e, f, g, h, i)
Global CDefFolderMenu_Create2.CDefFolderMenu_Create2

#Window = 0
#Menu   = 0
#ExplorerList = 0

; These can be changed to limit the range of menu IDs that the context menu will use
; to avoid conflicts with other menus in the program
;
#FirstShellMenuItem = 0
#LastShellMenuItem  = 9999

Global CustomMenuEntry

; Callback function for the CDefFolderMenu_Create2() call
;
Procedure Callback(*psf.IShellFolder, hwnd, pdtobj.IDataObject, uMsg, wParam, lParam)
  Select uMsg
     
    Case #DFM_MERGECONTEXTMENU
       
      ; Here custom entries can be added to the created menu
      ;
      *qcminfo.QCMINFO = lParam
      If *qcminfo\idCmdLast > *qcminfo\idCmdFirst     
       
        If InsertMenu_(*qcminfo\hmenu, *qcminfo\indexMenu, #MF_BYPOSITION|#MF_STRING, *qcminfo\idCmdFirst, @"--- Custom Menu Entry ---")
          ; Save the ID and tell the caller that one entry was added
          ;
          CustomMenuEntry = *qcminfo\idCmdFirst
          *qcminfo\idCmdFirst + 1
        EndIf
       
      EndIf
      ProcedureReturn #S_OK
   
    Case #DFM_INVOKECOMMAND
   
      ; Here the execution of the commands can be overwritten.
      ; return #S_FALSE to get the default behavior
      ProcedureReturn #S_FALSE
   
    Case #DFM_GETDEFSTATICID
   
      ; return #S_FALSE to get the default handling
      ProcedureReturn #S_FALSE
   
    Default
      ProcedureReturn #E_NOTIMPL
     
  EndSelect
EndProcedure

CoInitialize_(0)

If OpenLibrary(0, "shell32.dll")
  CDefFolderMenu_Create2 = GetFunction(0, "CDefFolderMenu_Create2")
 
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    ; Win2k only exports this by ordinal, newer versions export by name
    If CDefFolderMenu_Create2 = 0
      CDefFolderMenu_Create2 = GetFunctionEntry(0, 701)
    EndIf
  CompilerEndIf
 
  If CDefFolderMenu_Create2 = 0
    Debug "Error, cannot find CDefFolderMenu_Create2()"
    End
  EndIf
EndIf

ShellMenu.IContextMenu = 0

Procedure Kontextmenue_Event(window.i)
	Shared ShellMenu
	If  ShellMenu And EventMenu() >= #FirstShellMenuItem And EventMenu() <= #LastShellMenuItem
   
      If EventMenu() = CustomMenuEntry
        ; Its our custom menu item
        Debug "--- custom menu item selected ---"
     
      Else
        ; its one of the shell items
       
        Debug "handling event: " + Str(EventMenu())

        Command$ = Space(1000)
        If ShellMenu\GetCommandString(EventMenu(), #GCS_VERBA, #Null, @Command$, 1000) = #S_OK
          Debug "Commmand: " + Command$     
         
          ; Some of these commands can be directly passed to ShellExecute_() for example         
        EndIf
     
        ; Let the menu object execute this command
        ;
        info.CMINVOKECOMMANDINFOEX\cbSize = SizeOf(CMINVOKECOMMANDINFOEX)
        info\fMask  = 0
        info\hwnd   = WindowID(window)
        info\lpVerb = EventMenu()
        info\nShow  = #SW_SHOWNORMAL
       
        err = ShellMenu\InvokeCommand(@info)
        If err = #S_OK
          Debug "command executed"
        Else
          Debug "command could not be executed. error = "+Str(err)
        EndIf
      EndIf
   
    EndIf   	
EndProcedure

Procedure Kontextmenue(Window.i,Explorer.i)
	Shared ShellMenu
       If SHGetDesktopFolder_(@Desktop.IShellFolder) = #S_OK
        Debug "got desktop folder"
       
        ParentFolder$ = GetGadgetText(Explorer)               
        If Desktop\ParseDisplayName(WindowID(Window), #Null, ParentFolder$, #Null, @*ParentIDL, #Null) = #S_OK
          Debug "got parent folder idl"
         
          If Desktop\BindToObject(*ParentIDL, #Null, ?IID_IShellFolder, @Parent.IShellFolder) = #S_OK
            Debug "got parent folder object"
           
           
            ; Get the IDLs for all selected items
            ;
            TotalCount = CountGadgetItems(Explorer)
            ItemCount  = 0
            For i = 0 To TotalCount-1
              If GetGadgetItemState(Explorer, i) & #PB_Explorer_Selected And GetGadgetItemText(Explorer, i, 0) <> ".."
                ItemCount + 1
              EndIf
            Next i
           
            If ItemCount > 0
                         
              Dim *FileIDL(ItemCount-1)
             
              ParsedCount = 0
              For i = 0 To TotalCount-1
                If GetGadgetItemState(Explorer, i) & #PB_Explorer_Selected And GetGadgetItemText(Explorer, i, 0) <> ".."
                  ItemName$ = GetGadgetItemText(Explorer, i, 0)
                 
                  If Parent\ParseDisplayName(WindowID(Window), #Null, ItemName$, #Null, @*FileIDL(ParsedCount), #Null) = #S_OK
                    ParsedCount + 1
                  EndIf                 
                EndIf
              Next i   
             
              ; Only go to the menu if parsing all items worked correctly
              ;
              If ParsedCount = ItemCount
                Debug "got item idl's"       
               
                ; Free the old menu object
                If ShellMenu
                  ShellMenu\Release()
                  ShellMenu = 0
                EndIf
               
                ; Open the registry keys for shell extensions
                ;
                KeyCount = 1
                Dim KeyStrings.s(KeyCount)
                Dim hKey(KeyCount)
               
                KeyStrings(0) = "*"
;                 KeyStrings(1) = ".txt"
;                 KeyStrings(2) = "txtfile"
               
                KeysOpen = 0
                For i = 0 To KeyCount-1
                  If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, @KeyStrings(i), 0, #Null, 0, #KEY_READ, #Null, @hKey(KeysOpen), #Null) = #ERROR_SUCCESS
                    KeysOpen + 1
                  EndIf
                Next i
               
                ; Create the menu object for our items with the above callback
                ;
                If CDefFolderMenu_Create2(*ParentIDL, WindowID(Window), ParsedCount, @*FileIDL(), Parent, @Callback(), KeysOpen, @hKey(), @ShellMenu.IContextMenu) = #S_OK
                  Debug "got menu"
                 
                  ; Create a PB popupmenu to put the menu items in
                  ;
                  If CreatePopupMenu(#Menu)
                    Debug "got pb menu"
                   
                    ; Add the Shell menu to our popup menu
                    ; You can specify the range of menu item ids to use here (to not conflict with others from your program)
                    ;                       
                    If ShellMenu\QueryContextMenu(MenuID(#Menu), 0, #FirstShellMenuItem, #LastShellMenuItem, #CMF_NORMAL|#CMF_CANRENAME) >= 0
                      Debug "menu items added"
                   
                      ; Finally display the popup menu
                      ;
                      DisplayPopupMenu(#Menu, WindowID(Window))
                    EndIf
                  EndIf
                EndIf   
               
                For i = 0 To KeysOpen-1
                  RegCloseKey_(hkey(i))
                Next i
             
              Else
                Debug "error in parsing a selected item"
               
              EndIf
             
              ; Free the item IDLs (as far as they were parsed)
              ;
              For i = 0 To ParsedCount-1
                CoTaskMemFree_(*FileIDL(i))
              Next i

            EndIf
           
            Parent\Release()
          EndIf
         
          CoTaskMemFree_(*ParentIDL)
        EndIf
     
        Desktop\Release()
      EndIf
EndProcedure


If OpenWindow(#Window, 0, 0, 500, 500, "ContextMenu test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ExplorerListGadget(#ExplorerList, 10, 10, 480, 480, "C:\", #PB_Explorer_MultiSelect|#PB_Explorer_FullRowSelect|#PB_Explorer_AlwaysShowSelection)

  Repeat
    Event = WaitWindowEvent()
   
    ; Right-click event in the gadget
    ;
    If Event = #PB_Event_Gadget And EventGadget() = #ExplorerList And EventType() = #PB_EventType_RightClick
  		Kontextmenue(#Window,#ExplorerList)
    ElseIf Event = #PB_Event_Menu And ShellMenu And EventMenu() >= #FirstShellMenuItem And EventMenu() <= #LastShellMenuItem
    	Kontextmenue_Event(#Window)
    EndIf   
     
   
  Until Event = #PB_Event_CloseWindow
EndIf

CoUninitialize_()

End

DataSection

  IID_IShellFolder: ; {000214E6-0000-0000-C000-000000000046}
    Data.l $000214E6
    Data.w $0000, $0000
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46

EndDataSection
; IDE Options = PureBasic 5.31 (Windows - x64)
; CursorPosition = 2
; Folding = -
; EnableUnicode
; EnableXP
; EnableUser
; EnableCompileCount = 0
; EnableBuildCount = 0
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
oO0XX0Oo
Beiträge: 55
Registriert: 21.07.2017 22:36

Re: Explorer-Kontextmenü öffnen

Beitrag von oO0XX0Oo »

Hallo,

Im Großen und Ganzen funktioniert das zwar, aber es fehlen gegenüber dem Menü, welches man im Windows Explorer bekommt, viele Grundeinträge.

Z.B. für Verzeichnisse
Windows Explorer:
Bild
PureBasic:
Bild

Ähnlich sieht es auch für Klicks auf Dateien aus, hier z.B. auf eine .msi Datei
Windows Explorer:
Bild
PureBasic:
Bild

Kommt man an diese vollständigen Menüs, wie man sie im Windows Explorer
sehen kann unter PB nicht ran?
Antworten