2 * IContextMenu for items in the shellview
4 * Copyright 1998-2000 Juergen Schmied <juergen.schmied@debitel.net>,
5 * <juergen.schmied@metronet.de>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 #include "shell32_main.h"
35 #include "shellfolder.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
44 #define FCIDM_BASE 0x7000
48 IContextMenu3 IContextMenu3_iface
;
49 IShellExtInit IShellExtInit_iface
;
50 IObjectWithSite IObjectWithSite_iface
;
56 LPITEMIDLIST pidl
; /* root pidl */
57 LPITEMIDLIST
*apidl
; /* array of child pidls */
61 /* background menu data */
65 static inline ContextMenu
*impl_from_IContextMenu3(IContextMenu3
*iface
)
67 return CONTAINING_RECORD(iface
, ContextMenu
, IContextMenu3_iface
);
70 static inline ContextMenu
*impl_from_IShellExtInit(IShellExtInit
*iface
)
72 return CONTAINING_RECORD(iface
, ContextMenu
, IShellExtInit_iface
);
75 static inline ContextMenu
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
77 return CONTAINING_RECORD(iface
, ContextMenu
, IObjectWithSite_iface
);
80 static HRESULT WINAPI
ContextMenu_QueryInterface(IContextMenu3
*iface
, REFIID riid
, LPVOID
*ppvObj
)
82 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
84 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObj
);
88 if (IsEqualIID(riid
, &IID_IUnknown
) ||
89 IsEqualIID(riid
, &IID_IContextMenu
) ||
90 IsEqualIID(riid
, &IID_IContextMenu2
) ||
91 IsEqualIID(riid
, &IID_IContextMenu3
))
93 *ppvObj
= &This
->IContextMenu3_iface
;
95 else if (IsEqualIID(riid
, &IID_IShellExtInit
))
97 *ppvObj
= &This
->IShellExtInit_iface
;
99 else if (IsEqualIID(riid
, &IID_IObjectWithSite
))
101 *ppvObj
= &This
->IObjectWithSite_iface
;
106 IContextMenu3_AddRef(iface
);
110 TRACE("-- Interface: E_NOINTERFACE\n");
111 return E_NOINTERFACE
;
114 static ULONG WINAPI
ContextMenu_AddRef(IContextMenu3
*iface
)
116 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
117 ULONG ref
= InterlockedIncrement(&This
->ref
);
118 TRACE("(%p)->(%lu)\n", This
, ref
);
122 static ULONG WINAPI
ContextMenu_Release(IContextMenu3
*iface
)
124 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
125 ULONG ref
= InterlockedDecrement(&This
->ref
);
127 TRACE("(%p)->(%lu)\n", This
, ref
);
132 IShellFolder_Release(This
->parent
);
135 _ILFreeaPidl(This
->apidl
, This
->cidl
);
143 static UINT
max_menu_id(HMENU hmenu
, UINT offset
, UINT last
)
148 for (i
= GetMenuItemCount(hmenu
) - 1; i
>= 0; i
--)
151 memset(&item
, 0, sizeof(MENUITEMINFOW
));
152 item
.cbSize
= sizeof(MENUITEMINFOW
);
153 item
.fMask
= MIIM_ID
| MIIM_SUBMENU
| MIIM_TYPE
;
154 if (!GetMenuItemInfoW(hmenu
, i
, TRUE
, &item
))
156 if (!(item
.fType
& MFT_SEPARATOR
))
160 UINT submenu_max_id
= max_menu_id(item
.hSubMenu
, offset
, last
);
161 if (max_id
< submenu_max_id
)
162 max_id
= submenu_max_id
;
164 if (item
.wID
+ offset
<= last
)
166 if (max_id
<= item
.wID
+ offset
)
167 max_id
= item
.wID
+ offset
+ 1;
174 static HRESULT WINAPI
ItemMenu_QueryContextMenu(
175 IContextMenu3
*iface
,
182 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
185 TRACE("(%p)->(%p %d 0x%x 0x%x 0x%x )\n", This
, hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
187 if(!(CMF_DEFAULTONLY
& uFlags
) && This
->cidl
> 0)
189 HMENU hmenures
= LoadMenuW(shell32_hInstance
, MAKEINTRESOURCEW(MENU_SHV_FILE
));
191 if(uFlags
& CMF_EXPLORE
)
192 RemoveMenu(hmenures
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
194 Shell_MergeMenus(hmenu
, GetSubMenu(hmenures
, 0), indexMenu
, idCmdFirst
- FCIDM_BASE
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
195 uIDMax
= max_menu_id(GetSubMenu(hmenures
, 0), idCmdFirst
- FCIDM_BASE
, idCmdLast
);
197 DestroyMenu(hmenures
);
203 mi
.cbSize
= sizeof(mi
);
204 mi
.fMask
= MIIM_ID
| MIIM_STRING
| MIIM_FTYPE
;
207 GetMenuItemInfoW(hmenu
, FCIDM_SHVIEW_EXPLORE
- FCIDM_BASE
+ idCmdFirst
, MF_BYCOMMAND
, &mi
);
208 RemoveMenu(hmenu
, FCIDM_SHVIEW_EXPLORE
- FCIDM_BASE
+ idCmdFirst
, MF_BYCOMMAND
);
210 mi
.cbSize
= sizeof(mi
);
211 mi
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
| MIIM_STRING
;
213 mi
.fState
= MFS_ENABLED
;
214 mi
.wID
= FCIDM_SHVIEW_EXPLORE
- FCIDM_BASE
+ idCmdFirst
;
215 mi
.fType
= MFT_STRING
;
216 InsertMenuItemW(hmenu
, (uFlags
& CMF_EXPLORE
) ? 1 : 2, MF_BYPOSITION
, &mi
);
219 SetMenuDefaultItem(hmenu
, 0, MF_BYPOSITION
);
221 if(uFlags
& ~CMF_CANRENAME
)
222 RemoveMenu(hmenu
, FCIDM_SHVIEW_RENAME
- FCIDM_BASE
+ idCmdFirst
, MF_BYCOMMAND
);
225 UINT enable
= MF_BYCOMMAND
;
227 /* can't rename more than one item at a time*/
228 if (!This
->apidl
|| This
->cidl
> 1)
229 enable
|= MFS_DISABLED
;
232 DWORD attr
= SFGAO_CANRENAME
;
234 IShellFolder_GetAttributesOf(This
->parent
, 1, (LPCITEMIDLIST
*)This
->apidl
, &attr
);
235 enable
|= (attr
& SFGAO_CANRENAME
) ? MFS_ENABLED
: MFS_DISABLED
;
238 EnableMenuItem(hmenu
, FCIDM_SHVIEW_RENAME
- FCIDM_BASE
+ idCmdFirst
, enable
);
241 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, uIDMax
-idCmdFirst
);
243 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, 0);
246 /**************************************************************************
252 static void DoOpenExplore(ContextMenu
*This
, HWND hwnd
, LPCSTR verb
)
255 BOOL bFolderFound
= FALSE
;
257 SHELLEXECUTEINFOA sei
;
259 /* Find the first item in the list that is not a value. These commands
260 should never be invoked if there isn't at least one folder item in the list.*/
262 for(i
= 0; i
<This
->cidl
; i
++)
264 if(!_ILIsValue(This
->apidl
[i
]))
271 if (!bFolderFound
) return;
273 pidlFQ
= ILCombine(This
->pidl
, This
->apidl
[i
]);
275 ZeroMemory(&sei
, sizeof(sei
));
276 sei
.cbSize
= sizeof(sei
);
277 sei
.fMask
= SEE_MASK_IDLIST
| SEE_MASK_CLASSNAME
;
278 sei
.lpIDList
= pidlFQ
;
279 sei
.lpClass
= "Folder";
281 sei
.nShow
= SW_SHOWNORMAL
;
283 ShellExecuteExA(&sei
);
287 /**************************************************************************
290 * deletes the currently selected items
292 static void DoDelete(ContextMenu
*This
)
296 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
299 ISFHelper_DeleteItems(helper
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
);
300 ISFHelper_Release(helper
);
304 /**************************************************************************
307 * copies the currently selected items into the clipboard
309 static void DoCopyOrCut(ContextMenu
*This
, HWND hwnd
, BOOL cut
)
311 IDataObject
*dataobject
;
313 TRACE("(%p)->(wnd=%p, cut=%d)\n", This
, hwnd
, cut
);
315 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->parent
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
, 0, (void**)&dataobject
)))
317 OleSetClipboard(dataobject
);
318 IDataObject_Release(dataobject
);
322 /**************************************************************************
323 * Properties_AddPropSheetCallback
325 * Used by DoOpenProperties through SHCreatePropSheetExtArrayEx to add
326 * propertysheet pages from shell extensions.
328 static BOOL CALLBACK
Properties_AddPropSheetCallback(HPROPSHEETPAGE hpage
, LPARAM lparam
)
330 LPPROPSHEETHEADERW psh
= (LPPROPSHEETHEADERW
) lparam
;
331 psh
->phpage
[psh
->nPages
++] = hpage
;
336 static BOOL
format_date(FILETIME
*time
, WCHAR
*buffer
, DWORD size
)
342 if (!FileTimeToLocalFileTime(time
, &ft
))
345 if (!FileTimeToSystemTime(&ft
, &st
))
348 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buffer
, size
);
351 buffer
[ret
- 1] = ' ';
352 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buffer
+ ret
, size
- ret
);
357 static BOOL
get_program_description(WCHAR
*path
, WCHAR
*buffer
, DWORD size
)
359 WCHAR fileDescW
[41], *desc
;
360 DWORD versize
, *lang
;
365 versize
= GetFileVersionInfoSizeW(path
, NULL
);
366 if (!versize
) return FALSE
;
368 data
= malloc(versize
);
369 if (!data
) return FALSE
;
371 if (!GetFileVersionInfoW(path
, 0, versize
, data
))
374 if (!VerQueryValueW(data
, L
"\\VarFileInfo\\Translation", (LPVOID
*)&lang
, &llen
))
377 for (i
= 0; i
< llen
/ sizeof(DWORD
); i
++)
379 swprintf(fileDescW
, ARRAY_SIZE(fileDescW
), L
"\\StringFileInfo\\%04x%04x\\FileDescription",
380 LOWORD(lang
[i
]), HIWORD(lang
[i
]));
381 if (VerQueryValueW(data
, fileDescW
, (LPVOID
*)&desc
, &dlen
))
383 if (dlen
> size
- 1) dlen
= size
- 1;
384 memcpy(buffer
, desc
, dlen
* sizeof(WCHAR
));
396 struct file_properties_info
398 WCHAR path
[MAX_PATH
];
404 static void init_file_properties_dlg(HWND hwndDlg
, struct file_properties_info
*props
)
406 WCHAR buffer
[MAX_PATH
], buffer2
[MAX_PATH
];
407 WIN32_FILE_ATTRIBUTE_DATA exinfo
;
410 SetDlgItemTextW(hwndDlg
, IDC_FPROP_PATH
, props
->filename
);
411 SetDlgItemTextW(hwndDlg
, IDC_FPROP_LOCATION
, props
->dir
);
413 if (SHGetFileInfoW(props
->path
, 0, &shinfo
, sizeof(shinfo
), SHGFI_TYPENAME
|SHGFI_ICON
))
417 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_ICON
, STM_SETICON
, (WPARAM
)shinfo
.hIcon
, 0);
418 DestroyIcon(shinfo
.hIcon
);
420 if (shinfo
.szTypeName
[0])
421 SetDlgItemTextW(hwndDlg
, IDC_FPROP_TYPE
, shinfo
.szTypeName
);
424 if (!GetFileAttributesExW(props
->path
, GetFileExInfoStandard
, &exinfo
))
427 if (format_date(&exinfo
.ftCreationTime
, buffer
, ARRAY_SIZE(buffer
)))
428 SetDlgItemTextW(hwndDlg
, IDC_FPROP_CREATED
, buffer
);
430 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
)
431 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_READONLY
, BM_SETCHECK
, BST_CHECKED
, 0);
432 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
)
433 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_HIDDEN
, BM_SETCHECK
, BST_CHECKED
, 0);
434 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
)
435 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_ARCHIVE
, BM_SETCHECK
, BST_CHECKED
, 0);
437 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
439 SetDlgItemTextW(hwndDlg
, IDC_FPROP_SIZE
, L
"(unknown)");
440 /* TODO: Implement counting for directories */
444 /* Information about files only */
445 StrFormatByteSizeW(((LONGLONG
)exinfo
.nFileSizeHigh
<< 32) | exinfo
.nFileSizeLow
,
446 buffer
, ARRAY_SIZE(buffer
));
447 SetDlgItemTextW(hwndDlg
, IDC_FPROP_SIZE
, buffer
);
449 if (format_date(&exinfo
.ftLastWriteTime
, buffer
, ARRAY_SIZE(buffer
)))
450 SetDlgItemTextW(hwndDlg
, IDC_FPROP_MODIFIED
, buffer
);
451 if (format_date(&exinfo
.ftLastAccessTime
, buffer
, ARRAY_SIZE(buffer
)))
452 SetDlgItemTextW(hwndDlg
, IDC_FPROP_ACCESSED
, buffer
);
454 if (FindExecutableW(props
->path
, NULL
, buffer
) <= (HINSTANCE
)32)
457 /* Information about executables */
458 if (SHGetFileInfoW(buffer
, 0, &shinfo
, sizeof(shinfo
), SHGFI_ICON
| SHGFI_SMALLICON
) && shinfo
.hIcon
)
459 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_PROG_ICON
, STM_SETICON
, (WPARAM
)shinfo
.hIcon
, 0);
461 if (get_program_description(buffer
, buffer2
, ARRAY_SIZE(buffer2
)))
462 SetDlgItemTextW(hwndDlg
, IDC_FPROP_PROG_NAME
, buffer2
);
465 WCHAR
*p
= wcsrchr(buffer
, '\\');
466 SetDlgItemTextW(hwndDlg
, IDC_FPROP_PROG_NAME
, p
? ++p
: buffer
);
470 static INT_PTR CALLBACK
file_properties_proc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
476 LPPROPSHEETPAGEW page
= (LPPROPSHEETPAGEW
)lParam
;
477 SetWindowLongPtrW(hwndDlg
, DWLP_USER
, (LONG_PTR
)page
->lParam
);
478 init_file_properties_dlg(hwndDlg
, (struct file_properties_info
*)page
->lParam
);
483 if (LOWORD(wParam
) == IDC_FPROP_PROG_CHANGE
)
485 /* TODO: Implement file association dialog */
486 MessageBoxA(hwndDlg
, "Not implemented yet.", "Error", MB_OK
| MB_ICONEXCLAMATION
);
488 else if (LOWORD(wParam
) == IDC_FPROP_READONLY
||
489 LOWORD(wParam
) == IDC_FPROP_HIDDEN
||
490 LOWORD(wParam
) == IDC_FPROP_ARCHIVE
)
492 SendMessageW(GetParent(hwndDlg
), PSM_CHANGED
, (WPARAM
)hwndDlg
, 0);
494 else if (LOWORD(wParam
) == IDC_FPROP_PATH
&& HIWORD(wParam
) == EN_CHANGE
)
496 SendMessageW(GetParent(hwndDlg
), PSM_CHANGED
, (WPARAM
)hwndDlg
, 0);
502 LPPSHNOTIFY notify
= (LPPSHNOTIFY
)lParam
;
503 if (notify
->hdr
.code
== PSN_APPLY
)
505 struct file_properties_info
*props
= (struct file_properties_info
*)GetWindowLongPtrW(hwndDlg
, DWLP_USER
);
506 WCHAR newname
[MAX_PATH
], newpath
[MAX_PATH
];
509 attributes
= GetFileAttributesW(props
->path
);
510 if (attributes
!= INVALID_FILE_ATTRIBUTES
)
512 attributes
&= ~(FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_ARCHIVE
);
514 if (SendDlgItemMessageW(hwndDlg
, IDC_FPROP_READONLY
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
515 attributes
|= FILE_ATTRIBUTE_READONLY
;
516 if (SendDlgItemMessageW(hwndDlg
, IDC_FPROP_HIDDEN
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
517 attributes
|= FILE_ATTRIBUTE_HIDDEN
;
518 if (SendDlgItemMessageW(hwndDlg
, IDC_FPROP_ARCHIVE
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
519 attributes
|= FILE_ATTRIBUTE_ARCHIVE
;
521 if (!SetFileAttributesW(props
->path
, attributes
))
522 ERR("failed to update file attributes of %s\n", debugstr_w(props
->path
));
525 /* Update filename if it was changed */
526 if (GetDlgItemTextW(hwndDlg
, IDC_FPROP_PATH
, newname
, ARRAY_SIZE(newname
)) &&
527 wcscmp(props
->filename
, newname
) &&
528 lstrlenW(props
->dir
) + lstrlenW(newname
) + 2 < ARRAY_SIZE(newpath
))
530 lstrcpyW(newpath
, props
->dir
);
531 lstrcatW(newpath
, L
"\\");
532 lstrcatW(newpath
, newname
);
534 if (!MoveFileW(props
->path
, newpath
))
535 ERR("failed to move file %s to %s\n", debugstr_w(props
->path
), debugstr_w(newpath
));
539 lstrcpyW(props
->path
, newpath
);
540 lstrcpyW(props
->dir
, newpath
);
541 if ((p
= wcsrchr(props
->dir
, '\\')))
544 props
->filename
= p
+ 1;
547 props
->filename
= props
->dir
;
548 SetDlgItemTextW(hwndDlg
, IDC_FPROP_LOCATION
, props
->dir
);
563 static UINT CALLBACK
file_properties_callback(HWND hwnd
, UINT uMsg
, LPPROPSHEETPAGEW page
)
565 struct file_properties_info
*props
= (struct file_properties_info
*)page
->lParam
;
566 if (uMsg
== PSPCB_RELEASE
)
573 static void init_file_properties_pages(IDataObject
*dataobject
, LPFNADDPROPSHEETPAGE lpfnAddPage
, LPARAM lParam
)
575 struct file_properties_info
*props
;
576 HPROPSHEETPAGE general_page
;
577 PROPSHEETPAGEW propsheet
;
583 props
= malloc(sizeof(*props
));
586 format
.cfFormat
= CF_HDROP
;
588 format
.dwAspect
= DVASPECT_CONTENT
;
590 format
.tymed
= TYMED_HGLOBAL
;
592 hr
= IDataObject_GetData(dataobject
, &format
, &stgm
);
593 if (FAILED(hr
)) goto error
;
595 if (!DragQueryFileW((HDROP
)stgm
.hGlobal
, 0, props
->path
, ARRAY_SIZE(props
->path
)))
597 ReleaseStgMedium(&stgm
);
601 ReleaseStgMedium(&stgm
);
603 props
->attrib
= GetFileAttributesW(props
->path
);
604 if (props
->attrib
== INVALID_FILE_ATTRIBUTES
)
607 lstrcpyW(props
->dir
, props
->path
);
608 if ((p
= wcsrchr(props
->dir
, '\\')))
611 props
->filename
= p
+ 1;
614 props
->filename
= props
->dir
;
616 memset(&propsheet
, 0, sizeof(propsheet
));
617 propsheet
.dwSize
= sizeof(propsheet
);
618 propsheet
.dwFlags
= PSP_DEFAULT
| PSP_USECALLBACK
;
619 propsheet
.hInstance
= shell32_hInstance
;
620 if (props
->attrib
& FILE_ATTRIBUTE_DIRECTORY
)
621 propsheet
.pszTemplate
= (LPWSTR
)MAKEINTRESOURCE(IDD_FOLDER_PROPERTIES
);
623 propsheet
.pszTemplate
= (LPWSTR
)MAKEINTRESOURCE(IDD_FILE_PROPERTIES
);
624 propsheet
.pfnDlgProc
= file_properties_proc
;
625 propsheet
.pfnCallback
= file_properties_callback
;
626 propsheet
.lParam
= (LPARAM
)props
;
628 general_page
= CreatePropertySheetPageW(&propsheet
);
630 lpfnAddPage(general_page
, lParam
);
637 #define MAX_PROP_PAGES 99
639 static void DoOpenProperties(ContextMenu
*This
, HWND hwnd
)
641 LPSHELLFOLDER lpDesktopSF
;
644 WCHAR wszFiletype
[MAX_PATH
];
645 WCHAR wszFilename
[MAX_PATH
];
646 PROPSHEETHEADERW psh
;
647 HPROPSHEETPAGE hpages
[MAX_PROP_PAGES
];
651 TRACE("(%p)->(wnd=%p)\n", This
, hwnd
);
653 ZeroMemory(&psh
, sizeof(PROPSHEETHEADERW
));
654 psh
.dwSize
= sizeof (PROPSHEETHEADERW
);
655 psh
.hwndParent
= hwnd
;
656 psh
.dwFlags
= PSH_PROPTITLE
;
661 _ILSimpleGetTextW(This
->apidl
[0], (LPVOID
)wszFilename
, MAX_PATH
);
662 psh
.pszCaption
= (LPCWSTR
)wszFilename
;
664 /* Find out where to look for the shell extensions */
665 if (_ILIsValue(This
->apidl
[0]))
669 if (_ILGetExtension(This
->apidl
[0], sTemp
, 64))
671 HCR_MapTypeToValueA(sTemp
, sTemp
, 64, TRUE
);
672 MultiByteToWideChar(CP_ACP
, 0, sTemp
, -1, wszFiletype
, MAX_PATH
);
679 else if (_ILIsFolder(This
->apidl
[0]))
681 lstrcpynW(wszFiletype
, L
"Folder", 64);
683 else if (_ILIsSpecialFolder(This
->apidl
[0]))
686 folderGUID
= _ILGetGUIDPointer(This
->apidl
[0]);
687 lstrcpyW(wszFiletype
, L
"CLSID\\");
688 StringFromGUID2(folderGUID
, &wszFiletype
[6], MAX_PATH
- 6);
692 FIXME("Requested properties for unknown type.\n");
696 /* Get a suitable DataObject for accessing the files */
697 SHGetDesktopFolder(&lpDesktopSF
);
698 if (_ILIsPidlSimple(This
->pidl
))
700 ret
= IShellFolder_GetUIObjectOf(lpDesktopSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
701 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
702 IShellFolder_Release(lpDesktopSF
);
706 IShellFolder_BindToObject(lpDesktopSF
, This
->pidl
, NULL
, &IID_IShellFolder
, (LPVOID
*) &lpSF
);
707 ret
= IShellFolder_GetUIObjectOf(lpSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
708 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
709 IShellFolder_Release(lpSF
);
710 IShellFolder_Release(lpDesktopSF
);
715 init_file_properties_pages(lpDo
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
717 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszFiletype
, MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
720 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
721 SHDestroyPropSheetExtArray(hpsxa
);
723 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"*", MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
726 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
727 SHDestroyPropSheetExtArray(hpsxa
);
729 IDataObject_Release(lpDo
);
733 PropertySheetW(&psh
);
735 FIXME("No property pages found.\n");
738 static HRESULT WINAPI
ItemMenu_InvokeCommand(
739 IContextMenu3
*iface
,
740 LPCMINVOKECOMMANDINFO lpcmi
)
742 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
744 if (lpcmi
->cbSize
!= sizeof(CMINVOKECOMMANDINFO
))
745 FIXME("Is an EX structure\n");
747 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This
,lpcmi
,lpcmi
->lpVerb
, lpcmi
->hwnd
);
749 if (IS_INTRESOURCE(lpcmi
->lpVerb
) && LOWORD(lpcmi
->lpVerb
) > FCIDM_SHVIEWLAST
)
751 TRACE("Invalid Verb %x\n", LOWORD(lpcmi
->lpVerb
));
755 if (IS_INTRESOURCE(lpcmi
->lpVerb
))
757 switch(LOWORD(lpcmi
->lpVerb
) + FCIDM_BASE
)
759 case FCIDM_SHVIEW_EXPLORE
:
760 TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
761 DoOpenExplore(This
, lpcmi
->hwnd
, "explore");
763 case FCIDM_SHVIEW_OPEN
:
764 TRACE("Verb FCIDM_SHVIEW_OPEN\n");
765 DoOpenExplore(This
, lpcmi
->hwnd
, "open");
767 case FCIDM_SHVIEW_RENAME
:
769 IShellBrowser
*browser
;
771 /* get the active IShellView */
772 browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0);
777 if(SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
779 TRACE("(shellview=%p)\n", view
);
780 IShellView_SelectItem(view
, This
->apidl
[0],
781 SVSI_DESELECTOTHERS
|SVSI_EDIT
|SVSI_ENSUREVISIBLE
|SVSI_FOCUSED
|SVSI_SELECT
);
782 IShellView_Release(view
);
787 case FCIDM_SHVIEW_DELETE
:
788 TRACE("Verb FCIDM_SHVIEW_DELETE\n");
791 case FCIDM_SHVIEW_COPY
:
792 TRACE("Verb FCIDM_SHVIEW_COPY\n");
793 DoCopyOrCut(This
, lpcmi
->hwnd
, FALSE
);
795 case FCIDM_SHVIEW_CUT
:
796 TRACE("Verb FCIDM_SHVIEW_CUT\n");
797 DoCopyOrCut(This
, lpcmi
->hwnd
, TRUE
);
799 case FCIDM_SHVIEW_PROPERTIES
:
800 TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
801 DoOpenProperties(This
, lpcmi
->hwnd
);
804 FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi
->lpVerb
));
810 TRACE("Verb is %s\n",debugstr_a(lpcmi
->lpVerb
));
811 if (strcmp(lpcmi
->lpVerb
,"delete")==0)
813 else if (strcmp(lpcmi
->lpVerb
,"copy")==0)
814 DoCopyOrCut(This
, lpcmi
->hwnd
, FALSE
);
815 else if (strcmp(lpcmi
->lpVerb
,"cut")==0)
816 DoCopyOrCut(This
, lpcmi
->hwnd
, TRUE
);
817 else if (strcmp(lpcmi
->lpVerb
,"properties")==0)
818 DoOpenProperties(This
, lpcmi
->hwnd
);
820 FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi
->lpVerb
));
827 static HRESULT WINAPI
ItemMenu_GetCommandString(IContextMenu3
*iface
, UINT_PTR cmdid
, UINT flags
,
828 UINT
*reserved
, LPSTR name
, UINT maxlen
)
830 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
831 const WCHAR
*cmdW
= NULL
;
834 TRACE("(%p)->(%Ix, %#x, %p, %p, %u)\n", This
, cmdid
, flags
, reserved
, name
, maxlen
);
845 switch (cmdid
+ FCIDM_BASE
)
847 case FCIDM_SHVIEW_OPEN
:
850 case FCIDM_SHVIEW_EXPLORE
:
853 case FCIDM_SHVIEW_CUT
:
856 case FCIDM_SHVIEW_COPY
:
859 case FCIDM_SHVIEW_CREATELINK
:
862 case FCIDM_SHVIEW_DELETE
:
865 case FCIDM_SHVIEW_PROPERTIES
:
866 cmdW
= L
"properties";
868 case FCIDM_SHVIEW_RENAME
:
879 if (flags
== GCS_VERBA
)
880 WideCharToMultiByte(CP_ACP
, 0, cmdW
, -1, name
, maxlen
, NULL
, NULL
);
882 lstrcpynW((WCHAR
*)name
, cmdW
, maxlen
);
884 TRACE("name %s\n", flags
== GCS_VERBA
? debugstr_a(name
) : debugstr_w((WCHAR
*)name
));
895 /**************************************************************************
897 * should be only in IContextMenu2 and IContextMenu3
898 * is nevertheless called from word95
900 static HRESULT WINAPI
ContextMenu_HandleMenuMsg(IContextMenu3
*iface
, UINT msg
,
901 WPARAM wParam
, LPARAM lParam
)
903 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
904 FIXME("(%p)->(0x%x 0x%Ix 0x%Ix): stub\n", This
, msg
, wParam
, lParam
);
908 static HRESULT WINAPI
ContextMenu_HandleMenuMsg2(IContextMenu3
*iface
, UINT msg
,
909 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
911 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
912 FIXME("(%p)->(0x%x 0x%Ix 0x%Ix %p): stub\n", This
, msg
, wParam
, lParam
, result
);
916 static const IContextMenu3Vtbl ItemContextMenuVtbl
=
918 ContextMenu_QueryInterface
,
921 ItemMenu_QueryContextMenu
,
922 ItemMenu_InvokeCommand
,
923 ItemMenu_GetCommandString
,
924 ContextMenu_HandleMenuMsg
,
925 ContextMenu_HandleMenuMsg2
928 static HRESULT WINAPI
ShellExtInit_QueryInterface(IShellExtInit
*iface
, REFIID riid
, void **obj
)
930 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
931 return IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, obj
);
934 static ULONG WINAPI
ShellExtInit_AddRef(IShellExtInit
*iface
)
936 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
937 return IContextMenu3_AddRef(&This
->IContextMenu3_iface
);
940 static ULONG WINAPI
ShellExtInit_Release(IShellExtInit
*iface
)
942 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
943 return IContextMenu3_Release(&This
->IContextMenu3_iface
);
946 static HRESULT WINAPI
ShellExtInit_Initialize(IShellExtInit
*iface
, LPCITEMIDLIST folder
,
947 IDataObject
*dataobj
, HKEY progidkey
)
949 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
951 FIXME("(%p)->(%p %p %p): stub\n", This
, folder
, dataobj
, progidkey
);
956 static const IShellExtInitVtbl ShellExtInitVtbl
=
958 ShellExtInit_QueryInterface
,
960 ShellExtInit_Release
,
961 ShellExtInit_Initialize
964 static HRESULT WINAPI
ObjectWithSite_QueryInterface(IObjectWithSite
*iface
, REFIID riid
, void **obj
)
966 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
967 return IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, obj
);
970 static ULONG WINAPI
ObjectWithSite_AddRef(IObjectWithSite
*iface
)
972 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
973 return IContextMenu3_AddRef(&This
->IContextMenu3_iface
);
976 static ULONG WINAPI
ObjectWithSite_Release(IObjectWithSite
*iface
)
978 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
979 return IContextMenu3_Release(&This
->IContextMenu3_iface
);
982 static HRESULT WINAPI
ObjectWithSite_SetSite(IObjectWithSite
*iface
, IUnknown
*site
)
984 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
986 FIXME("(%p)->(%p): stub\n", This
, site
);
991 static HRESULT WINAPI
ObjectWithSite_GetSite(IObjectWithSite
*iface
, REFIID riid
, void **site
)
993 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
995 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_guid(riid
), site
);
1000 static const IObjectWithSiteVtbl ObjectWithSiteVtbl
=
1002 ObjectWithSite_QueryInterface
,
1003 ObjectWithSite_AddRef
,
1004 ObjectWithSite_Release
,
1005 ObjectWithSite_SetSite
,
1006 ObjectWithSite_GetSite
,
1009 HRESULT
ItemMenu_Constructor(IShellFolder
*parent
, LPCITEMIDLIST pidl
, const LPCITEMIDLIST
*apidl
, UINT cidl
,
1010 REFIID riid
, void **pObj
)
1016 This
= malloc(sizeof(*This
));
1017 if (!This
) return E_OUTOFMEMORY
;
1019 This
->IContextMenu3_iface
.lpVtbl
= &ItemContextMenuVtbl
;
1020 This
->IShellExtInit_iface
.lpVtbl
= &ShellExtInitVtbl
;
1021 This
->IObjectWithSite_iface
.lpVtbl
= &ObjectWithSiteVtbl
;
1023 This
->parent
= parent
;
1024 if (parent
) IShellFolder_AddRef(parent
);
1026 This
->pidl
= ILClone(pidl
);
1027 This
->apidl
= _ILCopyaPidl(apidl
, cidl
);
1029 This
->allvalues
= TRUE
;
1031 This
->desktop
= FALSE
;
1033 for (i
= 0; i
< cidl
; i
++)
1034 This
->allvalues
&= (_ILIsValue(apidl
[i
]) ? 1 : 0);
1036 hr
= IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, pObj
);
1037 IContextMenu3_Release(&This
->IContextMenu3_iface
);
1042 /* Background menu implementation */
1043 static HRESULT WINAPI
BackgroundMenu_QueryContextMenu(
1044 IContextMenu3
*iface
,
1051 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
1056 TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
1057 This
, hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
1059 hMyMenu
= LoadMenuA(shell32_hInstance
, "MENU_002");
1060 if (uFlags
& CMF_DEFAULTONLY
)
1062 HMENU ourMenu
= GetSubMenu(hMyMenu
,0);
1063 UINT oldDef
= GetMenuDefaultItem(hMenu
,TRUE
,GMDI_USEDISABLED
);
1064 UINT newDef
= GetMenuDefaultItem(ourMenu
,TRUE
,GMDI_USEDISABLED
);
1065 if (newDef
!= oldDef
)
1066 SetMenuDefaultItem(hMenu
,newDef
,TRUE
);
1067 if (newDef
!=0xFFFFFFFF)
1068 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, newDef
+1);
1070 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
1074 Shell_MergeMenus (hMenu
, GetSubMenu(hMyMenu
,0), indexMenu
,
1075 idCmdFirst
- FCIDM_BASE
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
1076 idMax
= max_menu_id(GetSubMenu(hMyMenu
, 0), idCmdFirst
- FCIDM_BASE
, idCmdLast
);
1077 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, idMax
-idCmdFirst
);
1079 DestroyMenu(hMyMenu
);
1081 TRACE("(%p)->returning 0x%lx\n",This
,hr
);
1085 static void DoNewFolder(ContextMenu
*This
, IShellView
*view
)
1089 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
1092 WCHAR nameW
[MAX_PATH
];
1095 ISFHelper_GetUniqueName(helper
, nameW
, MAX_PATH
);
1096 ISFHelper_AddFolder(helper
, 0, nameW
, &pidl
);
1100 /* if we are in a shellview do labeledit */
1101 IShellView_SelectItem(view
,
1102 pidl
,(SVSI_DESELECTOTHERS
| SVSI_EDIT
| SVSI_ENSUREVISIBLE
1103 |SVSI_FOCUSED
|SVSI_SELECT
));
1107 ISFHelper_Release(helper
);
1111 static HRESULT
paste_pidls(ContextMenu
*This
, ITEMIDLIST
**pidls
, UINT count
)
1113 IShellFolder
*psfDesktop
;
1117 /* bind to the source shellfolder */
1118 hr
= SHGetDesktopFolder(&psfDesktop
);
1122 for (i
= 0; SUCCEEDED(hr
) && i
< count
; i
++) {
1123 ITEMIDLIST
*pidl_dir
= NULL
;
1124 ITEMIDLIST
*pidl_item
;
1125 IShellFolder
*psfFrom
= NULL
;
1127 pidl_dir
= ILClone(pidls
[i
]);
1128 ILRemoveLastID(pidl_dir
);
1129 pidl_item
= ILFindLastID(pidls
[i
]);
1130 hr
= IShellFolder_BindToObject(psfDesktop
, pidl_dir
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfFrom
);
1134 /* get source and destination shellfolder */
1135 ISFHelper
*psfhlpdst
= NULL
, *psfhlpsrc
= NULL
;
1136 hr
= IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&psfhlpdst
);
1138 hr
= IShellFolder_QueryInterface(psfFrom
, &IID_ISFHelper
, (void**)&psfhlpsrc
);
1140 /* do the copy/move */
1141 if (psfhlpdst
&& psfhlpsrc
)
1143 hr
= ISFHelper_CopyItems(psfhlpdst
, psfFrom
, 1, (LPCITEMIDLIST
*)&pidl_item
);
1144 /* FIXME handle move
1145 ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item);
1148 if(psfhlpdst
) ISFHelper_Release(psfhlpdst
);
1149 if(psfhlpsrc
) ISFHelper_Release(psfhlpsrc
);
1150 IShellFolder_Release(psfFrom
);
1155 IShellFolder_Release(psfDesktop
);
1159 static HRESULT
DoPaste(ContextMenu
*This
)
1166 hr
= OleGetClipboard(&pda
);
1170 FORMATETC formatetc
;
1173 TRACE("pda=%p\n", pda
);
1175 /* Set the FORMATETC structure*/
1176 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
), TYMED_HGLOBAL
);
1178 /* Get the pidls from IDataObject */
1179 format_hr
= IDataObject_GetData(pda
,&formatetc
,&medium
);
1180 if(SUCCEEDED(format_hr
))
1182 LPITEMIDLIST
* apidl
;
1185 LPIDA lpcida
= GlobalLock(medium
.hGlobal
);
1186 TRACE("cida=%p\n", lpcida
);
1189 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
1192 hr
= paste_pidls(This
, apidl
, lpcida
->cidl
);
1193 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1197 hr
= HRESULT_FROM_WIN32(GetLastError());
1198 GlobalUnlock(medium
.hGlobal
);
1201 hr
= HRESULT_FROM_WIN32(GetLastError());
1202 ReleaseStgMedium(&medium
);
1205 if(FAILED(format_hr
))
1207 InitFormatEtc(formatetc
, CF_HDROP
, TYMED_HGLOBAL
);
1208 format_hr
= IDataObject_GetData(pda
,&formatetc
,&medium
);
1209 if(SUCCEEDED(format_hr
))
1211 WCHAR path
[MAX_PATH
];
1215 TRACE("CF_HDROP=%p\n", medium
.hGlobal
);
1216 count
= DragQueryFileW(medium
.hGlobal
, -1, NULL
, 0);
1217 pidls
= SHAlloc(count
*sizeof(ITEMIDLIST
*));
1220 for (i
= 0; i
< count
; i
++)
1222 DragQueryFileW(medium
.hGlobal
, i
, path
, ARRAY_SIZE(path
));
1223 if ((pidls
[i
] = ILCreateFromPathW(path
)) == NULL
)
1230 hr
= paste_pidls(This
, pidls
, count
);
1231 _ILFreeaPidl(pidls
, count
);
1234 hr
= HRESULT_FROM_WIN32(GetLastError());
1235 ReleaseStgMedium(&medium
);
1239 if (FAILED(format_hr
))
1241 ERR("there are no supported and retrievable clipboard formats\n");
1245 IDataObject_Release(pda
);
1250 OpenClipboard(NULL
);
1251 hMem
= GetClipboardData(CF_HDROP
);
1255 char * pDropFiles
= GlobalLock(hMem
);
1258 int len
, offset
= sizeof(DROPFILESTRUCT
);
1260 while( pDropFiles
[offset
] != 0)
1262 len
= strlen(pDropFiles
+ offset
);
1263 TRACE("%s\n", pDropFiles
+ offset
);
1274 static HRESULT WINAPI
BackgroundMenu_InvokeCommand(
1275 IContextMenu3
*iface
,
1276 LPCMINVOKECOMMANDINFO lpcmi
)
1278 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
1279 IShellBrowser
*browser
;
1280 IShellView
*view
= NULL
;
1283 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", This
, lpcmi
, lpcmi
->lpVerb
, lpcmi
->hwnd
);
1285 /* get the active IShellView */
1286 if ((browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0)))
1288 if (SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
1289 IShellView_GetWindow(view
, &hWnd
);
1292 if(HIWORD(lpcmi
->lpVerb
))
1294 TRACE("%s\n", debugstr_a(lpcmi
->lpVerb
));
1296 if (!strcmp(lpcmi
->lpVerb
, CMDSTR_NEWFOLDERA
))
1298 DoNewFolder(This
, view
);
1300 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWLISTA
))
1302 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW
, 0), 0);
1304 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWDETAILSA
))
1306 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW
, 0), 0);
1308 else if (!strcmp(lpcmi
->lpVerb
, "paste"))
1314 FIXME("please report: unknown verb %s\n", debugstr_a(lpcmi
->lpVerb
));
1319 switch (LOWORD(lpcmi
->lpVerb
) + FCIDM_BASE
)
1321 case FCIDM_SHVIEW_REFRESH
:
1322 if (view
) IShellView_Refresh(view
);
1325 case FCIDM_SHVIEW_NEWFOLDER
:
1326 DoNewFolder(This
, view
);
1329 case FCIDM_SHVIEW_INSERT
:
1333 case FCIDM_SHVIEW_PROPERTIES
:
1334 if (This
->desktop
) {
1335 ShellExecuteA(lpcmi
->hwnd
, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL
, NULL
, SW_SHOWNORMAL
);
1337 FIXME("launch item properties dialog\n");
1342 /* if it's an id just pass it to the parent shv */
1343 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(LOWORD(lpcmi
->lpVerb
), 0), 0);
1349 IShellView_Release(view
);
1354 static HRESULT WINAPI
BackgroundMenu_GetCommandString(
1355 IContextMenu3
*iface
,
1362 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
1363 const WCHAR
*cmdW
= NULL
;
1364 HRESULT hr
= E_FAIL
;
1366 TRACE("(%p)->(idcom=%Ix flags=%x %p name=%p len=%x)\n",This
, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
1377 switch (idCommand
+ FCIDM_BASE
)
1379 case FCIDM_SHVIEW_INSERT
:
1382 case FCIDM_SHVIEW_PROPERTIES
:
1383 cmdW
= L
"properties";
1393 if (uFlags
== GCS_VERBA
)
1394 WideCharToMultiByte(CP_ACP
, 0, cmdW
, -1, lpszName
, uMaxNameLen
, NULL
, NULL
);
1396 lstrcpynW((WCHAR
*)lpszName
, cmdW
, uMaxNameLen
);
1397 TRACE("name %s\n", uFlags
== GCS_VERBA
? debugstr_a(lpszName
) : debugstr_w((WCHAR
*)lpszName
));
1403 /* test the existence of the menu items, the file dialog enables
1404 the buttons according to this */
1405 if (HIWORD(idCommand
))
1407 if (!strcmp((LPSTR
)idCommand
, CMDSTR_VIEWLISTA
) ||
1408 !strcmp((LPSTR
)idCommand
, CMDSTR_VIEWDETAILSA
) ||
1409 !strcmp((LPSTR
)idCommand
, CMDSTR_NEWFOLDERA
))
1413 FIXME("unknown command string %s\n", uFlags
== GCS_VALIDATEA
? debugstr_a((LPSTR
)idCommand
) : debugstr_w((WCHAR
*)idCommand
));
1422 static const IContextMenu3Vtbl BackgroundContextMenuVtbl
=
1424 ContextMenu_QueryInterface
,
1426 ContextMenu_Release
,
1427 BackgroundMenu_QueryContextMenu
,
1428 BackgroundMenu_InvokeCommand
,
1429 BackgroundMenu_GetCommandString
,
1430 ContextMenu_HandleMenuMsg
,
1431 ContextMenu_HandleMenuMsg2
1434 HRESULT
BackgroundMenu_Constructor(IShellFolder
*parent
, BOOL desktop
, REFIID riid
, void **pObj
)
1439 This
= malloc(sizeof(*This
));
1440 if (!This
) return E_OUTOFMEMORY
;
1442 This
->IContextMenu3_iface
.lpVtbl
= &BackgroundContextMenuVtbl
;
1443 This
->IShellExtInit_iface
.lpVtbl
= &ShellExtInitVtbl
;
1444 This
->IObjectWithSite_iface
.lpVtbl
= &ObjectWithSiteVtbl
;
1446 This
->parent
= parent
;
1451 This
->allvalues
= FALSE
;
1453 This
->desktop
= desktop
;
1454 if (parent
) IShellFolder_AddRef(parent
);
1456 hr
= IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, pObj
);
1457 IContextMenu3_Release(&This
->IContextMenu3_iface
);