#include <fivewin.ch>
#include <winapi.ch>
memvar oPreview
#define MF_BYPOSITION 1024
#define WM_INITMENUPOPUP 0x0117
#define TPM_RETURNCMD 0x0100
function main()
local oDlg
public oPreview
// IMPORTANT!!
CoInitialize()
DEFINE WINDOW oDlg FROM 0,0 TO 650,650 PIXEL TITLE "Test"
oDlg:bLClicked := {|| ApriCon(oDlg:hWnd, "C:\fwh\samples\test.jpg") }
ACTIVATE WINDOW oDlg CENTERED
return nil
function ApriCon(hWnd, cFileName)
Local hMenu
Local cmd
local aCoords := GetCursorPos()
LOCAL hShell32, msg1, msg2, cmp
LOCAL n, i
LOCAL ContextMenu
// crate a context menu
ContextMenu := IContextMenu_Get(hWnd, cFileName)
if( ContextMenu == 0 )
return .F.
endif
// get localized "Open with"
hShell32 := GetModuleHandle("shell32.dll")
msg1 := LoadString(hShell32, 5376)
msg2 := LoadString(hShell32, 5377)
// create the menu
hMenu := CreatePopupMenu()
IContextMenu_GetMenu(ContextMenu, hMenu)
// looking for "Open with"
n := GetMItemCount(hMenu)
for i:=1 To n
cmp := GetMenuString(hMenu, i-1, MF_BYPOSITION)
if cmp == msg1 .or. cmp == msg2
exit
endif
next
aCoords := GetCursorPos()
if i < n //found
// fill the "open with" sub menu
n := IContextMenu_HandleMenuMsg(ContextMenu, WM_INITMENUPOPUP, GetSubMenu(hMenu,i-1), 0)
// show the menu
cmd := TrackPopupMenuEx_n( GetSubMenu(hMenu,i-1), TPM_RETURNCMD, aCoords[1], aCoords[2], hWnd, 0)
else
// show the complete menu
cmd := TrackPopupMenuEx_n( hMenu, TPM_RETURNCMD, aCoords[1], aCoords[2], hWnd, 0)
endif
// execute the command
if cmd>0
IcontextMenu_Invoke(ContextMenu, hWnd, cmd, aCoords[1], aCoords[2])
endif
// clean up
DestroyMenu(hMenu)
IcontextMenu_Release(ContextMenu)
// return true if an application starts
return cmd>0
#pragma BEGINDUMP
#define CINTERFACE
#define COBJMACROS
#include <windows.h>
#include <hbapi.h>
#include <CommCtrl.h>
#include <ShObjIdl.h>
#include <Shlwapi.h>
#include <ShlGuid.h>
#include <ShlObj.h>
LPWSTR AnsiToWide( LPSTR cAnsi );
void* GetUIObjectOf(HWND hWnd, LPWSTR cFileName, REFIID iid)
{
#if 1 //Debug :p
char tmp[100];
#define CK(msg) if(hr!=S_OK) { sprintf_s(tmp,100,msg " 0x%08X",hr); MessageBox(0,tmp,"error",MB_OK); }
#else
#define CK(msg)
#endif
HRESULT hr;
LPITEMIDLIST pidl;
SFGAOF sfgao;
void *ppv = NULL;
if (SUCCEEDED(hr = SHParseDisplayName(cFileName, NULL, &pidl, 0, &sfgao))) {
IShellFolder *psf;
LPCITEMIDLIST pidlChild;
if (SUCCEEDED(hr = SHBindToParent(pidl, &IID_IShellFolder,
(void**)&psf, &pidlChild))) {
hr = IShellFolder_GetUIObjectOf(psf, hWnd, 1, &pidlChild, iid, NULL, &ppv);
IShellFolder_Release(psf);
}
CoTaskMemFree(pidl);
}
CK("GetUIObjectOf")
return ppv;
}
HB_FUNC( ICONTEXTMENU_GET ) // hWnd, cFileName
{
#ifndef _WIN64
HWND hWnd = ( HWND ) hb_parnl( 1 );
#else
HWND hWnd = ( HWND ) hb_parnll( 1 );
#endif
LPWSTR cFileName = AnsiToWide(( char * ) hb_parc( 2 ));
IContextMenu *pContextMenu = (IContextMenu*)GetUIObjectOf(hWnd, cFileName, &IID_IContextMenu);
#ifndef _WIN64
hb_retnl( (long)pContextMenu );
#else
hb_retnll( (long long)pContextMenu );
#endif
}
HB_FUNC( ICONTEXTMENU_GETMENU ) //IContextMenu, hMenu
{
#ifndef _WIN64
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnl( 1 );
HMENU hMenu = ( HMENU ) hb_parnl( 2 );
#else
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnll( 1 );
HMENU hMenu = ( HMENU ) hb_parnll( 2 );
#endif
if( pContextMenu )
{
hb_retnl(IContextMenu_QueryContextMenu(pContextMenu, hMenu, 0, 1,0x7FFF, 0));
}
hb_retnl(0);
}
HB_FUNC( ICONTEXTMENU_INVOKE ) //IContextMenu, hWnd, id, pt.y, pt.x
{
#ifndef _WIN64
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnl( 1 );
HWND hWnd = ( HWND ) hb_parnl( 2 );
#else
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnll( 1 );
HWND hWnd = ( HWND ) hb_parnll( 2 );
#endif
int iCmd = hb_parni( 3 )-1;
CMINVOKECOMMANDINFOEX info = { 0 };
info.cbSize = sizeof(CMINVOKECOMMANDINFOEX);
info.fMask = CMIC_MASK_UNICODE | CMIC_MASK_PTINVOKE;
info.hwnd = hWnd;
info.lpVerb = MAKEINTRESOURCEA(iCmd);
info.lpVerbW = MAKEINTRESOURCEW(iCmd);
info.nShow = SW_SHOWNORMAL;
info.ptInvoke.y = hb_parni(4);
info.ptInvoke.x = hb_parni(5);
hb_retnl(IContextMenu_InvokeCommand(pContextMenu, (LPCMINVOKECOMMANDINFO)&info));
}
HB_FUNC( ICONTEXTMENU_HANDLEMENUMSG ) // IContextMenu, nMsg, nWParam, nLParam)
{
#ifndef _WIN64
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnl( 1 );
#else
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnll( 1 );
#endif
UINT message = ( UINT ) hb_parnl( 2 );
WPARAM wParam = ( WPARAM ) hb_parnl( 3 );
LPARAM lParam = ( LPARAM ) hb_parnl( 4 );
HRESULT hr;
IContextMenu2 *pContextMenu2;
IContextMenu_QueryInterface( pContextMenu, &IID_IContextMenu2, (void**)&pContextMenu2);
hr = IContextMenu2_HandleMenuMsg(pContextMenu2, message, wParam, lParam);
IContextMenu2_Release(pContextMenu2);
hb_retnl(hr);
}
HB_FUNC( ICONTEXTMENU_RELEASE ) //IContextMenu
{
#ifndef _WIN64
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnl( 1 );
#else
IContextMenu *pContextMenu = ( IContextMenu* ) hb_parnll( 1 );
#endif
if( pContextMenu )
{
IContextMenu_Release(pContextMenu);
}
hb_ret();
}
HB_FUNC( TRACKPOPUPMENUEX_N )
{
hb_retnl( TrackPopupMenuEx( ( HMENU ) hb_parnl( 1 ), hb_parni( 2 ), hb_parni( 4 ),
hb_parni( 3 ), ( HWND ) hb_parni( 5 ), NULL ) );
}
#pragma ENDDUMP