Code: Alles auswählen
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 SHITEMID
; cb.w
; abID.b[1]
; EndStructure
; Structure ITEMIDLIST
; mkid.SHITEMID
; EndStructure
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 Ansi2Uni(*st, *Buffer, blen)
If Len(PeekS(*st))<blen
ProcedureReturn MultiByteToWideChar_(#CP_ACP, 0, *st, -1, *Buffer, blen)
Else
ProcedureReturn 0
EndIf
EndProcedure
QueryInterface:
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
AddRef:
Procedure IUnknown_AddRef(*ti_unk.IUnknown):*p_Unk\nRefCount+1:ProcedureReturn *p_Unk\nRefCount:EndProcedure
Release:
Procedure IUnknown_Release(*ti_unk.IUnknown):*p_Unk\nRefCount-1:ProcedureReturn *p_Unk\nRefCount:EndProcedure
CreateInstance:
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
LockServer:
Procedure IClassFactory_LockServer(*ti_cf.IClassFactory, fLock)
ProcedureReturn #E_FAIL
EndProcedure
; Structure FORMATETC
; cfFormat.l
; ptd.l
; dwAspect.l
; lindex.l
; tymed.l
; EndStructure
#CF_HDROP = $0f
#DVASPECT_CONTENT = 1
#TYMED_HGLOBAL = 1
#TYMED_FILE = 2
; Structure STGMEDIUM
; tymed.l
; hGlobal.l
; pUnkForRelease.l
; EndStructure
Initialize:
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
QueryContextMenu:
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
GetCommandString:
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 Ansi2Uni(?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 Ansi2Uni(?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
InvokeCommand:
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
Procedure VTable() ; This is NOT a real procedure: PureBasic ignores ASM commands in the DataSection, so I had to put the vtable here
!section '.data' Data readable writeable
lpVT_IUnknown:
!dd l_vt_iunknown
!dd 0 ; *p_Unk\nRefCount
!dd 0 ; *p_Unk\nLockCount
VT_IUnknown:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
lpVT_IClassFactory:
!dd l_vt_iclassfactory
VT_IClassFactory:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
!dd l_createinstance+5
!dd l_lockserver+2
lpVT_IShellExtInit:
!dd l_vt_ishellextinit
VT_IShellExtInit:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
!dd l_initialize+5
lpVT_IContextMenu:
!dd l_vt_icontextmenu
VT_IContextMenu:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
!dd l_querycontextmenu+5
!dd l_invokecommand+5
!dd l_getcommandstring+5
EndProcedure
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
Code: Alles auswählen
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 SHITEMID
cb.w
abID.b[1]
EndStructure
Structure ITEMIDLIST
mkid.SHITEMID
EndStructure
Structure ClassFactoryObject
lpVtbl.l
nRefCount.l
EndStructure
Global m_pDataObj.IDataObject, cmd, hModule
Global i_Unk.IUnknown, i_SEI.IShellExtInit, i_QCM.IContextMenu, i_QCM2.IContextMenu2, i_QCM3.IContextMenu3
Global *p_Unk.ClassFactoryObject
Global File$, hImage, newImage, iWidth, iHeight, mDC, mObj
#MAX_WIDTH = 128
#MAX_HEIGHT = 64
Procedure Ansi2Uni(*st, *Buffer, blen)
If Len(PeekS(*st))<=blen
ProcedureReturn MultiByteToWideChar_(#CP_ACP, 0, *st, -1, *Buffer, blen)
Else
ProcedureReturn 0
EndIf
EndProcedure
QueryInterface:
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
ElseIf CompareMemory(*riid, ?IID_IContextMenu2, SizeOf(GUID))
*ppvObject\l = i_QCM2
ElseIf CompareMemory(*riid, ?IID_IContextMenu3, SizeOf(GUID))
*ppvObject\l = i_QCM3
Else
*ppvObject\l = 0
ProcedureReturn #E_NOINTERFACE
EndIf
Else
ProcedureReturn #S_FALSE
EndIf
i_Unk\AddRef()
ProcedureReturn #S_OK
EndProcedure
AddRef:
Procedure IUnknown_AddRef(*ti_unk.IUnknown):*p_Unk\nRefCount+1:ProcedureReturn *p_Unk\nRefCount:EndProcedure
Release:
Procedure IUnknown_Release(*ti_unk.IUnknown):*p_Unk\nRefCount-1:ProcedureReturn *p_Unk\nRefCount:EndProcedure
CreateInstance:
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
LockServer:
Procedure IClassFactory_LockServer(*ti_cf.IClassFactory, fLock)
ProcedureReturn #E_FAIL
EndProcedure
Structure FORMATETC
cfFormat.l
ptd.l
dwAspect.l
lindex.l
tymed.l
EndStructure
#CF_HDROP = $0f
#DVASPECT_CONTENT = 1
#TYMED_HGLOBAL = 1
#TYMED_FILE = 2
Structure STGMEDIUM
tymed.l
hGlobal.l
pUnkForRelease.l
EndStructure
Initialize:
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
If hImage
If IsGadget(0)
FreeGadget(0)
EndIf
If IsWindow(0)
CloseWindow(0)
EndIf
FreeImage(0)
hImage = 0
If newImage
FreeImage(1)
newImage = 0
EndIf
EndIf
hImage = LoadImage(0, File$)
If hImage
ProcedureReturn #S_OK
EndIf
EndIf
EndIf
EndIf
ProcedureReturn #S_FALSE
EndProcedure
#MIIM_ID = 2
#MIIM_STRING = $40
#MF_STRING = 0
#MFT_STRING = #MF_STRING
#CMF_DEFAULTONLY = 1
#MIIM_TYPE = $10
QueryContextMenu:
Procedure IContextMenu_QueryContextMenu(*i_icm.IContextMenu, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags)
If #CMF_DEFAULTONLY&uFlags:ProcedureReturn 0:EndIf
If hImage
cmd = indexMenu
mii.MENUITEMINFO
mii\cbSize = SizeOf(MENUITEMINFO)
mii\fMask = #MIIM_TYPE|#MIIM_ID
mii\fType = #MFT_OWNERDRAW
mii\wID = idCmdFirst
mii\dwTypeData = hImage
If InsertMenuItem_(hmenu, 0, #True, @mii)=#False
ProcedureReturn 1<<31
EndIf
ProcedureReturn 1
EndIf
ProcedureReturn 1<<31
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
GetCommandString:
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 Ansi2Uni(?CommandHelpLine, pszName, Len(PeekS(?CommandHelpLine)))=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 Ansi2Uni(?CommandString, pszName, cchMax)=0
ProcedureReturn #S_FALSE
EndIf
Default
ProcedureReturn #S_FALSE
EndSelect
Else
ProcedureReturn #S_FALSE
EndIf
ProcedureReturn #S_OK
EndProcedure
Procedure WndProc(hWnd, uMsg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_CLOSE
FreeImage(0)
hImage = 0
FreeGadget(0)
CloseWindow(0)
EndSelect
ProcedureReturn result
EndProcedure
Procedure ShowIt()
If hImage
UseImage(0)
If OpenWindow(0, 0, 0, ImageWidth(), ImageHeight(), #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered, "FastView demo")
If CreateGadgetList(WindowID())
ImageGadget(0, 0, 0, ImageWidth(), ImageHeight(), hImage)
newImage = 0
FreeImage(1)
SetWindowCallback(@WndProc())
Else
FreeImage(0)
hImage = 0
FreeImage(1)
newImage = 0
CloseWindow(0)
EndIf
EndIf
EndIf
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
InvokeCommand:
Procedure IContextMenu_InvokeCommand(*ti_icm.IContextMenu, *pici.CMINVOKECOMMANDINFOEX)
If *pici\cbSize=SizeOf(CMINVOKECOMMANDINFOEX)
If *pici\fMask&#CMIC_MASK_UNICODE
If (*pici\lpVerbW&$ffff)=cmd
ShowIt()
ProcedureReturn #NOERROR
EndIf
EndIf
ElseIf *pici\cbSize=SizeOf(CMINVOKECOMMANDINFO)
If (*pici\lpVerb&$ffff)=cmd
ShowIt()
ProcedureReturn #NOERROR
EndIf
Else
ProcedureReturn #S_FALSE
EndIf
EndProcedure
HandleMenuMsg:
Procedure IContextMenu2_HandleMenuMsg(*ti_icm2.IContextMenu2, uMsg, wParam, *lParam.MEASUREITEMSTRUCT)
Select uMsg
Case #WM_DRAWITEM
*dis.DRAWITEMSTRUCT = *lParam
left = ((*dis\rcItem\right-*dis\rcItem\left)/2)-(iWidth/2)
top = ((*dis\rcItem\bottom-*dis\rcItem\top)/2)-(iHeight/2)
If *dis\itemState&#ODS_SELECTED
FillRect_(*dis\hDC, @*dis\rcItem, #COLOR_HIGHLIGHT+1)
BitBlt_(*dis\hDC, left+*dis\rcItem\left, top+*dis\rcItem\top, iWidth, iHeight, mDC, 0, 0, #SRCCOPY)
RasterOperation = #DSTINVERT
Else
FillRect_(*dis\hDC, @*dis\rcItem, #COLOR_MENU+1)
RasterOperation = #SRCCOPY
EndIf
BitBlt_(*dis\hDC, left+*dis\rcItem\left, top+*dis\rcItem\top, iWidth, iHeight, mDC, 0, 0, RasterOperation)
Case #WM_MEASUREITEM
iWidth = ImageWidth()
iHeight = ImageHeight()
If iWidth>#MAX_WIDTH
iHeight = (#MAX_WIDTH*iHeight)/iWidth
iWidth = #MAX_WIDTH
EndIf
If iHeight>#MAX_HEIGHT
iWidth = (#MAX_HEIGHT*iWidth/iHeight)
iHeight = #MAX_HEIGHT
EndIf
*lParam\itemWidth = iWidth
*lParam\itemHeight = iHeight
CopyImage(0, 1)
newImage = ResizeImage(1, iWidth, iHeight)
mDC = CreateCompatibleDC_(GetDC_(GetDesktopWindow_()))
mObj = SelectObject_(mDC, newImage)
EndSelect
ProcedureReturn #NOERROR
EndProcedure
HandleMenuMsg2:
Procedure IContextMenu3_HandleMenuMsg2(*ti_icm3.IContextMenu3, uMsg, wParam, lParam, *plResult.LONG)
If *ti_icm3\HandleMenuMsg(uMsg, wParam, lParam)=#NOERROR
*plResult\l = #True
ProcedureReturn #NOERROR
EndIf
*plResult\l = #False
ProcedureReturn #E_FAIL
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
If ~GetModuleFileName_(?InDLL&$FFFF0000, *szBuffer, #MAX_PATH)
GetModuleFileName_(hModule, *szBuffer, #MAX_PATH)
EndIf
EndIf
If Len(PeekS(*szBuffer))
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
If *szBuffer:FreeMemory(*szBuffer):EndIf
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_QCM2 = ?lpVT_IContextMenu2
i_QCM3 = ?lpVT_IContextMenu3
i_SEI = ?lpVT_IShellExtInit
i_Unk = ?lpVT_IUnknown
*p_Unk = ?lpVT_IUnknown
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
; UseEC_IFFImageDecoder()
; UseEC_PBMImageDecoder()
; UseEC_PGMImageDecoder()
; UseEC_PPMImageDecoder()
; UseEC_XPMImageDecoder()
; UseEC_WBMPImageDecoder()
; UseEC_XBMImageDecoder()
; UseEC_OLEImageDecoder()
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
If mDC
SelectObject_(mDC, mObj)
DeleteDC_(mDC)
mDC = 0
EndIf
ProcedureReturn #S_OK
Else
ProcedureReturn #S_FALSE
EndIf
EndProcedure
Procedure VTable() ; This is NOT a real procedure: PureBasic ignores ASM commands in the DataSection, so I had to put the vtable here
!section '.data' Data readable writeable
lpVT_IUnknown:
!dd l_vt_iunknown
!dd 0 ; *p_Unk\nRefCount
!dd 0 ; *p_Unk\nLockCount
VT_IUnknown:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
lpVT_IClassFactory:
!dd l_vt_iclassfactory
VT_IClassFactory:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
!dd l_createinstance+5
!dd l_lockserver+2
lpVT_IShellExtInit:
!dd l_vt_ishellextinit
VT_IShellExtInit:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
!dd l_initialize+5
lpVT_IContextMenu:
lpVT_IContextMenu2:
lpVT_IContextMenu3:
!dd l_vt_icontextmenu
VT_IContextMenu:
VT_IContextMenu2:
VT_IContextMenu3:
!dd l_queryinterface+5
!dd l_addref+2
!dd l_release+2
!dd l_querycontextmenu+5
!dd l_invokecommand+5
!dd l_getcommandstring+5
!dd l_handlemenumsg+5
!dd l_handlemenumsg2+5
EndProcedure
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
IID_IContextMenu2:
Data.l $000214F4
Data.w 0, 0
Data.b $C0, 0, 0, 0, 0, 0, 0, $46
IID_IContextMenu3:
Data.l $bcfce0a0
Data.w $ec17, $11d0
Data.b $8d, $10, 0, $a0, $c9, $0f, $27, $19
CommandString:
Data.s "Show image"
CommandHelpLine:
Data.s "Shows the image"
EndDataSection
For VTable use the new DataSection Syntax. It´s easy.
P.S. Was fürn Englisch, Sorry