Hello COM people :)
My first post here, and I have no idea about how to use COM but I realised that it is very powerfull feature of Win32
Anyway I wanted to add menu to my program that will show explorer context menu for some file/folder, but due to my ignorance in this area I am not exacly sure how to do this.
I saw ernie's file manager source and found this code, but still I could not make it to work in my program.
I dont understand much this code, and also looks like I dont have all includes needed to compile COM stuff properly. Does someone maybe already has standalone example on how to show context menu from his own app?
My first post here, and I have no idea about how to use COM but I realised that it is very powerfull feature of Win32
Anyway I wanted to add menu to my program that will show explorer context menu for some file/folder, but due to my ignorance in this area I am not exacly sure how to do this.
I saw ernie's file manager source and found this code, but still I could not make it to work in my program.
ContextMenu proc public uses ebx edx hWnd:DWORD, pshfParent:LPSHELLFOLDER, pidl:LPITEMIDLIST, ppoint:DWORD
LOCAL pcm:LPCONTEXTMENU
LOCAL hMenu:DWORD
LOCAL iCmd:DWORD
LOCAL cmi:CMINVOKECOMMANDINFO
mov ebx, pshfParent
mov ebx,[ebx]
invoke (IShellFolder ptr [ebx]).GetUIObjectOf, pshfParent,
hWnd,
1,
addr pidl,
addr IID_IContextMenu,
0,
addr pcm
test eax,eax
js ret_error
invoke CreatePopupMenu
test eax,eax
jz ret_error
mov hMenu, eax
mov ebx, pcm
mov ebx, [ebx]
invoke (IContextMenu ptr [ebx]).QueryContextMenu, pcm,
hMenu,
0,
1,
7FFFh,
CMF_EXPLORE
test eax,eax
js ret_error
mov edx, ppoint
invoke TrackPopupMenu,
hMenu,
TPM_LEFTALIGN or TPM_RIGHTBUTTON or 0100h, ;TPM_RETURNCMD
(POINT ptr [edx]).x,
(POINT ptr [edx]).y,
0,
hWnd,
0
test eax,eax
jz ret_error
mov iCmd, eax
mov cmi.cbSize, sizeof CMINVOKECOMMANDINFO
mov cmi.fMask, 0
mov eax, hWnd
mov cmi.hwnd, eax
mov eax, iCmd
dec eax
and eax, 0000FFFFh
mov cmi.lpVerb, eax
mov cmi.lpParameters, 0
mov cmi.lpDirectory, 0
mov cmi.nShow, SW_SHOWNORMAL
mov cmi.dwHotKey, 0
mov cmi.hIcon, 0
mov ebx, pcm
mov ebx, [ebx]
invoke (IContextMenu ptr [ebx]).InvokeCommand, pcm, addr cmi
.IF eax < 0 ; failed
;int 3
.ENDIF
invoke DestroyMenu, hMenu
invoke (IContextMenu ptr [ebx]).Release, pcm
ret_ok:
mov eax,1
ret
ret_error:
xor eax,eax
ret
ContextMenu endp
I dont understand much this code, and also looks like I dont have all includes needed to compile COM stuff properly. Does someone maybe already has standalone example on how to show context menu from his own app?
I have no experience with this area as well, but i can help by explaining this function to you:
This uses a provided COM object instance. In this case its pshfParent (IShellFolder instance). This is only generated via COM function calls, or specific API. My guess is if its failing, it would be here as your probably not getting the right Object instance to satisfy this parameter. If it does work, it will return in 'pcm' (pointer to context menu instance) a context menu.
This simply makes a Popup menu. Nothing new.
This uses the returned context menu pointer (another COM object instance) to query it and popuplate hMenu (the popup menu you just created). This is my best guess from the parameters provided.
This simply displays the popup menu. Again, nothing to new here.
This section of code takes the chosen item from the popup menu and packs it into a CMINVOKECOMMANDINFO structure, so it can be passed back to the context menu object. Once the context menu object has been notified of the selection chosen from the user, it is told to 'invoke' the desired action associated with the item number.
This is clean up. Free the menu resource used as well as Release the COM instance created, which was the returned Context Menu object.
I hope this helps. Again from reviewing this, my guess is its not working because your probably do not have the right Object instance to get the entire train rolling. Everything else in this function is tightly written by appearances.
Best of luck.
:NaN:
mov ebx, pshfParent
mov ebx,[ebx]
invoke (IShellFolder ptr [ebx]).GetUIObjectOf, pshfParent,
hWnd,
1,
addr pidl,
addr IID_IContextMenu,
0,
addr pcm
test eax,eax
js ret_error
This uses a provided COM object instance. In this case its pshfParent (IShellFolder instance). This is only generated via COM function calls, or specific API. My guess is if its failing, it would be here as your probably not getting the right Object instance to satisfy this parameter. If it does work, it will return in 'pcm' (pointer to context menu instance) a context menu.
invoke CreatePopupMenu
test eax,eax
jz ret_error
mov hMenu, eax
This simply makes a Popup menu. Nothing new.
mov ebx, pcm
mov ebx, [ebx]
invoke (IContextMenu ptr [ebx]).QueryContextMenu, pcm,
hMenu,
0,
1,
7FFFh,
CMF_EXPLORE
test eax,eax
js ret_error
This uses the returned context menu pointer (another COM object instance) to query it and popuplate hMenu (the popup menu you just created). This is my best guess from the parameters provided.
mov edx, ppoint
invoke TrackPopupMenu,
hMenu,
TPM_LEFTALIGN or TPM_RIGHTBUTTON or 0100h, ;TPM_RETURNCMD
(POINT ptr [edx]).x,
(POINT ptr [edx]).y,
0,
hWnd,
0
test eax,eax
jz ret_error
This simply displays the popup menu. Again, nothing to new here.
mov iCmd, eax
mov cmi.cbSize, sizeof CMINVOKECOMMANDINFO
mov cmi.fMask, 0
mov eax, hWnd
mov cmi.hwnd, eax
mov eax, iCmd
dec eax
and eax, 0000FFFFh
mov cmi.lpVerb, eax
mov cmi.lpParameters, 0
mov cmi.lpDirectory, 0
mov cmi.nShow, SW_SHOWNORMAL
mov cmi.dwHotKey, 0
mov cmi.hIcon, 0
mov ebx, pcm
mov ebx, [ebx]
invoke (IContextMenu ptr [ebx]).InvokeCommand, pcm, addr cmi
.IF eax < 0 ; failed
;int 3
.ENDIF
This section of code takes the chosen item from the popup menu and packs it into a CMINVOKECOMMANDINFO structure, so it can be passed back to the context menu object. Once the context menu object has been notified of the selection chosen from the user, it is told to 'invoke' the desired action associated with the item number.
invoke DestroyMenu, hMenu
invoke (IContextMenu ptr [ebx]).Release, pcm
This is clean up. Free the menu resource used as well as Release the COM instance created, which was the returned Context Menu object.
I hope this helps. Again from reviewing this, my guess is its not working because your probably do not have the right Object instance to get the entire train rolling. Everything else in this function is tightly written by appearances.
Best of luck.
:NaN:
Check out this link as well for reference:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/ishellfolder/ishellfolder.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/ishellfolder/ishellfolder.asp
This link talks about ways of getting the IShellFolder interface (what you need for this function to work).
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/folder_info.asp
My guess is a simple test would be using the API: SHGetDesktopFolder
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shgetdesktopfolder.asp
Using this interface you should *probably* be presented with the context menu that you would see when you goto "my computer" and right click. (My guess only here)
Regards,
:NaN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/folder_info.asp
My guess is a simple test would be using the API: SHGetDesktopFolder
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shgetdesktopfolder.asp
Using this interface you should *probably* be presented with the context menu that you would see when you goto "my computer" and right click. (My guess only here)
Regards,
:NaN: