ReactOS 0.4.16-dev-927-g467dec4
util.c File Reference
#include "shimgvw.h"
#include <windowsx.h>
#include <shlobj.h>
#include <shellapi.h>
#include <shellutils.h>
#include <shlwapi_undoc.h>
Include dependency graph for util.c:

Go to the source code of this file.

Classes

struct  _ENABLECOMMANDDATA
 

Typedefs

typedef struct _ENABLECOMMANDDATA ENABLECOMMANDDATA
 

Functions

static int GetMenuItemIdByPos (HMENU hMenu, UINT Pos)
 
static BOOL IsMenuSeparator (HMENU hMenu, UINT Pos)
 
static BOOL IsSelfShellVerb (PCWSTR Assoc, PCWSTR Verb)
 
static void ModifyShellContextMenu (IContextMenu *pCM, HMENU hMenu, UINT CmdIdFirst, PCWSTR Assoc)
 
static LRESULT CALLBACK ShellContextMenuWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
static void DoShellContextMenu (HWND hwnd, IContextMenu *pCM, PCWSTR File, LPARAM lParam)
 
HRESULT GetUIObjectOfPath (HWND hwnd, PCWSTR File, REFIID riid, void **ppv)
 
void DoShellContextMenuOnFile (HWND hwnd, PCWSTR File, LPARAM lParam)
 
static DWORD CALLBACK EnableCommandIfVerbExistsProc (LPVOID ThreadParam)
 
void EnableCommandIfVerbExists (UINT ImageId, HWND hwnd, UINT CmdId, PCWSTR Verb, PCWSTR File)
 
void ShellExecuteVerb (HWND hwnd, PCWSTR Verb, PCWSTR File, BOOL Quit)
 
UINT ErrorBox (HWND hwnd, UINT Error)
 
void DisplayHelp (HWND hwnd)
 

Variables

IContextMenug_pContextMenu = NULL
 

Typedef Documentation

◆ ENABLECOMMANDDATA

Function Documentation

◆ DisplayHelp()

void DisplayHelp ( HWND  hwnd)

Definition at line 253 of file util.c.

254{
256}
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
UINT ErrorBox(HWND hwnd, UINT Error)
Definition: util.c:247
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023

Referenced by Preview_OnCommand().

◆ DoShellContextMenu()

static void DoShellContextMenu ( HWND  hwnd,
IContextMenu pCM,
PCWSTR  File,
LPARAM  lParam 
)
static

Definition at line 93 of file util.c.

94{
95 enum { first = 1, last = 0x7fff };
96 HRESULT hr;
97 HMENU hMenu = CreatePopupMenu();
98 UINT cmf = GetKeyState(VK_SHIFT) < 0 ? CMF_EXTENDEDVERBS : 0;
99
101 if ((int)lParam == -1)
102 {
103 RECT rect;
105 pt.x = (rect.left + rect.right) / 2;
106 pt.y = rect.top;
107 }
108
109 g_pContextMenu = pCM;
111 if (!hwnd)
112 goto die;
113 hr = IContextMenu_QueryContextMenu(pCM, hMenu, 0, first, last, cmf | CMF_NODEFAULT);
114 if (SUCCEEDED(hr))
115 {
116 UINT id;
118 id = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, pt.x, pt.y, hwnd, NULL);
119 if (id)
120 {
121 UINT flags = (GetKeyState(VK_SHIFT) < 0 ? CMIC_MASK_SHIFT_DOWN : 0) |
122 (GetKeyState(VK_CONTROL) < 0 ? CMIC_MASK_CONTROL_DOWN : 0);
123 CMINVOKECOMMANDINFO ici = { sizeof(ici), flags, hwnd, MAKEINTRESOURCEA(id - first) };
124 ici.nShow = SW_SHOW;
125 hr = IContextMenu_InvokeCommand(pCM, &ici);
126 }
127 }
129die:
130 DestroyMenu(hMenu);
132}
Definition: File.h:16
LPARAM lParam
Definition: combotst.c:139
#define NULL
Definition: types.h:112
static void ModifyShellContextMenu(IContextMenu *pCM, HMENU hMenu, UINT CmdIdFirst, PCWSTR Assoc)
Definition: util.c:47
static LRESULT CALLBACK ShellContextMenuWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: util.c:84
IContextMenu * g_pContextMenu
Definition: util.c:15
HWND WINAPI SHCreateWorkerWindowW(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra)
Definition: ordinal.c:3004
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
#define pt(x, y)
Definition: drawing.c:79
GLbitfield flags
Definition: glext.h:7161
const GLint * first
Definition: glext.h:5794
GLuint id
Definition: glext.h:5910
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define die(str)
Definition: mkdosfs.c:347
static UINT UINT last
Definition: font.c:45
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
unsigned int UINT
Definition: ndis.h:50
#define WS_CHILD
Definition: pedump.c:617
#define WS_VISIBLE
Definition: pedump.c:620
HRESULT hr
Definition: shlfolder.c:183
& rect
Definition: startmenu.cpp:1413
#define GET_Y_LPARAM(lp)
Definition: windowsx.h:300
#define GET_X_LPARAM(lp)
Definition: windowsx.h:299
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define VK_CONTROL
Definition: winuser.h:2206
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define VK_SHIFT
Definition: winuser.h:2205
#define SW_SHOW
Definition: winuser.h:778
#define TPM_RETURNCMD
Definition: winuser.h:2390
BOOL WINAPI DestroyWindow(_In_ HWND)
SHORT WINAPI GetKeyState(_In_ int)

Referenced by DoShellContextMenuOnFile().

◆ DoShellContextMenuOnFile()

void DoShellContextMenuOnFile ( HWND  hwnd,
PCWSTR  File,
LPARAM  lParam 
)

Definition at line 152 of file util.c.

153{
154 IContextMenu *pCM;
156 if (SUCCEEDED(hr))
157 {
159 IContextMenu_Release(pCM);
160 }
161}
HRESULT GetUIObjectOfPath(HWND hwnd, PCWSTR File, REFIID riid, void **ppv)
Definition: util.c:135
static void DoShellContextMenu(HWND hwnd, IContextMenu *pCM, PCWSTR File, LPARAM lParam)
Definition: util.c:93
#define IID_PPV_ARG(Itype, ppType)

Referenced by ZoomWndProc().

◆ EnableCommandIfVerbExists()

void EnableCommandIfVerbExists ( UINT  ImageId,
HWND  hwnd,
UINT  CmdId,
PCWSTR  Verb,
PCWSTR  File 
)

Definition at line 209 of file util.c.

210{
211 const SIZE_T cch = lstrlenW(File) + 1;
213 if (pData)
214 {
215 pData->hwnd = hwnd;
216 pData->Verb = Verb; // Note: This assumes the string is valid for the lifetime of the thread.
217 pData->CmdId = CmdId;
218 pData->ImageId = ImageId;
219 CopyMemory(pData->File, File, cch * sizeof(*File));
221 }
222}
#define lstrlenW
Definition: compat.h:750
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
static DWORD CALLBACK EnableCommandIfVerbExistsProc(LPVOID ThreadParam)
Definition: util.c:173
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define CTF_COINIT
Definition: shlwapi.h:1981
#define CTF_INSIST
Definition: shlwapi.h:1978
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CopyMemory
Definition: winbase.h:1741

Referenced by Preview_pLoadImage().

◆ EnableCommandIfVerbExistsProc()

static DWORD CALLBACK EnableCommandIfVerbExistsProc ( LPVOID  ThreadParam)
static

Definition at line 173 of file util.c.

174{
175 enum { first = 1, last = 0x7fff };
176 ENABLECOMMANDDATA *pData = ThreadParam;
177 IContextMenu *pCM;
179 if (SUCCEEDED(hr))
180 {
181 HMENU hMenu = CreatePopupMenu();
182 hr = IContextMenu_QueryContextMenu(pCM, hMenu, 0, first, last, CMF_NORMAL);
183 if (SUCCEEDED(hr))
184 {
185 for (UINT i = 0, c = GetMenuItemCount(hMenu); i < c; ++i)
186 {
187 WCHAR buf[200];
188 UINT id = GetMenuItemIdByPos(hMenu, i);
189 if (id == (UINT)-1)
190 continue;
191
192 *buf = UNICODE_NULL;
193 hr = IContextMenu_GetCommandString(pCM, id - first, GCS_VERBW, NULL, (char*)buf, _countof(buf));
194 if (SUCCEEDED(hr) && !lstrcmpiW(buf, pData->Verb))
195 {
196 PostMessageW(pData->hwnd, WM_UPDATECOMMANDSTATE, MAKELONG(pData->CmdId, TRUE), pData->ImageId);
197 break;
198 }
199 }
200 }
201 DestroyMenu(hMenu);
202 IContextMenu_Release(pCM);
203 }
204 SHFree(pData);
205 return 0;
206}
#define TRUE
Definition: types.h:120
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
static int GetMenuItemIdByPos(HMENU hMenu, UINT Pos)
Definition: util.c:18
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define c
Definition: ke_i.h:80
#define UNICODE_NULL
#define WM_UPDATECOMMANDSTATE
Definition: shimgvw.h:33
#define _countof(array)
Definition: sndvol32.h:70
#define MAKELONG(a, b)
Definition: typedefs.h:249
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by EnableCommandIfVerbExists().

◆ ErrorBox()

UINT ErrorBox ( HWND  hwnd,
UINT  Error 
)

Definition at line 247 of file util.c.

248{
249 return SHELL_ErrorBox(hwnd, Error);
250}
BOOL Error
Definition: chkdsk.c:66
#define SHELL_ErrorBox
Definition: shellutils.h:126

Referenced by DisplayHelp().

◆ GetMenuItemIdByPos()

static int GetMenuItemIdByPos ( HMENU  hMenu,
UINT  Pos 
)
static

Definition at line 18 of file util.c.

19{
20 MENUITEMINFOW mii;
21 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */
22 mii.fMask = MIIM_ID;
23 mii.cch = 0;
24 return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) ? mii.wID : -1;
25}
ush Pos
Definition: deflate.h:92
#define MIIM_ID
Definition: winuser.h:725
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)

Referenced by EnableCommandIfVerbExistsProc(), and ModifyShellContextMenu().

◆ GetUIObjectOfPath()

HRESULT GetUIObjectOfPath ( HWND  hwnd,
PCWSTR  File,
REFIID  riid,
void **  ppv 
)

Definition at line 135 of file util.c.

136{
138 IShellFolder *pSF;
139 PCUITEMID_CHILD pidlItem;
141 *ppv = NULL;
142 if (pidl && SUCCEEDED(SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &pSF), &pidlItem)))
143 {
144 hr = IShellFolder_GetUIObjectOf(pSF, hwnd, 1, &pidlItem, riid, NULL, ppv);
145 IShellFolder_Release(pSF);
146 }
147 SHFree(pidl);
148 return hr;
149}
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1462
#define ILCreateFromPath
Definition: shlobj.h:2514
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92

Referenced by DoShellContextMenuOnFile(), and EnableCommandIfVerbExistsProc().

◆ IsMenuSeparator()

static BOOL IsMenuSeparator ( HMENU  hMenu,
UINT  Pos 
)
static

Definition at line 28 of file util.c.

29{
30 MENUITEMINFOW mii;
31 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */
32 mii.fMask = MIIM_FTYPE;
33 mii.cch = 0;
34 return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) && (mii.fType & MFT_SEPARATOR);
35}
#define MIIM_FTYPE
Definition: winuser.h:732
#define MFT_SEPARATOR
Definition: winuser.h:747

Referenced by ModifyShellContextMenu().

◆ IsSelfShellVerb()

static BOOL IsSelfShellVerb ( PCWSTR  Assoc,
PCWSTR  Verb 
)
static

Definition at line 38 of file util.c.

39{
40 WCHAR buf[MAX_PATH * 3];
43 return hr == S_OK && *Assoc == L'.' && StrStrW(buf, L",ImageView_Fullscreen");
44}
LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:590
#define MAX_PATH
Definition: compat.h:34
HRESULT WINAPI AssocQueryStringW(ASSOCF cfFlags, ASSOCSTR str, LPCWSTR pszAssoc, LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut)
Definition: assoc.c:436
unsigned long DWORD
Definition: ntddk_ex.h:95
#define S_OK
Definition: intsafe.h:52
#define L(x)
Definition: ntvdm.h:50
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:612
@ ASSOCF_NOTRUNCATE
Definition: shlwapi.h:597

Referenced by ModifyShellContextMenu().

◆ ModifyShellContextMenu()

static void ModifyShellContextMenu ( IContextMenu pCM,
HMENU  hMenu,
UINT  CmdIdFirst,
PCWSTR  Assoc 
)
static

Definition at line 47 of file util.c.

48{
49 HRESULT hr;
50 for (UINT i = 0, c = GetMenuItemCount(hMenu); i < c; ++i)
51 {
52 WCHAR buf[200];
53 UINT id = GetMenuItemIdByPos(hMenu, i);
54 if (id == (UINT)-1)
55 continue;
56
58 /* Note: We just ask for the wide string because all the items we care about come from shell32 and it handles both */
59 hr = IContextMenu_GetCommandString(pCM, id - CmdIdFirst, GCS_VERBW, NULL, (char*)buf, _countof(buf));
60 if (SUCCEEDED(hr))
61 {
63 if (IsSelfShellVerb(Assoc, buf))
64 ++remove;
65 else if (!lstrcmpiW(L"cut", buf) || !lstrcmpiW(L"paste", buf) || !lstrcmpiW(L"pastelink", buf) ||
66 !lstrcmpiW(L"delete", buf) || !lstrcmpiW(L"link", buf))
67 ++remove;
68
69 if (remove && DeleteMenu(hMenu, i, MF_BYPOSITION))
70 {
71 if (i-- > 0)
72 {
73 if (IsMenuSeparator(hMenu, i) && IsMenuSeparator(hMenu, i + 1))
74 DeleteMenu(hMenu, i, MF_BYPOSITION);
75 }
76 }
77 }
78 }
79
80 while (IsMenuSeparator(hMenu, 0) && DeleteMenu(hMenu, 0, MF_BYPOSITION)) {}
81}
#define FALSE
Definition: types.h:117
static BOOL IsMenuSeparator(HMENU hMenu, UINT Pos)
Definition: util.c:28
static BOOL IsSelfShellVerb(PCWSTR Assoc, PCWSTR Verb)
Definition: util.c:38
int remove
Definition: msacm.c:1366
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define MF_BYPOSITION
Definition: winuser.h:203

Referenced by DoShellContextMenu().

◆ ShellContextMenuWindowProc()

static LRESULT CALLBACK ShellContextMenuWindowProc ( HWND  hwnd,
UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 84 of file util.c.

85{
86 LRESULT lRes = 0;
88 lRes = DefWindowProc(hwnd, uMsg, wParam, lParam);
89 return lRes;
90}
WPARAM wParam
Definition: combotst.c:138
#define FAILED(hr)
Definition: intsafe.h:51
#define DefWindowProc
Definition: ros2win.h:31
HRESULT WINAPI SHForwardContextMenuMsg(IUnknown *pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult, BOOL useIContextMenu2)
Definition: rosordinal.c:11
LONG_PTR LRESULT
Definition: windef.h:209

Referenced by DoShellContextMenu().

◆ ShellExecuteVerb()

void ShellExecuteVerb ( HWND  hwnd,
PCWSTR  Verb,
PCWSTR  File,
BOOL  Quit 
)

Definition at line 225 of file util.c.

226{
228 if (!*File)
229 return;
230
231 sei.hwnd = hwnd;
232 sei.lpVerb = Verb;
233 sei.lpFile = File;
234 sei.nShow = SW_SHOW;
235 if (!ShellExecuteExW(&sei))
236 {
237 DPRINT1("ShellExecuteExW(%ls, %ls) failed with code %ld\n", Verb, File, GetLastError());
238 }
239 else if (Quit)
240 {
241 // Destroy the window to quit the application
243 }
244}
#define DPRINT1
Definition: precomp.h:8
#define SEE_MASK_ASYNCOK
Definition: shellapi.h:54
#define SEE_MASK_INVOKEIDLIST
Definition: shellapi.h:28
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2452
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by Preview_Edit(), and Preview_pPrintImage().

Variable Documentation

◆ g_pContextMenu

IContextMenu* g_pContextMenu = NULL

Definition at line 15 of file util.c.

Referenced by DoShellContextMenu(), and ShellContextMenuWindowProc().