PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Программирование на PureBasic » Контекстное меню проводника


Контекстное меню проводника

Сообщений 1 страница 3 из 3

1

Вот нашел на забугорном форуме код контекстного меню. Если суметь его подрихтовать, то будет такое же как у WINAMP, WINRAR, AIMP и др.  А пока может считывать только один файл. Установка скомпилировать DLL и запустить регистрацию из командной строки:

1) C:\WINDOWS\system32\regsvr32  C:\PathToMyDLL\MY.dll          установка

2) C:\WINDOWS\system32\regsvr32 /u  C:\PathToMyDLL\MY.dll                  удаление

Код:
Procedure Error(message$) 
  wError = GetLastError_() 
  If wError 
    *ErrorBuffer = AllocateMemory(1024) 
    FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, wError, 0, *ErrorBuffer, 1024, 0) 
    message$+Chr(10)+PeekS(*ErrorBuffer) 
    FreeMemory(*ErrorBuffer) 
  EndIf 
  MessageRequester("Error", message$) 
EndProcedure 

Structure ClassFactoryObject 
  lpVtbl.l 
  nRefCount.l 
  nLockCount.l 
EndStructure 

Global m_pDataObj.IDataObject, cmd, hModule 
Global i_Unk.IUnknown, i_SEI.IShellExtInit, i_QCM.IContextMenu 
Global *p_Unk.ClassFactoryObject 
Global File$ 

Procedure Ansi2Uni1(*st, *Buffer, blen) 
  If Len(PeekS(*st))<blen 
    ProcedureReturn MultiByteToWideChar_(#CP_ACP, 0, *st, -1, *Buffer, blen) 
  Else 
    ProcedureReturn 0 
  EndIf 
EndProcedure 

Procedure IUnknown_QueryInterface(*ti_unk.IUnknown, *riid.GUID, *ppvObject.LONG) 
  If *ppvObject 
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(GUID)) 
      MessageRequester("", "iunknown") 
      *ppvObject\l = i_Unk 
    ElseIf CompareMemory(*riid, ?IID_IShellExtInit, SizeOf(GUID)) 
      *ppvObject\l = i_SEI 
    ElseIf CompareMemory(*riid, ?IID_IContextMenu, SizeOf(GUID)) 
      *ppvObject\l = i_QCM 
    Else 
      ProcedureReturn #E_NOINTERFACE 
    EndIf 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
  i_Unk\AddRef() 
  ProcedureReturn #S_OK 
EndProcedure 

Procedure IUnknown_AddRef(*ti_unk.IUnknown):*p_Unk\nRefCount+1:ProcedureReturn *p_Unk\nRefCount:EndProcedure 

Procedure IUnknown_Release(*ti_unk.IUnknown):*p_Unk\nRefCount-1:ProcedureReturn *p_Unk\nRefCount:EndProcedure 

Procedure IClassFactory_CreateInstance(*ti_cf.IClassFactory, *pUnkOuter.IUnknown, *riid.GUID, *ppvObject) 
  If *pUnkOuter 
    ProcedureReturn #CLASS_E_NOAGGREGATION 
  Else 
    If i_SEI=#Null 
      ProcedureReturn #E_OUTOFMEMORY 
    Else 
      hr = i_SEI\QueryInterface(*riid, *ppvObject) 
    EndIf 
  EndIf 
  ProcedureReturn hr 
EndProcedure 

Procedure IClassFactory_LockServer(*ti_cf.IClassFactory, fLock) 
  ProcedureReturn #E_FAIL 
EndProcedure 

#CF_HDROP = $0f 
#DVASPECT_CONTENT = 1 
#TYMED_HGLOBAL = 1 
#TYMED_FILE = 2 

Procedure IShellExtInit_Initialize(*ti_sei.IShellExtInit, *pidlFolder.ITEMIDLIST, *pdtobj.IDataObject, hkeyProgID) 
  If m_pDataObj 
    m_pDataObj\Release() 
  EndIf 
  If *pdtobj 
    m_pDataObj = *pdtobj 
    *pdtobj\AddRef() 
    fe.FORMATETC\cfFormat = #CF_HDROP 
    fe\ptd = #Null 
    fe\dwAspect = #DVASPECT_CONTENT 
    fe\lindex = -1 
    fe\tymed = #TYMED_HGLOBAL 
    If *pdtobj\GetData(@fe, @medium.STGMEDIUM)=#S_OK 
      uCount = DragQueryFile_(medium\hGlobal, -1, #Null, 0) 
      If uCount=1 
        *m_szFile = AllocateMemory(#MAX_PATH) 
        DragQueryFile_(medium\hGlobal, 0, *m_szFile, #MAX_PATH) 
        If Len(PeekS(*m_szFile))=0 
          uCount = 0 
        Else 
          File$ = PeekS(*m_szFile) 
        EndIf 
        FreeMemory(*m_szFile) 
      EndIf 
      ReleaseStgMedium_(@medium) 
      If uCount=1 
        ProcedureReturn #S_OK 
      EndIf 
    EndIf 
  EndIf 
  ProcedureReturn #S_FALSE 
EndProcedure 

#MIIM_ID = 2 
#MIIM_STRING = $40 
#MF_STRING = 0 
#MFT_STRING = #MF_STRING 
#CMF_DEFAULTONLY = 1 

Procedure IContextMenu_QueryContextMenu(*i_icm.IContextMenu, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags) 
  If #CMF_DEFAULTONLY&uFlags:ProcedureReturn 0:EndIf 
  cmd = indexMenu 
  mii.MENUITEMINFO 
  mii\cbSize = SizeOf(MENUITEMINFO) 
  mii\fMask = #MIIM_STRING|#MIIM_ID 
  mii\fType = #MFT_STRING 
  mii\wID = idCmdFirst 
  mii\dwTypeData = ?CommandString 
  If InsertMenuItem_(hmenu, 0, #True, @mii)=#False 
    ProcedureReturn 1<<31 
  EndIf 
  ProcedureReturn 1 
EndProcedure 

Enumeration 
  #GCS_VERBA 
  #GCS_HELPTEXTA 
  #GCS_VALIDATEA 
  #GCS_VERBW 
  #GCS_HELPTEXTW 
  #GCS_VALIDATEW 
EndEnumeration 
#GCS_UNICODE = 4 
#GCS_VERB = #GCS_VERBA 
#GCS_HELPTEXT = #GCS_HELPTEXTA 
#GCS_VALIDATE = #GCS_VALIDATEA 

Procedure IContextMenu_GetCommandString(*ti_icm.IContextMenu, idCmd, uFlags, pwReserved, pszName, cchMax) 
  If idCmd=cmd 
    Select uFlags 
      Case #GCS_HELPTEXTA ; Sets pszName To an ANSI string containing the Help text For the command. 
        CopyMemory(?CommandHelpLine, pszName, Len(PeekS(?CommandHelpLine))) 
      Case #GCS_HELPTEXTW ; Sets pszName To a Unicode string containing the Help text For the command. 
        If Ansi2Uni1(?CommandHelpLine, pszName, cchMax)=0 
          ProcedureReturn #S_FALSE 
        EndIf 
      Case #GCS_VALIDATEA ; Returns S_OK If the menu item exists, Or S_FALSE otherwise. 
        ProcedureReturn #S_OK 
      Case #GCS_VALIDATEW ; Returns S_OK If the menu item exists, Or S_FALSE otherwise. 
        ProcedureReturn #S_OK 
      Case #GCS_VERBA ; Sets pszName To an ANSI string containing the language-independent command name For the menu item. 
        PokeS(pszName, PeekS(?CommandString)) 
      Case #GCS_VERBW ; Sets pszName To a Unicode string containing the language-independent command name For the menu item. 
        If Ansi2Uni1(?CommandString, pszName, cchMax)=0 
          ProcedureReturn #S_FALSE 
        EndIf 
      Default 
        ProcedureReturn #S_FALSE 
    EndSelect 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
  ProcedureReturn #S_OK 
EndProcedure 

Structure CMINVOKECOMMANDINFO 
cbSize.l 
fMask.l 
hwnd.l 
lpVerb.l 
lpParameters.l 
lpDirectory.l 
nShow.l 
dwHotKey.l 
hIcon.l 
EndStructure 

Structure CMINVOKECOMMANDINFOEX Extends CMINVOKECOMMANDINFO 
lpTitle.l 
lpVerbW.l 
lpParametersW.l 
lpDirectoryW.l 
lpTitleW.l 
ptInvoke.POINT 
EndStructure 

#SEE_MASK_UNICODE = $4000 
#CMIC_MASK_UNICODE = #SEE_MASK_UNICODE 

Procedure IContextMenu_InvokeCommand(*ti_icm.IContextMenu, *pici.CMINVOKECOMMANDINFOEX) 
  If *pici\cbSize=SizeOf(CMINVOKECOMMANDINFOEX) 
    If *pici\fMask&#CMIC_MASK_UNICODE 
      If (*pici\lpVerbW&$ffff)=cmd 
        MessageRequester("Show file name", File$) 
        ProcedureReturn #NOERROR 
      EndIf 
    EndIf 
  ElseIf *pici\cbSize=SizeOf(CMINVOKECOMMANDINFO) 
    If (*pici\lpVerb&$ffff)=cmd 
      MessageRequester("Show file name", File$) 
      ProcedureReturn #NOERROR 
    EndIf 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
EndProcedure 

#SELFREG_E_FIRST = $80009E40 
#SELFREG_E_CLASS = #SELFREG_E_FIRST+1 

#GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4 

ProcedureDLL DllRegisterServer() 
  InDLL: 
  If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "*\shellex\ContextMenuHandlers\FastView.Image", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  RegSetValueEx_(hKey1, "", 0, #REG_SZ, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 38) 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "FastView.Image\shellex\ContextMenuHandlers", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  RegSetValueEx_(hKey1, "", 0, #REG_SZ, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 38) 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegCreateKeyEx_(#HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  RegSetValueEx_(hKey1, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 0, #REG_SZ, "FastView.Image", 15) 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  *szBuffer = AllocateMemory(#MAX_PATH) 
  If *szBuffer And GetModuleFileName_(?InDLL&$FFFF0000, *szBuffer, #MAX_PATH) 
    If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "CLSID\{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
    RegSetValueEx_(hKey1, "", 0, #REG_SZ, "FastView.Image", 15) 
    If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
    If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "CLSID\{851aab5c-2008-4157-9c5d-a28dfa7b2660}\InProcServer32", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
    RegSetValueEx_(hKey1, "", 0, #REG_SZ, *szBuffer, Len(PeekS(*szBuffer))+1) 
    RegSetValueEx_(hKey1, "ThreadingModel", 0, #REG_SZ, "Apartment", 10) 
    If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  Else 
    ProcedureReturn #SELFREG_E_CLASS 
  EndIf 
  FreeMemory(*szBuffer) 
  ProcedureReturn #S_OK 
EndProcedure 

ProcedureDLL DllUnregisterServer() 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "*\shellex\ContextMenuHandlers\FastView.Image")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "FastView.Image\shellex\ContextMenuHandlers")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "FastView.Image\shellex")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "FastView.Image")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegOpenKeyEx_(#HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", 0, #KEY_ALL_ACCESS, @hKey1)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  If RegDeleteValue_(hKey1, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegOpenKeyEx_(#HKEY_CLASSES_ROOT, "CLSID\{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 0, #KEY_ALL_ACCESS, @hKey1)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  If RegDeleteKey_(hKey1, "InProcServer32")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegOpenKeyEx_(#HKEY_CLASSES_ROOT, "CLSID", 0, #KEY_ALL_ACCESS, @hKey1)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  If RegDeleteKey_(hKey1, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  ProcedureReturn #S_OK 
EndProcedure 

ProcedureDLL AttachProcess(Instance) 
  DisableThreadLibraryCalls_(Instance) 
  hModule = Instance 
  i_QCM = ?lpVT_IContextMenu 
  i_SEI = ?lpVT_IShellExtInit 
  i_Unk = ?lpVT_IUnknown 
  *p_Unk = ?lpVT_IUnknown 
  ProcedureReturn #True 
EndProcedure 

ProcedureDLL DllGetClassObject(*rclsid.GUID, *riid.GUID, *ppv.LONG) 
  If *ppv 
    If CompareMemory(*rclsid, ?CLSID_ContextMenuHandler, SizeOf(GUID)) 
      If CompareMemory(*riid, ?IID_IClassFactory, SizeOf(GUID)) 
        *ppv\l = ?lpVT_IClassFactory 
      Else 
        *ppv\l = 0 
        ProcedureReturn #CLASS_E_CLASSNOTAVAILABLE 
      EndIf 
    Else 
      *ppv\l = 0 
      ProcedureReturn #CLASS_E_CLASSNOTAVAILABLE 
    EndIf 
  Else 
    *ppv\l = 0 
    ProcedureReturn #CLASS_E_CLASSNOTAVAILABLE 
  EndIf 
  ProcedureReturn #S_OK 
EndProcedure 

ProcedureDLL DllCanUnloadNow() 
  If *p_Unk\nRefCount<=0 And *p_Unk\nLockCount<=0 
    ProcedureReturn #S_OK 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
EndProcedure 

DataSection 
  lpVT_IUnknown: 
    Data.l ?VT_IUnknown, 0, 0 
  VT_IUnknown: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
  lpVT_IClassFactory: 
    Data.l ?VT_IClassFactory 
  VT_IClassFactory: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
    Data.l @IClassFactory_CreateInstance(), @IClassFactory_LockServer() 
  lpVT_IShellExtInit: 
    Data.l ?VT_IShellExtInit 
  VT_IShellExtInit: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
    Data.l @IShellExtInit_Initialize() 
  lpVT_IContextMenu: 
    Data.l ?VT_IContextMenu 
  VT_IContextMenu: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
    Data.l @IContextMenu_QueryContextMenu() 
    Data.l @IContextMenu_InvokeCommand() 
    Data.l @IContextMenu_GetCommandString() 
EndDataSection 

DataSection ; 
  CLSID_ContextMenuHandler: ; {851aab5c-2008-4157-9c5d-a28dfa7b2660} 
  Data.l $851aab5c 
  Data.w $2008, $4157 
  Data.b $9c, $5d, $a2, $8d, $fa, $7b, $26, $60 
  IID_IUnknown: 
  Data.l $00000000 
  Data.w $0000, $0000 
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46 
  IID_IClassFactory: 
  Data.l $00000001 
  Data.w $0, $0 
  Data.b $C0, $0, $0, $0, $0, $0, $0, $46 
  IID_IShellExtInit: 
  Data.l $000214E8 
  Data.w 0, 0 
  Data.b $C0, 0, 0, 0, 0, 0, 0, $46 
  IID_IContextMenu: 
  Data.l $000214E4 
  Data.w 0, 0 
  Data.b $C0, 0, 0, 0, 0, 0, 0, $46 
  CommandString: 
  Data.s "Show file name" 
  CommandHelpLine: 
  Data.s "Shows the file name" 
EndDataSection

0

2

И еще что касается контекстного меню:

Пример kvitaliy у меня создает меню, но ни в какую не хочет его удалять.

Я скомпилил библиотеку для более удобного создания контекстного меню через командную строку:

Скачать

Поместить в папку с пуриком, у меня:   PureBasic\PureLibraries\UserLibraries

Прошу при случае потестить.

Пример ее использования:

Код:
Procedure Open_Window_0()
  If OpenWindow(0, 224, 4, 297, 169, "New window ( 0 )",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
 
      ButtonGadget(0, 45, 15, 205, 40, "Удалить меню")
      ButtonGadget(1, 45, 95, 205, 45, "Создать меню")
      

  EndIf
EndProcedure

Open_Window_0()

Repeat

  ev=WaitWindowEvent()
  
  If ev=#PB_Event_Gadget
  
    If EventGadget()=0
       DELETE_KONTEXT("МОЕ МЕНЮ")
    ElseIf EventGadget()=1
       KONTEXT_MENU_CREATE("МОЕ МЕНЮ","PROGA.exe")  ;устанавливать  меню  из нужной папки.
    EndIf                                         
                                                     
  EndIf
  
       
  
Until ev=#PB_Event_CloseWindow

Отредактировано haav (02.03.2010 18:47:47)

0

3

Я давно уже подправил верхний код для множественного выбора файлов, но он так мне и не пригодился. Может кому понадобится. Все тоже самое:

Установка скомпилировать DLL и запустить регистрацию из командной строки (для win7 запускать CMD под админом):

1) C:\WINDOWS\system32\regsvr32  C:\PathToMyDLL\MY.dll          установка

2) C:\WINDOWS\system32\regsvr32 /u  C:\PathToMyDLL\MY.dll       удаление


В массив GLINDEX_S ,  записываются имена файлов . Я сделал размер массива на 101 файл, если нужно больше, поменяете. Вывод в примере идет в messagebox.

Код:
;1) C:\WINDOWS\system32\regsvr32  C:\PathToMyDLL\MY.dll          ?????????

;2) C:\WINDOWS\system32\regsvr32 /u  C:\PathToMyDLL\MY.dll                  ????????

Procedure Error(message$) 
  wError = GetLastError_() 
  If wError 
    *ErrorBuffer = AllocateMemory(1024) 
    FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, wError, 0, *ErrorBuffer, 1024, 0) 
    message$+Chr(10)+PeekS(*ErrorBuffer) 
    FreeMemory(*ErrorBuffer) 
  EndIf 
  MessageRequester("Error", message$) 
EndProcedure 

Structure ClassFactoryObject 
  lpVtbl.l 
  nRefCount.l 
  nLockCount.l 
EndStructure 

Global m_pDataObj.IDataObject, cmd, hModule 
Global i_Unk.IUnknown, i_SEI.IShellExtInit, i_QCM.IContextMenu 
Global *p_Unk.ClassFactoryObject 
Global File$
Global GLINDEX_9.l
Global Dim GLINDEX_S.s(100)

Procedure Ansi2Uni1(*st, *Buffer, blen) 
  If Len(PeekS(*st))<blen 
    ProcedureReturn MultiByteToWideChar_(#CP_ACP, 0, *st, -1, *Buffer, blen) 
  Else 
    ProcedureReturn 0 
  EndIf 
EndProcedure 

Procedure IUnknown_QueryInterface(*ti_unk.IUnknown, *riid.GUID, *ppvObject.LONG) 
  If *ppvObject 
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(GUID)) 
      MessageRequester("", "iunknown") 
      *ppvObject\l = i_Unk 
    ElseIf CompareMemory(*riid, ?IID_IShellExtInit, SizeOf(GUID)) 
      *ppvObject\l = i_SEI 
    ElseIf CompareMemory(*riid, ?IID_IContextMenu, SizeOf(GUID)) 
      *ppvObject\l = i_QCM 
    Else 
      ProcedureReturn #E_NOINTERFACE 
    EndIf 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
  i_Unk\AddRef() 
  ProcedureReturn #S_OK 
EndProcedure 

Procedure IUnknown_AddRef(*ti_unk.IUnknown):*p_Unk\nRefCount+1:ProcedureReturn *p_Unk\nRefCount:EndProcedure 

Procedure IUnknown_Release(*ti_unk.IUnknown):*p_Unk\nRefCount-1:ProcedureReturn *p_Unk\nRefCount:EndProcedure 

Procedure IClassFactory_CreateInstance(*ti_cf.IClassFactory, *pUnkOuter.IUnknown, *riid.GUID, *ppvObject) 
  If *pUnkOuter 
    ProcedureReturn #CLASS_E_NOAGGREGATION 
  Else 
    If i_SEI=#Null 
      ProcedureReturn #E_OUTOFMEMORY 
    Else 
      hr = i_SEI\QueryInterface(*riid, *ppvObject) 
    EndIf 
  EndIf 
  ProcedureReturn hr 
EndProcedure 

Procedure IClassFactory_LockServer(*ti_cf.IClassFactory, fLock) 
  ProcedureReturn #E_FAIL 
EndProcedure 

#CF_HDROP = $0f 
#DVASPECT_CONTENT = 1 
#TYMED_HGLOBAL = 1 
#TYMED_FILE = 2 

Procedure IShellExtInit_Initialize(*ti_sei.IShellExtInit, *pidlFolder.ITEMIDLIST, *pdtobj.IDataObject, hkeyProgID) 
  If m_pDataObj 
    m_pDataObj\Release() 
  EndIf 
  If *pdtobj 
    m_pDataObj = *pdtobj 
    *pdtobj\AddRef() 
    fe.FORMATETC\cfFormat = #CF_HDROP 
    fe\ptd = #Null 
    fe\dwAspect = #DVASPECT_CONTENT 
    fe\lindex = -1 
    fe\tymed = #TYMED_HGLOBAL 
    If *pdtobj\GetData(@fe, @medium.STGMEDIUM)=#S_OK 
      uCount = DragQueryFile_(medium\hGlobal, -1, #Null, 0) 
      GLINDEX_9=uCount
      If uCount>=1
        For dd=0 To uCount-1
        *m_szFile = AllocateMemory(#MAX_PATH) 
        DragQueryFile_(medium\hGlobal, dd, *m_szFile, #MAX_PATH) 
        If Len(PeekS(*m_szFile))=0 
          uCount = 0 
        Else 
          GLINDEX_S(dd) = PeekS(*m_szFile) 
        EndIf 
        FreeMemory(*m_szFile) 
        Next
      EndIf 
      ReleaseStgMedium_(@medium) 
      If uCount>=1 
        ProcedureReturn #S_OK 
      EndIf 
    EndIf 
  EndIf 
  ProcedureReturn #S_FALSE 
EndProcedure 

#MIIM_ID = 2 
#MIIM_STRING = $40 
#MF_STRING = 0 
#MFT_STRING = #MF_STRING 
#CMF_DEFAULTONLY = 1 

Procedure IContextMenu_QueryContextMenu(*i_icm.IContextMenu, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags) 
  If #CMF_DEFAULTONLY&uFlags:ProcedureReturn 0:EndIf 
  cmd = indexMenu 
  mii.MENUITEMINFO 
  mii\cbSize = SizeOf(MENUITEMINFO) 
  mii\fMask = #MIIM_STRING|#MIIM_ID 
  mii\fType = #MFT_STRING 
  mii\wID = idCmdFirst 
  mii\dwTypeData = ?CommandString 
  If InsertMenuItem_(hmenu, 0, #True, @mii)=#False 
    ProcedureReturn 1<<31 
  EndIf 
  ProcedureReturn 1 
EndProcedure 

Enumeration 
  #GCS_VERBA 
  #GCS_HELPTEXTA 
  #GCS_VALIDATEA 
  #GCS_VERBW 
  #GCS_HELPTEXTW 
  #GCS_VALIDATEW 
EndEnumeration 
#GCS_UNICODE = 4 
#GCS_VERB = #GCS_VERBA 
#GCS_HELPTEXT = #GCS_HELPTEXTA 
#GCS_VALIDATE = #GCS_VALIDATEA 

Procedure IContextMenu_GetCommandString(*ti_icm.IContextMenu, idCmd, uFlags, pwReserved, pszName, cchMax) 
  If idCmd=cmd 
    Select uFlags 
      Case #GCS_HELPTEXTA ; Sets pszName To an ANSI string containing the Help text For the command. 
        CopyMemory(?CommandHelpLine, pszName, Len(PeekS(?CommandHelpLine))) 
      Case #GCS_HELPTEXTW ; Sets pszName To a Unicode string containing the Help text For the command. 
        If Ansi2Uni1(?CommandHelpLine, pszName, cchMax)=0 
          ProcedureReturn #S_FALSE 
        EndIf 
      Case #GCS_VALIDATEA ; Returns S_OK If the menu item exists, Or S_FALSE otherwise. 
        ProcedureReturn #S_OK 
      Case #GCS_VALIDATEW ; Returns S_OK If the menu item exists, Or S_FALSE otherwise. 
        ProcedureReturn #S_OK 
      Case #GCS_VERBA ; Sets pszName To an ANSI string containing the language-independent command name For the menu item. 
        PokeS(pszName, PeekS(?CommandString)) 
      Case #GCS_VERBW ; Sets pszName To a Unicode string containing the language-independent command name For the menu item. 
        If Ansi2Uni1(?CommandString, pszName, cchMax)=0 
          ProcedureReturn #S_FALSE 
        EndIf 
      Default 
        ProcedureReturn #S_FALSE 
    EndSelect 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
  ProcedureReturn #S_OK 
EndProcedure 

Structure CMINVOKECOMMANDINFO 
cbSize.l 
fMask.l 
hwnd.l 
lpVerb.l 
lpParameters.l 
lpDirectory.l 
nShow.l 
dwHotKey.l 
hIcon.l 
EndStructure 

Structure CMINVOKECOMMANDINFOEX Extends CMINVOKECOMMANDINFO 
lpTitle.l 
lpVerbW.l 
lpParametersW.l 
lpDirectoryW.l 
lpTitleW.l 
ptInvoke.POINT 
EndStructure 

#SEE_MASK_UNICODE = $4000 
#CMIC_MASK_UNICODE = #SEE_MASK_UNICODE 

Procedure IContextMenu_InvokeCommand(*ti_icm.IContextMenu, *pici.CMINVOKECOMMANDINFOEX) 
  If *pici\cbSize=SizeOf(CMINVOKECOMMANDINFOEX) 
    If *pici\fMask&#CMIC_MASK_UNICODE 
      If (*pici\lpVerbW&$ffff)=cmd 
        For dd=0 To GLINDEX_9-1
          inputstring.s = inputstring.s + GLINDEX_S(dd) + Chr(10)
        Next 
        MessageRequester(Str(dd),inputstring.s)
        ProcedureReturn #NOERROR 
      EndIf 
    EndIf 
  ElseIf *pici\cbSize=SizeOf(CMINVOKECOMMANDINFO) 
    If (*pici\lpVerb&$ffff)=cmd 
      For dd=0 To GLINDEX_9-1
        inputstring.s = inputstring.s + GLINDEX_S(dd) + Chr(10)
       Next 
        MessageRequester(Str(dd),inputstring.s)
      ProcedureReturn #NOERROR 
    EndIf 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
EndProcedure 

#SELFREG_E_FIRST = $80009E40 
#SELFREG_E_CLASS = #SELFREG_E_FIRST+1 

#GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4 

ProcedureDLL DllRegisterServer() 
  InDLL: 
  If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "*\shellex\ContextMenuHandlers\FastView.Image", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  RegSetValueEx_(hKey1, "", 0, #REG_SZ, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 38) 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "FastView.Image\shellex\ContextMenuHandlers", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  RegSetValueEx_(hKey1, "", 0, #REG_SZ, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 38) 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegCreateKeyEx_(#HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  RegSetValueEx_(hKey1, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 0, #REG_SZ, "FastView.Image", 15) 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  *szBuffer = AllocateMemory(#MAX_PATH) 
  If *szBuffer And GetModuleFileName_(?InDLL&$FFFF0000, *szBuffer, #MAX_PATH) 
    If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "CLSID\{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
    RegSetValueEx_(hKey1, "", 0, #REG_SZ, "FastView.Image", 15) 
    If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
    If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "CLSID\{851aab5c-2008-4157-9c5d-a28dfa7b2660}\InProcServer32", 0, 0, #REG_OPTION_NON_VOLATILE, #KEY_ALL_ACCESS, #Null, @hKey1, 0)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
    RegSetValueEx_(hKey1, "", 0, #REG_SZ, *szBuffer, Len(PeekS(*szBuffer))+1) 
    RegSetValueEx_(hKey1, "ThreadingModel", 0, #REG_SZ, "Apartment", 10) 
    If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  Else 
    ProcedureReturn #SELFREG_E_CLASS 
  EndIf 
  FreeMemory(*szBuffer) 
  ProcedureReturn #S_OK 
EndProcedure 

ProcedureDLL DllUnregisterServer() 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "*\shellex\ContextMenuHandlers\FastView.Image")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "FastView.Image\shellex\ContextMenuHandlers")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "FastView.Image\shellex")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegDeleteKey_(#HKEY_CLASSES_ROOT, "FastView.Image")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If RegOpenKeyEx_(#HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", 0, #KEY_ALL_ACCESS, @hKey1)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  If RegDeleteValue_(hKey1, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegOpenKeyEx_(#HKEY_CLASSES_ROOT, "CLSID\{851aab5c-2008-4157-9c5d-a28dfa7b2660}", 0, #KEY_ALL_ACCESS, @hKey1)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  If RegDeleteKey_(hKey1, "InProcServer32")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  If RegOpenKeyEx_(#HKEY_CLASSES_ROOT, "CLSID", 0, #KEY_ALL_ACCESS, @hKey1)<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS:EndIf 
  If RegDeleteKey_(hKey1, "{851aab5c-2008-4157-9c5d-a28dfa7b2660}")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf 
  If hKey1:RegCloseKey_(hKey1):hKey1 = 0:EndIf 
  ProcedureReturn #S_OK 
EndProcedure 

ProcedureDLL AttachProcess(Instance) 
  DisableThreadLibraryCalls_(Instance) 
  hModule = Instance 
  i_QCM = ?lpVT_IContextMenu 
  i_SEI = ?lpVT_IShellExtInit 
  i_Unk = ?lpVT_IUnknown 
  *p_Unk = ?lpVT_IUnknown 
  ProcedureReturn #True 
EndProcedure 

ProcedureDLL DllGetClassObject(*rclsid.GUID, *riid.GUID, *ppv.LONG) 
  If *ppv 
    If CompareMemory(*rclsid, ?CLSID_ContextMenuHandler, SizeOf(GUID)) 
      If CompareMemory(*riid, ?IID_IClassFactory, SizeOf(GUID)) 
        *ppv\l = ?lpVT_IClassFactory 
      Else 
        *ppv\l = 0 
        ProcedureReturn #CLASS_E_CLASSNOTAVAILABLE 
      EndIf 
    Else 
      *ppv\l = 0 
      ProcedureReturn #CLASS_E_CLASSNOTAVAILABLE 
    EndIf 
  Else 
    *ppv\l = 0 
    ProcedureReturn #CLASS_E_CLASSNOTAVAILABLE 
  EndIf 
  ProcedureReturn #S_OK 
EndProcedure 

ProcedureDLL DllCanUnloadNow() 
  If *p_Unk\nRefCount<=0 And *p_Unk\nLockCount<=0 
    ProcedureReturn #S_OK 
  Else 
    ProcedureReturn #S_FALSE 
  EndIf 
EndProcedure 

DataSection 
  lpVT_IUnknown: 
    Data.l ?VT_IUnknown, 0, 0 
  VT_IUnknown: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
  lpVT_IClassFactory: 
    Data.l ?VT_IClassFactory 
  VT_IClassFactory: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
    Data.l @IClassFactory_CreateInstance(), @IClassFactory_LockServer() 
  lpVT_IShellExtInit: 
    Data.l ?VT_IShellExtInit 
  VT_IShellExtInit: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
    Data.l @IShellExtInit_Initialize() 
  lpVT_IContextMenu: 
    Data.l ?VT_IContextMenu 
  VT_IContextMenu: 
    Data.l @IUnknown_QueryInterface(), @IUnknown_AddRef(), @IUnknown_Release() 
    Data.l @IContextMenu_QueryContextMenu() 
    Data.l @IContextMenu_InvokeCommand() 
    Data.l @IContextMenu_GetCommandString() 
EndDataSection 

DataSection ; 
  CLSID_ContextMenuHandler: ; {851aab5c-2008-4157-9c5d-a28dfa7b2660} 
  Data.l $851aab5c 
  Data.w $2008, $4157 
  Data.b $9c, $5d, $a2, $8d, $fa, $7b, $26, $60 
  IID_IUnknown: 
  Data.l $00000000 
  Data.w $0000, $0000 
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46 
  IID_IClassFactory: 
  Data.l $00000001 
  Data.w $0, $0 
  Data.b $C0, $0, $0, $0, $0, $0, $0, $46 
  IID_IShellExtInit: 
  Data.l $000214E8 
  Data.w 0, 0 
  Data.b $C0, 0, 0, 0, 0, 0, 0, $46 
  IID_IContextMenu: 
  Data.l $000214E4 
  Data.w 0, 0 
  Data.b $C0, 0, 0, 0, 0, 0, 0, $46 
  CommandString: 
  Data.s "Show file name" 
  CommandHelpLine: 
  Data.s "Shows the file name" 
EndDataSection

0


Вы здесь » PureBasic - форум » Программирование на PureBasic » Контекстное меню проводника