你的意思是要监控windows的资源管理器?

解决方案 »

  1.   

    ;
    ; 资源管理器上下文菜单扩展 

    ;; Usage:
    ;   To use it, you must build this source As a DLL And put the DLL in some known 
    ;   place (Not in C:\Windows\Temp Wink, so you remember where it is when you want 
    ;   To unregister it.
    ;
    ;   But you must register it first, With this DOS command:
    ;     C:\WINDOWS\system32>regsvr32 C:\PathToMyDLL\mydll.dll
    ;
    ;   To unregister it:
    ;     C:\WINDOWS\system32>regsvr32 /u C:\PathToMyDLL\mydll.dll
    ;
    ;
    ;   Then launch an explorer window And right click on any file. The context menu 
    ;   should show a "View file name" item which, If selected, should show "Shows the 
    ;   file name" in the status bar. If clicked, a MessageRequester should appear With 
    ;   the name of the right-clicked file. ; Try compiling the dll with debugging support enabled, and you can track all
    ; object use with a debugger like DebugView (http://www.sysinternals.com/Utilities/DebugView.html)
    ;
    EnableCOMDebuggingGlobal ExistingObjectCount
    Global hModuleCOMClass(ShellMenuObject)
      COMInterface(ShellMenuObject, IClassFactory)
      COMInterface(ShellMenuObject, IShellExtInit)
      COMInterface(ShellMenuObject, IContextMenu)
      
      COMClassData(ShellMenuObject)
        nLockCount.l
        m_pDataObj.IDataObject
        File$
      EndCOMClassData
        
      COMConstructor(ShellMenuObject)
        ExistingObjectCount + 1            ; used to know if the dll can be unloaded
        COMConstructorReturn IClassFactory ; return IClassFactory from the constructor
      EndCOMConstructor
      
      COMDestructor(ShellMenuObject)
        ExistingObjectCount - 1
      EndCOMDestructor
      
    EndCOMClass(ShellMenuObject, IClassFactory, IShellExtInit, IContextMenu)DefineCLSID(CLSID_ContextMenuHandler, $851aab5c, $2008, $4157, $9c, $5d, $a2, $8d, $fa, $7b, $26, $60)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$)
    EndProcedureProcedure Ansi2Uni(*st, *Buffer, blen)
      If Len(PeekS(*st))<blen
        ProcedureReturn MultiByteToWideChar_(#CP_ACP, 0, *st, -1, *Buffer, blen)
      Else
        ProcedureReturn 0
      EndIf
    EndProcedure
    #CMF_DEFAULTONLY = 1Enumeration
      #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_VALIDATEAStructure CMINVOKECOMMANDINFO
     cbSize.l
     fMask.l
     hwnd.l
     lpVerb.l
     lpParameters.l
     lpDirectory.l
     nShow.l
     dwHotKey.l
     hIcon.l
    EndStructureStructure 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#SELFREG_E_FIRST = $80009E40
    #SELFREG_E_CLASS = #SELFREG_E_FIRST+1#GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4
    Procedure ShellMenuObject_IClassFactory_CreateInstance(*THIS.ShellMenuObject, *pUnkOuter.IUnknown, *riid.GUID, *ppvObject) COMMethodOf(ShellMenuObject)
      If *pUnkOuter
        ProcedureReturn #CLASS_E_NOAGGREGATION
      Else
        IUnknown.IUnknown = *THIS
        ProcedureReturn IUnknown\QueryInterface(*riid, *ppvObject)
      EndIf
      ProcedureReturn hr
    EndProcedure
    ; Procedure ShellMenuObject_IClassFactory_LockServer(*THIS.ShellMenuObject, fLock) MethodOf(ShellMenuObject)
    ;   ProcedureReturn #E_FAIL
    ; EndProcedure; The above empty method can be implemented with this single macro:
    ;
    COMEmptyMethod(ShellMenuObject, IClassFactory, LockServer, #E_FAIL)
      

  2.   

    ;
    ; 资源管理器上下文菜单扩展 

    ;; Usage:
    ;   To use it, you must build this source As a DLL And put the DLL in some known 
    ;   place (Not in C:\Windows\Temp Wink, so you remember where it is when you want 
    ;   To unregister it.
    ;
    ;   But you must register it first, With this DOS command:
    ;     C:\WINDOWS\system32>regsvr32 C:\PathToMyDLL\mydll.dll
    ;
    ;   To unregister it:
    ;     C:\WINDOWS\system32>regsvr32 /u C:\PathToMyDLL\mydll.dll
    ;
    ;
    ;   Then launch an explorer window And right click on any file. The context menu 
    ;   should show a "View file name" item which, If selected, should show "Shows the 
    ;   file name" in the status bar. If clicked, a MessageRequester should appear With 
    ;   the name of the right-clicked file. ; Try compiling the dll with debugging support enabled, and you can track all
    ; object use with a debugger like DebugView (http://www.sysinternals.com/Utilities/DebugView.html)
    ;
    EnableCOMDebuggingGlobal ExistingObjectCount
    Global hModuleCOMClass(ShellMenuObject)
      COMInterface(ShellMenuObject, IClassFactory)
      COMInterface(ShellMenuObject, IShellExtInit)
      COMInterface(ShellMenuObject, IContextMenu)
      
      COMClassData(ShellMenuObject)
        nLockCount.l
        m_pDataObj.IDataObject
        File$
      EndCOMClassData
        
      COMConstructor(ShellMenuObject)
        ExistingObjectCount + 1            ; used to know if the dll can be unloaded
        COMConstructorReturn IClassFactory ; return IClassFactory from the constructor
      EndCOMConstructor
      
      COMDestructor(ShellMenuObject)
        ExistingObjectCount - 1
      EndCOMDestructor
      
    EndCOMClass(ShellMenuObject, IClassFactory, IShellExtInit, IContextMenu)DefineCLSID(CLSID_ContextMenuHandler, $851aab5c, $2008, $4157, $9c, $5d, $a2, $8d, $fa, $7b, $26, $60)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$)
    EndProcedureProcedure Ansi2Uni(*st, *Buffer, blen)
      If Len(PeekS(*st))<blen
        ProcedureReturn MultiByteToWideChar_(#CP_ACP, 0, *st, -1, *Buffer, blen)
      Else
        ProcedureReturn 0
      EndIf
    EndProcedure
    #CMF_DEFAULTONLY = 1Enumeration
      #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_VALIDATEAStructure CMINVOKECOMMANDINFO
     cbSize.l
     fMask.l
     hwnd.l
     lpVerb.l
     lpParameters.l
     lpDirectory.l
     nShow.l
     dwHotKey.l
     hIcon.l
    EndStructureStructure 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#SELFREG_E_FIRST = $80009E40
    #SELFREG_E_CLASS = #SELFREG_E_FIRST+1#GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4
    Procedure ShellMenuObject_IClassFactory_CreateInstance(*THIS.ShellMenuObject, *pUnkOuter.IUnknown, *riid.GUID, *ppvObject) COMMethodOf(ShellMenuObject)
      If *pUnkOuter
        ProcedureReturn #CLASS_E_NOAGGREGATION
      Else
        IUnknown.IUnknown = *THIS
        ProcedureReturn IUnknown\QueryInterface(*riid, *ppvObject)
      EndIf
      ProcedureReturn hr
    EndProcedure
    ; Procedure ShellMenuObject_IClassFactory_LockServer(*THIS.ShellMenuObject, fLock) MethodOf(ShellMenuObject)
    ;   ProcedureReturn #E_FAIL
    ; EndProcedure; The above empty method can be implemented with this single macro:
    ;
    COMEmptyMethod(ShellMenuObject, IClassFactory, LockServer, #E_FAIL)
      

  3.   

    ;
    ; PropertyPage Shell Extension dll example
    ;   Adds a new page to the properties displayed for drives in the explorer.
    ;; Usage:
    ;   To use it, you must build this source As a DLL And put the DLL in some known 
    ;   place (Not in C:\Windows\Temp Wink, so you remember where it is when you want 
    ;   To unregister it.
    ;
    ;   But you must register it first, With this DOS command:
    ;     C:\WINDOWS\system32>regsvr32 C:\PathToMyDLL\mydll.dll
    ;
    ;   To unregister it:
    ;     C:\WINDOWS\system32>regsvr32 /u C:\PathToMyDLL\mydll.dll
    ;
    ;
    ;   Then launch an explorer window And right click on a drive and select 'Properties'
    ;   There should be an extra empty page in the Properties called "Example Property Page"; Try compiling the dll with debugging support enabled, and you can track all
    ; object use with a debugger like DebugView (http://www.sysinternals.com/Utilities/DebugView.html)
    ;; Compile the dll with com debugging support enabled, and you can track all
    ; object use with a debugger like DebugView (http://www.sysinternals.com/Utilities/DebugView.html)
    ;
    EnableCOMDebugging; for the unload function 
    Global TotalObjectCount, DllInstanceCOMClass(PropertySheet)
      COMInterface(PropertySheet, IClassFactory)
      COMInterface(PropertySheet, IShellExtInit)
      COMInterface(PropertySheet, IShellPropSheetExt)   
      
      COMClassData(PropertySheet)
        Directory$     
        Thread.l
      EndCOMClassData  
      
      COMConstructor(PropertySheet)    
        TotalObjectCount + 1
        COMConstructorReturn IClassFactory
      EndCOMConstructor
      
      COMDestructor(PropertySheet)
        TotalObjectCount - 1
      EndCOMDestructor
    EndCOMClass(PropertySheet, IClassFactory, IShellExtInit, IShellPropSheetExt)
    #CLSID_MyPropertySheet = "{3b3dccdc-8263-4c16-8405-e1d58d6a5a46}"
    #MyPropertySheetName  = "PBTestPropertySheet.1"DefineCLSID(CLSID_MyPropertySheet, $3b3dccdc, $8263, $4c16, $84, $05, $e1, $d5, $8d, $6a, $5a, $46);- Method definitions
    ;
    Procedure PropertySheet_IClassFactory_CreateInstance(*THIS.PropertySheet, *pUnkOuter.IUnknown, *IID.GUID, *pObject.LONG) COMMethodOf(PropertySheet)
      Protected i
      Protected IUnknown.IUnknown = *THIS  If *pUnkOuter
        ProcedureReturn #CLASS_E_NOAGGREGATION
      Else
        ProcedureReturn IUnknown\QueryInterface(*IID, *pObject)
      EndIf
    EndProcedureCOMEmptyMethod(PropertySheet, IClassFactory, LockServer, #E_FAIL)Procedure PropertySheet_IShellExtInit_Initialize(*THIS.PropertySheet, *Folder.ITEMIDLIST, DataObject.IDataObject, hkeyProgID) COMMethodOf(PropertySheet)
      Protected Format.FORMATETC, Medium.STGMEDIUM
      Protected Result = #E_FAIL
      Protected Count, Length
      Protected init.INITCOMMONCONTROLSEX
      
      init\dwSize = SizeOf(INITCOMMONCONTROLSEX)
      init\dwICC  = #ICC_DATE_CLASSES|#ICC_STANDARD_CLASSES
      InitCommonControlsEx_(@init) ; must call this to avoid a crash when loading the dialog box
        
      
      ;
      ; NOTE: maybe implement the CFSTR_MOUNTEDVOLUME format to handle NTFS volumes
      ; mounted on a directory and not a driveletter
      ;
      
      If DataObject    
        Format\cfFormat = #CF_HDROP
        Format\ptd      = #Null
        Format\dwAspect = #DVASPECT_CONTENT
        Format\lindex   = -1
        Format\tymed    = #TYMED_HGLOBAL
        
        If DataObject\GetData(@Format, @Medium) = #S_OK
          Count = DragQueryFile_(Medium\hGlobal, $FFFFFFFF, #Null, 0)
          
          If Count = 1
            Length = DragQueryFile_(Medium\hGlobal, 0, #Null, 0)
            *THIS\Directory$ = Space(Length)
            DragQueryFile_(Medium\hGlobal, 0, @*THIS\Directory$, Length+1)    
            
            Result = #S_OK    
          EndIf      ReleaseStgMedium_(@Medium)
        EndIf    
      EndIf  ProcedureReturn Result
    EndProcedure
    Procedure PropertySheetPageProc(hWnd, uMsg, *page.PROPSHEETPAGE)
      Protected *THIS.PropertySheet = *page\lParam
      Protected ThisIUnknown.IUnknown = *page\lParam  Select uMsg
      
        Case #PSPCB_ADDREF:  OutputDebugString_("Page is being added") 
          ThisIUnknown\AddRef() ; prevent the dll/object from being destroyed while the page exists
        
        Case #PSPCB_CREATE:  OutputDebugString_("Dialog box is being created")
        
        Case #PSPCB_RELEASE: OutputDebugString_("Page is being destroyed")
          ThisIUnknown\Release() ; allow release of the dll/object
          
      EndSelect  ProcedureReturn #True
    EndProcedureMacro DialogReturn(Window, Value)
      SetWindowLong_(Window, #DWL_MSGRESULT, Value)
      ProcedureReturn #True
    EndMacro#NF_QUERY = 3
    #NF_REQUERY = 4
    #NFR_ANSI = 1
    #NFR_UNICODE = 2Procedure PropertySheetDialogProc(Window, Message, wParam, lParam)
      Protected *hdr.NMHDR  Select Message
      
        Case #WM_INITDIALOG    Case #WM_DESTROY    Case #WM_NOTIFY
          *hdr.NMHDR = lParam
          OutputDebugString_("WM_NOTIFY: code = "+Str(*hdr\code))
          
          If *hdr\code = #PSN_SETACTIVE
            DialogReturn(Window, 0) ; important to handle this, otherwise we get a crash!      
          EndIf      
      
      EndSelect
      
      ProcedureReturn #False
    EndProcedure; This is a dialog template for an empty dialog
    ;
    DataSection  Dialog:
        Data.w 1 ; DlgVer
        Data.w $FFFF ; extended dlg structure
        Data.l 0 ; helpID
        Data.l 0 ; exStyle  
        Data.l #WS_CHILD | #WS_VISIBLE  ; Style    
        Data.w 0 ; Nb of items in the dialog    
        Data.w 0 ; x
        Data.w 0 ; y
        Data.w 0 ; w
        Data.w 0 ; h
        Data.w 0 ; PADDING
        Data.w $0000 ; NO menu!
        Data.w 0 ; PADDING
        Data.w $0000 ; No windowClass    
        Data.w 0 ; PADDING
        Data.w $0000 ; NO title
        Data.w 0 ; PADDING
            
    EndDataSection
      

  4.   

    ;
    ; PropertyPage Shell Extension dll example
    ;   Adds a new page to the properties displayed for drives in the explorer.
    ;; Usage:
    ;   To use it, you must build this source As a DLL And put the DLL in some known 
    ;   place (Not in C:\Windows\Temp Wink, so you remember where it is when you want 
    ;   To unregister it.
    ;
    ;   But you must register it first, With this DOS command:
    ;     C:\WINDOWS\system32>regsvr32 C:\PathToMyDLL\mydll.dll
    ;
    ;   To unregister it:
    ;     C:\WINDOWS\system32>regsvr32 /u C:\PathToMyDLL\mydll.dll
    ;
    ;
    ;   Then launch an explorer window And right click on a drive and select 'Properties'
    ;   There should be an extra empty page in the Properties called "Example Property Page"; Try compiling the dll with debugging support enabled, and you can track all
    ; object use with a debugger like DebugView (http://www.sysinternals.com/Utilities/DebugView.html)
    ;; Compile the dll with com debugging support enabled, and you can track all
    ; object use with a debugger like DebugView (http://www.sysinternals.com/Utilities/DebugView.html)
    ;
    EnableCOMDebugging; for the unload function 
    Global TotalObjectCount, DllInstanceCOMClass(PropertySheet)
      COMInterface(PropertySheet, IClassFactory)
      COMInterface(PropertySheet, IShellExtInit)
      COMInterface(PropertySheet, IShellPropSheetExt)   
      
      COMClassData(PropertySheet)
        Directory$     
        Thread.l
      EndCOMClassData  
      
      COMConstructor(PropertySheet)    
        TotalObjectCount + 1
        COMConstructorReturn IClassFactory
      EndCOMConstructor
      
      COMDestructor(PropertySheet)
        TotalObjectCount - 1
      EndCOMDestructor
    EndCOMClass(PropertySheet, IClassFactory, IShellExtInit, IShellPropSheetExt)
    #CLSID_MyPropertySheet = "{3b3dccdc-8263-4c16-8405-e1d58d6a5a46}"
    #MyPropertySheetName  = "PBTestPropertySheet.1"DefineCLSID(CLSID_MyPropertySheet, $3b3dccdc, $8263, $4c16, $84, $05, $e1, $d5, $8d, $6a, $5a, $46);- Method definitions
    ;
    Procedure PropertySheet_IClassFactory_CreateInstance(*THIS.PropertySheet, *pUnkOuter.IUnknown, *IID.GUID, *pObject.LONG) COMMethodOf(PropertySheet)
      Protected i
      Protected IUnknown.IUnknown = *THIS  If *pUnkOuter
        ProcedureReturn #CLASS_E_NOAGGREGATION
      Else
        ProcedureReturn IUnknown\QueryInterface(*IID, *pObject)
      EndIf
    EndProcedureCOMEmptyMethod(PropertySheet, IClassFactory, LockServer, #E_FAIL)Procedure PropertySheet_IShellExtInit_Initialize(*THIS.PropertySheet, *Folder.ITEMIDLIST, DataObject.IDataObject, hkeyProgID) COMMethodOf(PropertySheet)
      Protected Format.FORMATETC, Medium.STGMEDIUM
      Protected Result = #E_FAIL
      Protected Count, Length
      Protected init.INITCOMMONCONTROLSEX
      
      init\dwSize = SizeOf(INITCOMMONCONTROLSEX)
      init\dwICC  = #ICC_DATE_CLASSES|#ICC_STANDARD_CLASSES
      InitCommonControlsEx_(@init) ; must call this to avoid a crash when loading the dialog box
        
      
      ;
      ; NOTE: maybe implement the CFSTR_MOUNTEDVOLUME format to handle NTFS volumes
      ; mounted on a directory and not a driveletter
      ;
      
      If DataObject    
        Format\cfFormat = #CF_HDROP
        Format\ptd      = #Null
        Format\dwAspect = #DVASPECT_CONTENT
        Format\lindex   = -1
        Format\tymed    = #TYMED_HGLOBAL
        
        If DataObject\GetData(@Format, @Medium) = #S_OK
          Count = DragQueryFile_(Medium\hGlobal, $FFFFFFFF, #Null, 0)
          
          If Count = 1
            Length = DragQueryFile_(Medium\hGlobal, 0, #Null, 0)
            *THIS\Directory$ = Space(Length)
            DragQueryFile_(Medium\hGlobal, 0, @*THIS\Directory$, Length+1)    
            
            Result = #S_OK    
          EndIf      ReleaseStgMedium_(@Medium)
        EndIf    
      EndIf  ProcedureReturn Result
    EndProcedure
    Procedure PropertySheetPageProc(hWnd, uMsg, *page.PROPSHEETPAGE)
      Protected *THIS.PropertySheet = *page\lParam
      Protected ThisIUnknown.IUnknown = *page\lParam  Select uMsg
      
        Case #PSPCB_ADDREF:  OutputDebugString_("Page is being added") 
          ThisIUnknown\AddRef() ; prevent the dll/object from being destroyed while the page exists
        
        Case #PSPCB_CREATE:  OutputDebugString_("Dialog box is being created")
        
        Case #PSPCB_RELEASE: OutputDebugString_("Page is being destroyed")
          ThisIUnknown\Release() ; allow release of the dll/object
          
      EndSelect  ProcedureReturn #True
    EndProcedureMacro DialogReturn(Window, Value)
      SetWindowLong_(Window, #DWL_MSGRESULT, Value)
      ProcedureReturn #True
    EndMacro#NF_QUERY = 3
    #NF_REQUERY = 4
    #NFR_ANSI = 1
    #NFR_UNICODE = 2Procedure PropertySheetDialogProc(Window, Message, wParam, lParam)
      Protected *hdr.NMHDR  Select Message
      
        Case #WM_INITDIALOG    Case #WM_DESTROY    Case #WM_NOTIFY
          *hdr.NMHDR = lParam
          OutputDebugString_("WM_NOTIFY: code = "+Str(*hdr\code))
          
          If *hdr\code = #PSN_SETACTIVE
            DialogReturn(Window, 0) ; important to handle this, otherwise we get a crash!      
          EndIf      
      
      EndSelect
      
      ProcedureReturn #False
    EndProcedure; This is a dialog template for an empty dialog
    ;
    DataSection  Dialog:
        Data.w 1 ; DlgVer
        Data.w $FFFF ; extended dlg structure
        Data.l 0 ; helpID
        Data.l 0 ; exStyle  
        Data.l #WS_CHILD | #WS_VISIBLE  ; Style    
        Data.w 0 ; Nb of items in the dialog    
        Data.w 0 ; x
        Data.w 0 ; y
        Data.w 0 ; w
        Data.w 0 ; h
        Data.w 0 ; PADDING
        Data.w $0000 ; NO menu!
        Data.w 0 ; PADDING
        Data.w $0000 ; No windowClass    
        Data.w 0 ; PADDING
        Data.w $0000 ; NO title
        Data.w 0 ; PADDING
            
    EndDataSection