7,763
社区成员
发帖
与我相关
我的任务
分享
ProcedureDLL DllRegisterServer()
InDLL:
If RegCreateKeyEx_(#HKEY_CLASSES_ROOT, "*\shellex\ContextMenuHandlers\MysticBoy.CFP", 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, "MysticBoy.CFP\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, "MysticBoy.CFP", 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, "MysticBoy.CFP", 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\MysticBoy.CFP")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf
If RegDeleteKey_(#HKEY_CLASSES_ROOT, "MysticBoy.CFP\shellex\ContextMenuHandlers")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf
If RegDeleteKey_(#HKEY_CLASSES_ROOT, "MysticBoy.CFP\shellex")<>#ERROR_SUCCESS:ProcedureReturn #SELFREG_E_CLASS::EndIf
If RegDeleteKey_(#HKEY_CLASSES_ROOT, "MysticBoy.CFP")<>#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
BuildCOMVTable_IClassFactory(ShellMenuObject)
BuildCOMVTable_IShellExtInit(ShellMenuObject)
BuildCOMVTable_IContextMenu(ShellMenuObject)
ProcedureReturn #True
EndProcedure
ProcedureDLL DllGetClassObject(*rclsid.GUID, *riid.GUID, *ppv.LONG)
If *ppv
If CompareCLSID(*rclsid, ?CLSID_ContextMenuHandler)
If CompareIID(*riid, ?IID_IClassFactory)
*ppv\l = New_ShellMenuObject() ; returns the IClassFactory
ProcedureReturn #S_OK
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
EndProcedure
ProcedureDLL DllCanUnloadNow()
If ExistingObjectCount = 0
ProcedureReturn #S_OK
Else
ProcedureReturn #S_FALSE
EndIf
EndProcedure
DataSection
CommandString:
Data.s "复制完整路径(&F)"
CommandHelpLine:
Data.s "复制此文件的完整路径."+Chr(0)
EndDataSection
[code=VBScript]
Declare PutFileName2Clipboard(filename.s)
EnableCOMDebugging
Global ExistingObjectCount
Global hModule
COMClass(ShellMenuObject)
COMInterface(ShellMenuObject, IClassFactory)
COMInterface(ShellMenuObject, IShellExtInit)
COMInterface(ShellMenuObject, IContextMenu)
COMClassData(ShellMenuObject)
nLockCount.l
m_pDataObj.IDataObject
File$
EndCOMClassData
COMConstructor(ShellMenuObject)
ExistingObjectCount + 1
COMConstructorReturn IClassFactory ;
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("错误", message$)
EndProcedure
Procedure 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 = 1
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
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
#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
COMEmptyMethod(ShellMenuObject, IClassFactory, LockServer, #E_FAIL)
Procedure ShellMenuObject_IShellExtInit_Initialize(*THIS.ShellMenuObject, *pidlFolder.ITEMIDLIST, *pdtobj.IDataObject, hkeyProgID) COMMethodOf(ShellMenuObject)
If *THIS\m_pDataObj
*THIS\m_pDataObj\Release()
*THIS\m_pDataObj = 0
EndIf
If *pdtobj
*THIS\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
*THIS\File$ = PeekS(*m_szFile)
EndIf
FreeMemory(*m_szFile)
EndIf
ReleaseStgMedium_(@medium)
If uCount=1
ProcedureReturn #S_OK
EndIf
EndIf
EndIf
ProcedureReturn #S_FALSE
EndProcedure
Procedure ShellMenuObject_IContextMenu_QueryContextMenu(*THIS.ShellMenuObject, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags) COMMethodOf(ShellMenuObject)
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
Procedure ShellMenuObject_IContextMenu_GetCommandString(*THIS.ShellMenuObject, idCmd, uFlags, pwReserved, pszName, cchMax) COMMethodOf(ShellMenuObject)
If idCmd=cmd
Select uFlags
Case #GCS_HELPTEXTA
CopyMemory(?CommandHelpLine, pszName, Len(PeekS(?CommandHelpLine)))
Case #GCS_HELPTEXTW
If Ansi2Uni(?CommandHelpLine, pszName, cchMax)=0
ProcedureReturn #S_FALSE
EndIf
Case #GCS_VALIDATEA
ProcedureReturn #S_OK
Case #GCS_VALIDATEW
ProcedureReturn #S_OK
Case #GCS_VERBA
PokeS(pszName, PeekS(?CommandString))
Case #GCS_VERBW
If Ansi2Uni(?CommandString, pszName, cchMax)=0
ProcedureReturn #S_FALSE
EndIf
Default
ProcedureReturn #S_FALSE
EndSelect
Else
ProcedureReturn #S_FALSE
EndIf
ProcedureReturn #S_OK
EndProcedure
Procedure ShellMenuObject_IContextMenu_InvokeCommand(*THIS.ShellMenuObject, *pici.CMINVOKECOMMANDINFOEX) COMMethodOf(ShellMenuObject)
If *pici\cbSize=SizeOf(CMINVOKECOMMANDINFOEX)
If *pici\fMask&#CMIC_MASK_UNICODE
If (*pici\lpVerbW&$ffff)=cmd
PutFileName2Clipboard(*THIS\File$);
ProcedureReturn #NOERROR
EndIf
EndIf
EndIf
If *pici\cbSize>=SizeOf(CMINVOKECOMMANDINFO)
If (*pici\lpVerb&$ffff)=cmd
PutFileName2Clipboard(*THIS\File$);
ProcedureReturn #NOERROR
EndIf
Else
ProcedureReturn #S_FALSE
EndIf
EndProcedure
Procedure PutFileName2Clipboard(filename.s)
ClearClipboard()
SetClipboardText(filename);
EndProcedure
Declare PutFileName2Clipboard(filename.s)
EnableCOMDebugging
Global ExistingObjectCount
Global hModule
COMClass(ShellMenuObject)
COMInterface(ShellMenuObject, IClassFactory)
COMInterface(ShellMenuObject, IShellExtInit)
COMInterface(ShellMenuObject, IContextMenu)
COMClassData(ShellMenuObject)
nLockCount.l
m_pDataObj.IDataObject
File$
EndCOMClassData
COMConstructor(ShellMenuObject)
ExistingObjectCount + 1
COMConstructorReturn IClassFactory ;
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("错误", message$)
EndProcedure
Procedure 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 = 1
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
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
#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
COMEmptyMethod(ShellMenuObject, IClassFactory, LockServer, #E_FAIL)
Procedure ShellMenuObject_IShellExtInit_Initialize(*THIS.ShellMenuObject, *pidlFolder.ITEMIDLIST, *pdtobj.IDataObject, hkeyProgID) COMMethodOf(ShellMenuObject)
If *THIS\m_pDataObj
*THIS\m_pDataObj\Release()
*THIS\m_pDataObj = 0
EndIf
If *pdtobj
*THIS\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
*THIS\File$ = PeekS(*m_szFile)
EndIf
FreeMemory(*m_szFile)
EndIf
ReleaseStgMedium_(@medium)
If uCount=1
ProcedureReturn #S_OK
EndIf
EndIf
EndIf
ProcedureReturn #S_FALSE
EndProcedure
Procedure ShellMenuObject_IContextMenu_QueryContextMenu(*THIS.ShellMenuObject, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags) COMMethodOf(ShellMenuObject)
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
Procedure ShellMenuObject_IContextMenu_GetCommandString(*THIS.ShellMenuObject, idCmd, uFlags, pwReserved, pszName, cchMax) COMMethodOf(ShellMenuObject)
If idCmd=cmd
Select uFlags
Case #GCS_HELPTEXTA
CopyMemory(?CommandHelpLine, pszName, Len(PeekS(?CommandHelpLine)))
Case #GCS_HELPTEXTW
If Ansi2Uni(?CommandHelpLine, pszName, cchMax)=0
ProcedureReturn #S_FALSE
EndIf
Case #GCS_VALIDATEA
ProcedureReturn #S_OK
Case #GCS_VALIDATEW
ProcedureReturn #S_OK
Case #GCS_VERBA
PokeS(pszName, PeekS(?CommandString))
Case #GCS_VERBW
If Ansi2Uni(?CommandString, pszName, cchMax)=0
ProcedureReturn #S_FALSE
EndIf
Default
ProcedureReturn #S_FALSE
EndSelect
Else
ProcedureReturn #S_FALSE
EndIf
ProcedureReturn #S_OK
EndProcedure
Procedure ShellMenuObject_IContextMenu_InvokeCommand(*THIS.ShellMenuObject, *pici.CMINVOKECOMMANDINFOEX) COMMethodOf(ShellMenuObject)
If *pici\cbSize=SizeOf(CMINVOKECOMMANDINFOEX)
If *pici\fMask&#CMIC_MASK_UNICODE
If (*pici\lpVerbW&$ffff)=cmd
PutFileName2Clipboard(*THIS\File$);
ProcedureReturn #NOERROR
EndIf
EndIf
EndIf
If *pici\cbSize>=SizeOf(CMINVOKECOMMANDINFO)
If (*pici\lpVerb&$ffff)=cmd
PutFileName2Clipboard(*THIS\File$);
ProcedureReturn #NOERROR
EndIf
Else
ProcedureReturn #S_FALSE
EndIf
EndProcedure
Procedure PutFileName2Clipboard(filename.s)
ClearClipboard()
SetClipboardText(filename);
EndProcedure