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
25 #define NONAMELESSUNION
32 #include "undocshell.h"
37 #include "shell32_main.h"
38 #include "shellfolder.h"
43 #include "wine/heap.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
48 #define FCIDM_BASE 0x7000
52 IContextMenu3 IContextMenu3_iface
;
53 IShellExtInit IShellExtInit_iface
;
54 IObjectWithSite IObjectWithSite_iface
;
60 LPITEMIDLIST pidl
; /* root pidl */
61 LPITEMIDLIST
*apidl
; /* array of child pidls */
65 /* background menu data */
69 static inline ContextMenu
*impl_from_IContextMenu3(IContextMenu3
*iface
)
71 return CONTAINING_RECORD(iface
, ContextMenu
, IContextMenu3_iface
);
74 static inline ContextMenu
*impl_from_IShellExtInit(IShellExtInit
*iface
)
76 return CONTAINING_RECORD(iface
, ContextMenu
, IShellExtInit_iface
);
79 static inline ContextMenu
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
81 return CONTAINING_RECORD(iface
, ContextMenu
, IObjectWithSite_iface
);
84 static HRESULT WINAPI
ContextMenu_QueryInterface(IContextMenu3
*iface
, REFIID riid
, LPVOID
*ppvObj
)
86 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
88 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObj
);
92 if (IsEqualIID(riid
, &IID_IUnknown
) ||
93 IsEqualIID(riid
, &IID_IContextMenu
) ||
94 IsEqualIID(riid
, &IID_IContextMenu2
) ||
95 IsEqualIID(riid
, &IID_IContextMenu3
))
97 *ppvObj
= &This
->IContextMenu3_iface
;
99 else if (IsEqualIID(riid
, &IID_IShellExtInit
))
101 *ppvObj
= &This
->IShellExtInit_iface
;
103 else if (IsEqualIID(riid
, &IID_IObjectWithSite
))
105 *ppvObj
= &This
->IObjectWithSite_iface
;
110 IContextMenu3_AddRef(iface
);
114 TRACE("-- Interface: E_NOINTERFACE\n");
115 return E_NOINTERFACE
;
118 static ULONG WINAPI
ContextMenu_AddRef(IContextMenu3
*iface
)
120 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
121 ULONG ref
= InterlockedIncrement(&This
->ref
);
122 TRACE("(%p)->(%u)\n", This
, ref
);
126 static ULONG WINAPI
ContextMenu_Release(IContextMenu3
*iface
)
128 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
129 ULONG ref
= InterlockedDecrement(&This
->ref
);
131 TRACE("(%p)->(%u)\n", This
, ref
);
136 IShellFolder_Release(This
->parent
);
139 _ILFreeaPidl(This
->apidl
, This
->cidl
);
147 static UINT
max_menu_id(HMENU hmenu
, UINT offset
, UINT last
)
152 for (i
= GetMenuItemCount(hmenu
) - 1; i
>= 0; i
--)
155 memset(&item
, 0, sizeof(MENUITEMINFOW
));
156 item
.cbSize
= sizeof(MENUITEMINFOW
);
157 item
.fMask
= MIIM_ID
| MIIM_SUBMENU
| MIIM_TYPE
;
158 if (!GetMenuItemInfoW(hmenu
, i
, TRUE
, &item
))
160 if (!(item
.fType
& MFT_SEPARATOR
))
164 UINT submenu_max_id
= max_menu_id(item
.hSubMenu
, offset
, last
);
165 if (max_id
< submenu_max_id
)
166 max_id
= submenu_max_id
;
168 if (item
.wID
+ offset
<= last
)
170 if (max_id
<= item
.wID
+ offset
)
171 max_id
= item
.wID
+ offset
+ 1;
178 static HRESULT WINAPI
ItemMenu_QueryContextMenu(
179 IContextMenu3
*iface
,
186 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
189 TRACE("(%p)->(%p %d 0x%x 0x%x 0x%x )\n", This
, hmenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
191 if(!(CMF_DEFAULTONLY
& uFlags
) && This
->cidl
> 0)
193 HMENU hmenures
= LoadMenuW(shell32_hInstance
, MAKEINTRESOURCEW(MENU_SHV_FILE
));
195 if(uFlags
& CMF_EXPLORE
)
196 RemoveMenu(hmenures
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
198 Shell_MergeMenus(hmenu
, GetSubMenu(hmenures
, 0), indexMenu
, idCmdFirst
- FCIDM_BASE
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
199 uIDMax
= max_menu_id(GetSubMenu(hmenures
, 0), idCmdFirst
- FCIDM_BASE
, idCmdLast
);
201 DestroyMenu(hmenures
);
207 mi
.cbSize
= sizeof(mi
);
208 mi
.fMask
= MIIM_ID
| MIIM_STRING
| MIIM_FTYPE
;
211 GetMenuItemInfoW(hmenu
, FCIDM_SHVIEW_EXPLORE
- FCIDM_BASE
+ idCmdFirst
, MF_BYCOMMAND
, &mi
);
212 RemoveMenu(hmenu
, FCIDM_SHVIEW_EXPLORE
- FCIDM_BASE
+ idCmdFirst
, MF_BYCOMMAND
);
214 mi
.cbSize
= sizeof(mi
);
215 mi
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
| MIIM_STRING
;
217 mi
.fState
= MFS_ENABLED
;
218 mi
.wID
= FCIDM_SHVIEW_EXPLORE
- FCIDM_BASE
+ idCmdFirst
;
219 mi
.fType
= MFT_STRING
;
220 InsertMenuItemW(hmenu
, (uFlags
& CMF_EXPLORE
) ? 1 : 2, MF_BYPOSITION
, &mi
);
223 SetMenuDefaultItem(hmenu
, 0, MF_BYPOSITION
);
225 if(uFlags
& ~CMF_CANRENAME
)
226 RemoveMenu(hmenu
, FCIDM_SHVIEW_RENAME
- FCIDM_BASE
+ idCmdFirst
, MF_BYCOMMAND
);
229 UINT enable
= MF_BYCOMMAND
;
231 /* can't rename more than one item at a time*/
232 if (!This
->apidl
|| This
->cidl
> 1)
233 enable
|= MFS_DISABLED
;
236 DWORD attr
= SFGAO_CANRENAME
;
238 IShellFolder_GetAttributesOf(This
->parent
, 1, (LPCITEMIDLIST
*)This
->apidl
, &attr
);
239 enable
|= (attr
& SFGAO_CANRENAME
) ? MFS_ENABLED
: MFS_DISABLED
;
242 EnableMenuItem(hmenu
, FCIDM_SHVIEW_RENAME
- FCIDM_BASE
+ idCmdFirst
, enable
);
245 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, uIDMax
-idCmdFirst
);
247 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, 0);
250 /**************************************************************************
256 static void DoOpenExplore(ContextMenu
*This
, HWND hwnd
, LPCSTR verb
)
259 BOOL bFolderFound
= FALSE
;
261 SHELLEXECUTEINFOA sei
;
263 /* Find the first item in the list that is not a value. These commands
264 should never be invoked if there isn't at least one folder item in the list.*/
266 for(i
= 0; i
<This
->cidl
; i
++)
268 if(!_ILIsValue(This
->apidl
[i
]))
275 if (!bFolderFound
) return;
277 pidlFQ
= ILCombine(This
->pidl
, This
->apidl
[i
]);
279 ZeroMemory(&sei
, sizeof(sei
));
280 sei
.cbSize
= sizeof(sei
);
281 sei
.fMask
= SEE_MASK_IDLIST
| SEE_MASK_CLASSNAME
;
282 sei
.lpIDList
= pidlFQ
;
283 sei
.lpClass
= "Folder";
285 sei
.nShow
= SW_SHOWNORMAL
;
287 ShellExecuteExA(&sei
);
291 /**************************************************************************
294 * deletes the currently selected items
296 static void DoDelete(ContextMenu
*This
)
300 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
303 ISFHelper_DeleteItems(helper
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
);
304 ISFHelper_Release(helper
);
308 /**************************************************************************
311 * copies the currently selected items into the clipboard
313 static void DoCopyOrCut(ContextMenu
*This
, HWND hwnd
, BOOL cut
)
315 IDataObject
*dataobject
;
317 TRACE("(%p)->(wnd=%p, cut=%d)\n", This
, hwnd
, cut
);
319 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->parent
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
, 0, (void**)&dataobject
)))
321 OleSetClipboard(dataobject
);
322 IDataObject_Release(dataobject
);
326 /**************************************************************************
327 * Properties_AddPropSheetCallback
329 * Used by DoOpenProperties through SHCreatePropSheetExtArrayEx to add
330 * propertysheet pages from shell extensions.
332 static BOOL CALLBACK
Properties_AddPropSheetCallback(HPROPSHEETPAGE hpage
, LPARAM lparam
)
334 LPPROPSHEETHEADERW psh
= (LPPROPSHEETHEADERW
) lparam
;
335 psh
->u3
.phpage
[psh
->nPages
++] = hpage
;
340 static BOOL
format_date(FILETIME
*time
, WCHAR
*buffer
, DWORD size
)
346 if (!FileTimeToLocalFileTime(time
, &ft
))
349 if (!FileTimeToSystemTime(&ft
, &st
))
352 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, buffer
, size
);
355 buffer
[ret
- 1] = ' ';
356 ret
= GetTimeFormatW(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, buffer
+ ret
, size
- ret
);
361 static BOOL
get_program_description(WCHAR
*path
, WCHAR
*buffer
, DWORD size
)
363 WCHAR fileDescW
[41], *desc
;
364 DWORD versize
, *lang
;
369 versize
= GetFileVersionInfoSizeW(path
, NULL
);
370 if (!versize
) return FALSE
;
372 data
= heap_alloc(versize
);
373 if (!data
) return FALSE
;
375 if (!GetFileVersionInfoW(path
, 0, versize
, data
))
378 if (!VerQueryValueW(data
, L
"\\VarFileInfo\\Translation", (LPVOID
*)&lang
, &llen
))
381 for (i
= 0; i
< llen
/ sizeof(DWORD
); i
++)
383 swprintf(fileDescW
, ARRAY_SIZE(fileDescW
), L
"\\StringFileInfo\\%04x%04x\\FileDescription",
384 LOWORD(lang
[i
]), HIWORD(lang
[i
]));
385 if (VerQueryValueW(data
, fileDescW
, (LPVOID
*)&desc
, &dlen
))
387 if (dlen
> size
- 1) dlen
= size
- 1;
388 memcpy(buffer
, desc
, dlen
* sizeof(WCHAR
));
400 struct file_properties_info
402 WCHAR path
[MAX_PATH
];
408 static void init_file_properties_dlg(HWND hwndDlg
, struct file_properties_info
*props
)
410 WCHAR buffer
[MAX_PATH
], buffer2
[MAX_PATH
];
411 WIN32_FILE_ATTRIBUTE_DATA exinfo
;
414 SetDlgItemTextW(hwndDlg
, IDC_FPROP_PATH
, props
->filename
);
415 SetDlgItemTextW(hwndDlg
, IDC_FPROP_LOCATION
, props
->dir
);
417 if (SHGetFileInfoW(props
->path
, 0, &shinfo
, sizeof(shinfo
), SHGFI_TYPENAME
|SHGFI_ICON
))
421 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_ICON
, STM_SETICON
, (WPARAM
)shinfo
.hIcon
, 0);
422 DestroyIcon(shinfo
.hIcon
);
424 if (shinfo
.szTypeName
[0])
425 SetDlgItemTextW(hwndDlg
, IDC_FPROP_TYPE
, shinfo
.szTypeName
);
428 if (!GetFileAttributesExW(props
->path
, GetFileExInfoStandard
, &exinfo
))
431 if (format_date(&exinfo
.ftCreationTime
, buffer
, ARRAY_SIZE(buffer
)))
432 SetDlgItemTextW(hwndDlg
, IDC_FPROP_CREATED
, buffer
);
434 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
)
435 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_READONLY
, BM_SETCHECK
, BST_CHECKED
, 0);
436 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
)
437 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_HIDDEN
, BM_SETCHECK
, BST_CHECKED
, 0);
438 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_ARCHIVE
)
439 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_ARCHIVE
, BM_SETCHECK
, BST_CHECKED
, 0);
441 if (exinfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
443 SetDlgItemTextW(hwndDlg
, IDC_FPROP_SIZE
, L
"(unknown)");
444 /* TODO: Implement counting for directories */
448 /* Information about files only */
449 StrFormatByteSizeW(((LONGLONG
)exinfo
.nFileSizeHigh
<< 32) | exinfo
.nFileSizeLow
,
450 buffer
, ARRAY_SIZE(buffer
));
451 SetDlgItemTextW(hwndDlg
, IDC_FPROP_SIZE
, buffer
);
453 if (format_date(&exinfo
.ftLastWriteTime
, buffer
, ARRAY_SIZE(buffer
)))
454 SetDlgItemTextW(hwndDlg
, IDC_FPROP_MODIFIED
, buffer
);
455 if (format_date(&exinfo
.ftLastAccessTime
, buffer
, ARRAY_SIZE(buffer
)))
456 SetDlgItemTextW(hwndDlg
, IDC_FPROP_ACCESSED
, buffer
);
458 if (FindExecutableW(props
->path
, NULL
, buffer
) <= (HINSTANCE
)32)
461 /* Information about executables */
462 if (SHGetFileInfoW(buffer
, 0, &shinfo
, sizeof(shinfo
), SHGFI_ICON
| SHGFI_SMALLICON
) && shinfo
.hIcon
)
463 SendDlgItemMessageW(hwndDlg
, IDC_FPROP_PROG_ICON
, STM_SETICON
, (WPARAM
)shinfo
.hIcon
, 0);
465 if (get_program_description(buffer
, buffer2
, ARRAY_SIZE(buffer2
)))
466 SetDlgItemTextW(hwndDlg
, IDC_FPROP_PROG_NAME
, buffer2
);
469 WCHAR
*p
= wcsrchr(buffer
, '\\');
470 SetDlgItemTextW(hwndDlg
, IDC_FPROP_PROG_NAME
, p
? ++p
: buffer
);
474 static INT_PTR CALLBACK
file_properties_proc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
480 LPPROPSHEETPAGEW page
= (LPPROPSHEETPAGEW
)lParam
;
481 SetWindowLongPtrW(hwndDlg
, DWLP_USER
, (LONG_PTR
)page
->lParam
);
482 init_file_properties_dlg(hwndDlg
, (struct file_properties_info
*)page
->lParam
);
487 if (LOWORD(wParam
) == IDC_FPROP_PROG_CHANGE
)
489 /* TODO: Implement file association dialog */
490 MessageBoxA(hwndDlg
, "Not implemented yet.", "Error", MB_OK
| MB_ICONEXCLAMATION
);
492 else if (LOWORD(wParam
) == IDC_FPROP_READONLY
||
493 LOWORD(wParam
) == IDC_FPROP_HIDDEN
||
494 LOWORD(wParam
) == IDC_FPROP_ARCHIVE
)
496 SendMessageW(GetParent(hwndDlg
), PSM_CHANGED
, (WPARAM
)hwndDlg
, 0);
498 else if (LOWORD(wParam
) == IDC_FPROP_PATH
&& HIWORD(wParam
) == EN_CHANGE
)
500 SendMessageW(GetParent(hwndDlg
), PSM_CHANGED
, (WPARAM
)hwndDlg
, 0);
506 LPPSHNOTIFY notify
= (LPPSHNOTIFY
)lParam
;
507 if (notify
->hdr
.code
== PSN_APPLY
)
509 struct file_properties_info
*props
= (struct file_properties_info
*)GetWindowLongPtrW(hwndDlg
, DWLP_USER
);
510 WCHAR newname
[MAX_PATH
], newpath
[MAX_PATH
];
513 attributes
= GetFileAttributesW(props
->path
);
514 if (attributes
!= INVALID_FILE_ATTRIBUTES
)
516 attributes
&= ~(FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_ARCHIVE
);
518 if (SendDlgItemMessageW(hwndDlg
, IDC_FPROP_READONLY
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
519 attributes
|= FILE_ATTRIBUTE_READONLY
;
520 if (SendDlgItemMessageW(hwndDlg
, IDC_FPROP_HIDDEN
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
521 attributes
|= FILE_ATTRIBUTE_HIDDEN
;
522 if (SendDlgItemMessageW(hwndDlg
, IDC_FPROP_ARCHIVE
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
523 attributes
|= FILE_ATTRIBUTE_ARCHIVE
;
525 if (!SetFileAttributesW(props
->path
, attributes
))
526 ERR("failed to update file attributes of %s\n", debugstr_w(props
->path
));
529 /* Update filename if it was changed */
530 if (GetDlgItemTextW(hwndDlg
, IDC_FPROP_PATH
, newname
, ARRAY_SIZE(newname
)) &&
531 wcscmp(props
->filename
, newname
) &&
532 lstrlenW(props
->dir
) + lstrlenW(newname
) + 2 < ARRAY_SIZE(newpath
))
534 lstrcpyW(newpath
, props
->dir
);
535 lstrcatW(newpath
, L
"\\");
536 lstrcatW(newpath
, newname
);
538 if (!MoveFileW(props
->path
, newpath
))
539 ERR("failed to move file %s to %s\n", debugstr_w(props
->path
), debugstr_w(newpath
));
543 lstrcpyW(props
->path
, newpath
);
544 lstrcpyW(props
->dir
, newpath
);
545 if ((p
= wcsrchr(props
->dir
, '\\')))
548 props
->filename
= p
+ 1;
551 props
->filename
= props
->dir
;
552 SetDlgItemTextW(hwndDlg
, IDC_FPROP_LOCATION
, props
->dir
);
567 static UINT CALLBACK
file_properties_callback(HWND hwnd
, UINT uMsg
, LPPROPSHEETPAGEW page
)
569 struct file_properties_info
*props
= (struct file_properties_info
*)page
->lParam
;
570 if (uMsg
== PSPCB_RELEASE
)
577 static void init_file_properties_pages(IDataObject
*dataobject
, LPFNADDPROPSHEETPAGE lpfnAddPage
, LPARAM lParam
)
579 struct file_properties_info
*props
;
580 HPROPSHEETPAGE general_page
;
581 PROPSHEETPAGEW propsheet
;
587 props
= heap_alloc(sizeof(*props
));
590 format
.cfFormat
= CF_HDROP
;
592 format
.dwAspect
= DVASPECT_CONTENT
;
594 format
.tymed
= TYMED_HGLOBAL
;
596 hr
= IDataObject_GetData(dataobject
, &format
, &stgm
);
597 if (FAILED(hr
)) goto error
;
599 if (!DragQueryFileW((HDROP
)stgm
.u
.hGlobal
, 0, props
->path
, ARRAY_SIZE(props
->path
)))
601 ReleaseStgMedium(&stgm
);
605 ReleaseStgMedium(&stgm
);
607 props
->attrib
= GetFileAttributesW(props
->path
);
608 if (props
->attrib
== INVALID_FILE_ATTRIBUTES
)
611 lstrcpyW(props
->dir
, props
->path
);
612 if ((p
= wcsrchr(props
->dir
, '\\')))
615 props
->filename
= p
+ 1;
618 props
->filename
= props
->dir
;
620 memset(&propsheet
, 0, sizeof(propsheet
));
621 propsheet
.dwSize
= sizeof(propsheet
);
622 propsheet
.dwFlags
= PSP_DEFAULT
| PSP_USECALLBACK
;
623 propsheet
.hInstance
= shell32_hInstance
;
624 if (props
->attrib
& FILE_ATTRIBUTE_DIRECTORY
)
625 propsheet
.u
.pszTemplate
= (LPWSTR
)MAKEINTRESOURCE(IDD_FOLDER_PROPERTIES
);
627 propsheet
.u
.pszTemplate
= (LPWSTR
)MAKEINTRESOURCE(IDD_FILE_PROPERTIES
);
628 propsheet
.pfnDlgProc
= file_properties_proc
;
629 propsheet
.pfnCallback
= file_properties_callback
;
630 propsheet
.lParam
= (LPARAM
)props
;
632 general_page
= CreatePropertySheetPageW(&propsheet
);
634 lpfnAddPage(general_page
, lParam
);
641 #define MAX_PROP_PAGES 99
643 static void DoOpenProperties(ContextMenu
*This
, HWND hwnd
)
645 LPSHELLFOLDER lpDesktopSF
;
648 WCHAR wszFiletype
[MAX_PATH
];
649 WCHAR wszFilename
[MAX_PATH
];
650 PROPSHEETHEADERW psh
;
651 HPROPSHEETPAGE hpages
[MAX_PROP_PAGES
];
655 TRACE("(%p)->(wnd=%p)\n", This
, hwnd
);
657 ZeroMemory(&psh
, sizeof(PROPSHEETHEADERW
));
658 psh
.dwSize
= sizeof (PROPSHEETHEADERW
);
659 psh
.hwndParent
= hwnd
;
660 psh
.dwFlags
= PSH_PROPTITLE
;
662 psh
.u3
.phpage
= hpages
;
663 psh
.u2
.nStartPage
= 0;
665 _ILSimpleGetTextW(This
->apidl
[0], (LPVOID
)wszFilename
, MAX_PATH
);
666 psh
.pszCaption
= (LPCWSTR
)wszFilename
;
668 /* Find out where to look for the shell extensions */
669 if (_ILIsValue(This
->apidl
[0]))
673 if (_ILGetExtension(This
->apidl
[0], sTemp
, 64))
675 HCR_MapTypeToValueA(sTemp
, sTemp
, 64, TRUE
);
676 MultiByteToWideChar(CP_ACP
, 0, sTemp
, -1, wszFiletype
, MAX_PATH
);
683 else if (_ILIsFolder(This
->apidl
[0]))
685 lstrcpynW(wszFiletype
, L
"Folder", 64);
687 else if (_ILIsSpecialFolder(This
->apidl
[0]))
690 folderGUID
= _ILGetGUIDPointer(This
->apidl
[0]);
691 lstrcpyW(wszFiletype
, L
"CLSID\\");
692 StringFromGUID2(folderGUID
, &wszFiletype
[6], MAX_PATH
- 6);
696 FIXME("Requested properties for unknown type.\n");
700 /* Get a suitable DataObject for accessing the files */
701 SHGetDesktopFolder(&lpDesktopSF
);
702 if (_ILIsPidlSimple(This
->pidl
))
704 ret
= IShellFolder_GetUIObjectOf(lpDesktopSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
705 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
706 IShellFolder_Release(lpDesktopSF
);
710 IShellFolder_BindToObject(lpDesktopSF
, This
->pidl
, NULL
, &IID_IShellFolder
, (LPVOID
*) &lpSF
);
711 ret
= IShellFolder_GetUIObjectOf(lpSF
, hwnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
712 &IID_IDataObject
, NULL
, (LPVOID
*)&lpDo
);
713 IShellFolder_Release(lpSF
);
714 IShellFolder_Release(lpDesktopSF
);
719 init_file_properties_pages(lpDo
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
721 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszFiletype
, MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
724 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
725 SHDestroyPropSheetExtArray(hpsxa
);
727 hpsxa
= SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"*", MAX_PROP_PAGES
- psh
.nPages
, lpDo
);
730 SHAddFromPropSheetExtArray(hpsxa
, Properties_AddPropSheetCallback
, (LPARAM
)&psh
);
731 SHDestroyPropSheetExtArray(hpsxa
);
733 IDataObject_Release(lpDo
);
737 PropertySheetW(&psh
);
739 FIXME("No property pages found.\n");
742 static HRESULT WINAPI
ItemMenu_InvokeCommand(
743 IContextMenu3
*iface
,
744 LPCMINVOKECOMMANDINFO lpcmi
)
746 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
748 if (lpcmi
->cbSize
!= sizeof(CMINVOKECOMMANDINFO
))
749 FIXME("Is an EX structure\n");
751 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This
,lpcmi
,lpcmi
->lpVerb
, lpcmi
->hwnd
);
753 if (IS_INTRESOURCE(lpcmi
->lpVerb
) && LOWORD(lpcmi
->lpVerb
) > FCIDM_SHVIEWLAST
)
755 TRACE("Invalid Verb %x\n", LOWORD(lpcmi
->lpVerb
));
759 if (IS_INTRESOURCE(lpcmi
->lpVerb
))
761 switch(LOWORD(lpcmi
->lpVerb
) + FCIDM_BASE
)
763 case FCIDM_SHVIEW_EXPLORE
:
764 TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
765 DoOpenExplore(This
, lpcmi
->hwnd
, "explore");
767 case FCIDM_SHVIEW_OPEN
:
768 TRACE("Verb FCIDM_SHVIEW_OPEN\n");
769 DoOpenExplore(This
, lpcmi
->hwnd
, "open");
771 case FCIDM_SHVIEW_RENAME
:
773 IShellBrowser
*browser
;
775 /* get the active IShellView */
776 browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0);
781 if(SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
783 TRACE("(shellview=%p)\n", view
);
784 IShellView_SelectItem(view
, This
->apidl
[0],
785 SVSI_DESELECTOTHERS
|SVSI_EDIT
|SVSI_ENSUREVISIBLE
|SVSI_FOCUSED
|SVSI_SELECT
);
786 IShellView_Release(view
);
791 case FCIDM_SHVIEW_DELETE
:
792 TRACE("Verb FCIDM_SHVIEW_DELETE\n");
795 case FCIDM_SHVIEW_COPY
:
796 TRACE("Verb FCIDM_SHVIEW_COPY\n");
797 DoCopyOrCut(This
, lpcmi
->hwnd
, FALSE
);
799 case FCIDM_SHVIEW_CUT
:
800 TRACE("Verb FCIDM_SHVIEW_CUT\n");
801 DoCopyOrCut(This
, lpcmi
->hwnd
, TRUE
);
803 case FCIDM_SHVIEW_PROPERTIES
:
804 TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
805 DoOpenProperties(This
, lpcmi
->hwnd
);
808 FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi
->lpVerb
));
814 TRACE("Verb is %s\n",debugstr_a(lpcmi
->lpVerb
));
815 if (strcmp(lpcmi
->lpVerb
,"delete")==0)
817 else if (strcmp(lpcmi
->lpVerb
,"copy")==0)
818 DoCopyOrCut(This
, lpcmi
->hwnd
, FALSE
);
819 else if (strcmp(lpcmi
->lpVerb
,"cut")==0)
820 DoCopyOrCut(This
, lpcmi
->hwnd
, TRUE
);
821 else if (strcmp(lpcmi
->lpVerb
,"properties")==0)
822 DoOpenProperties(This
, lpcmi
->hwnd
);
824 FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi
->lpVerb
));
831 static HRESULT WINAPI
ItemMenu_GetCommandString(IContextMenu3
*iface
, UINT_PTR cmdid
, UINT flags
,
832 UINT
*reserved
, LPSTR name
, UINT maxlen
)
834 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
835 const WCHAR
*cmdW
= NULL
;
838 TRACE("(%p)->(%lx, %#x, %p, %p, %u)\n", This
, cmdid
, flags
, reserved
, name
, maxlen
);
849 switch (cmdid
+ FCIDM_BASE
)
851 case FCIDM_SHVIEW_OPEN
:
854 case FCIDM_SHVIEW_EXPLORE
:
857 case FCIDM_SHVIEW_CUT
:
860 case FCIDM_SHVIEW_COPY
:
863 case FCIDM_SHVIEW_CREATELINK
:
866 case FCIDM_SHVIEW_DELETE
:
869 case FCIDM_SHVIEW_PROPERTIES
:
870 cmdW
= L
"properties";
872 case FCIDM_SHVIEW_RENAME
:
883 if (flags
== GCS_VERBA
)
884 WideCharToMultiByte(CP_ACP
, 0, cmdW
, -1, name
, maxlen
, NULL
, NULL
);
886 lstrcpynW((WCHAR
*)name
, cmdW
, maxlen
);
888 TRACE("name %s\n", flags
== GCS_VERBA
? debugstr_a(name
) : debugstr_w((WCHAR
*)name
));
899 /**************************************************************************
901 * should be only in IContextMenu2 and IContextMenu3
902 * is nevertheless called from word95
904 static HRESULT WINAPI
ContextMenu_HandleMenuMsg(IContextMenu3
*iface
, UINT msg
,
905 WPARAM wParam
, LPARAM lParam
)
907 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
908 FIXME("(%p)->(0x%x 0x%lx 0x%lx): stub\n", This
, msg
, wParam
, lParam
);
912 static HRESULT WINAPI
ContextMenu_HandleMenuMsg2(IContextMenu3
*iface
, UINT msg
,
913 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
915 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
916 FIXME("(%p)->(0x%x 0x%lx 0x%lx %p): stub\n", This
, msg
, wParam
, lParam
, result
);
920 static const IContextMenu3Vtbl ItemContextMenuVtbl
=
922 ContextMenu_QueryInterface
,
925 ItemMenu_QueryContextMenu
,
926 ItemMenu_InvokeCommand
,
927 ItemMenu_GetCommandString
,
928 ContextMenu_HandleMenuMsg
,
929 ContextMenu_HandleMenuMsg2
932 static HRESULT WINAPI
ShellExtInit_QueryInterface(IShellExtInit
*iface
, REFIID riid
, void **obj
)
934 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
935 return IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, obj
);
938 static ULONG WINAPI
ShellExtInit_AddRef(IShellExtInit
*iface
)
940 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
941 return IContextMenu3_AddRef(&This
->IContextMenu3_iface
);
944 static ULONG WINAPI
ShellExtInit_Release(IShellExtInit
*iface
)
946 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
947 return IContextMenu3_Release(&This
->IContextMenu3_iface
);
950 static HRESULT WINAPI
ShellExtInit_Initialize(IShellExtInit
*iface
, LPCITEMIDLIST folder
,
951 IDataObject
*dataobj
, HKEY progidkey
)
953 ContextMenu
*This
= impl_from_IShellExtInit(iface
);
955 FIXME("(%p)->(%p %p %p): stub\n", This
, folder
, dataobj
, progidkey
);
960 static const IShellExtInitVtbl ShellExtInitVtbl
=
962 ShellExtInit_QueryInterface
,
964 ShellExtInit_Release
,
965 ShellExtInit_Initialize
968 static HRESULT WINAPI
ObjectWithSite_QueryInterface(IObjectWithSite
*iface
, REFIID riid
, void **obj
)
970 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
971 return IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, obj
);
974 static ULONG WINAPI
ObjectWithSite_AddRef(IObjectWithSite
*iface
)
976 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
977 return IContextMenu3_AddRef(&This
->IContextMenu3_iface
);
980 static ULONG WINAPI
ObjectWithSite_Release(IObjectWithSite
*iface
)
982 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
983 return IContextMenu3_Release(&This
->IContextMenu3_iface
);
986 static HRESULT WINAPI
ObjectWithSite_SetSite(IObjectWithSite
*iface
, IUnknown
*site
)
988 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
990 FIXME("(%p)->(%p): stub\n", This
, site
);
995 static HRESULT WINAPI
ObjectWithSite_GetSite(IObjectWithSite
*iface
, REFIID riid
, void **site
)
997 ContextMenu
*This
= impl_from_IObjectWithSite(iface
);
999 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_guid(riid
), site
);
1004 static const IObjectWithSiteVtbl ObjectWithSiteVtbl
=
1006 ObjectWithSite_QueryInterface
,
1007 ObjectWithSite_AddRef
,
1008 ObjectWithSite_Release
,
1009 ObjectWithSite_SetSite
,
1010 ObjectWithSite_GetSite
,
1013 HRESULT
ItemMenu_Constructor(IShellFolder
*parent
, LPCITEMIDLIST pidl
, const LPCITEMIDLIST
*apidl
, UINT cidl
,
1014 REFIID riid
, void **pObj
)
1020 This
= heap_alloc(sizeof(*This
));
1021 if (!This
) return E_OUTOFMEMORY
;
1023 This
->IContextMenu3_iface
.lpVtbl
= &ItemContextMenuVtbl
;
1024 This
->IShellExtInit_iface
.lpVtbl
= &ShellExtInitVtbl
;
1025 This
->IObjectWithSite_iface
.lpVtbl
= &ObjectWithSiteVtbl
;
1027 This
->parent
= parent
;
1028 if (parent
) IShellFolder_AddRef(parent
);
1030 This
->pidl
= ILClone(pidl
);
1031 This
->apidl
= _ILCopyaPidl(apidl
, cidl
);
1033 This
->allvalues
= TRUE
;
1035 This
->desktop
= FALSE
;
1037 for (i
= 0; i
< cidl
; i
++)
1038 This
->allvalues
&= (_ILIsValue(apidl
[i
]) ? 1 : 0);
1040 hr
= IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, pObj
);
1041 IContextMenu3_Release(&This
->IContextMenu3_iface
);
1046 /* Background menu implementation */
1047 static HRESULT WINAPI
BackgroundMenu_QueryContextMenu(
1048 IContextMenu3
*iface
,
1055 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
1060 TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
1061 This
, hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
1063 hMyMenu
= LoadMenuA(shell32_hInstance
, "MENU_002");
1064 if (uFlags
& CMF_DEFAULTONLY
)
1066 HMENU ourMenu
= GetSubMenu(hMyMenu
,0);
1067 UINT oldDef
= GetMenuDefaultItem(hMenu
,TRUE
,GMDI_USEDISABLED
);
1068 UINT newDef
= GetMenuDefaultItem(ourMenu
,TRUE
,GMDI_USEDISABLED
);
1069 if (newDef
!= oldDef
)
1070 SetMenuDefaultItem(hMenu
,newDef
,TRUE
);
1071 if (newDef
!=0xFFFFFFFF)
1072 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, newDef
+1);
1074 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
1078 Shell_MergeMenus (hMenu
, GetSubMenu(hMyMenu
,0), indexMenu
,
1079 idCmdFirst
- FCIDM_BASE
, idCmdLast
, MM_SUBMENUSHAVEIDS
);
1080 idMax
= max_menu_id(GetSubMenu(hMyMenu
, 0), idCmdFirst
- FCIDM_BASE
, idCmdLast
);
1081 hr
= MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, idMax
-idCmdFirst
);
1083 DestroyMenu(hMyMenu
);
1085 TRACE("(%p)->returning 0x%x\n",This
,hr
);
1089 static void DoNewFolder(ContextMenu
*This
, IShellView
*view
)
1093 IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&helper
);
1096 WCHAR nameW
[MAX_PATH
];
1099 ISFHelper_GetUniqueName(helper
, nameW
, MAX_PATH
);
1100 ISFHelper_AddFolder(helper
, 0, nameW
, &pidl
);
1104 /* if we are in a shellview do labeledit */
1105 IShellView_SelectItem(view
,
1106 pidl
,(SVSI_DESELECTOTHERS
| SVSI_EDIT
| SVSI_ENSUREVISIBLE
1107 |SVSI_FOCUSED
|SVSI_SELECT
));
1111 ISFHelper_Release(helper
);
1115 static HRESULT
paste_pidls(ContextMenu
*This
, ITEMIDLIST
**pidls
, UINT count
)
1117 IShellFolder
*psfDesktop
;
1121 /* bind to the source shellfolder */
1122 hr
= SHGetDesktopFolder(&psfDesktop
);
1126 for (i
= 0; SUCCEEDED(hr
) && i
< count
; i
++) {
1127 ITEMIDLIST
*pidl_dir
= NULL
;
1128 ITEMIDLIST
*pidl_item
;
1129 IShellFolder
*psfFrom
= NULL
;
1131 pidl_dir
= ILClone(pidls
[i
]);
1132 ILRemoveLastID(pidl_dir
);
1133 pidl_item
= ILFindLastID(pidls
[i
]);
1134 hr
= IShellFolder_BindToObject(psfDesktop
, pidl_dir
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfFrom
);
1138 /* get source and destination shellfolder */
1139 ISFHelper
*psfhlpdst
= NULL
, *psfhlpsrc
= NULL
;
1140 hr
= IShellFolder_QueryInterface(This
->parent
, &IID_ISFHelper
, (void**)&psfhlpdst
);
1142 hr
= IShellFolder_QueryInterface(psfFrom
, &IID_ISFHelper
, (void**)&psfhlpsrc
);
1144 /* do the copy/move */
1145 if (psfhlpdst
&& psfhlpsrc
)
1147 hr
= ISFHelper_CopyItems(psfhlpdst
, psfFrom
, 1, (LPCITEMIDLIST
*)&pidl_item
);
1148 /* FIXME handle move
1149 ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item);
1152 if(psfhlpdst
) ISFHelper_Release(psfhlpdst
);
1153 if(psfhlpsrc
) ISFHelper_Release(psfhlpsrc
);
1154 IShellFolder_Release(psfFrom
);
1159 IShellFolder_Release(psfDesktop
);
1163 static HRESULT
DoPaste(ContextMenu
*This
)
1170 hr
= OleGetClipboard(&pda
);
1174 FORMATETC formatetc
;
1177 TRACE("pda=%p\n", pda
);
1179 /* Set the FORMATETC structure*/
1180 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
), TYMED_HGLOBAL
);
1182 /* Get the pidls from IDataObject */
1183 format_hr
= IDataObject_GetData(pda
,&formatetc
,&medium
);
1184 if(SUCCEEDED(format_hr
))
1186 LPITEMIDLIST
* apidl
;
1189 LPIDA lpcida
= GlobalLock(medium
.u
.hGlobal
);
1190 TRACE("cida=%p\n", lpcida
);
1193 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
1196 hr
= paste_pidls(This
, apidl
, lpcida
->cidl
);
1197 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1201 hr
= HRESULT_FROM_WIN32(GetLastError());
1202 GlobalUnlock(medium
.u
.hGlobal
);
1205 hr
= HRESULT_FROM_WIN32(GetLastError());
1206 ReleaseStgMedium(&medium
);
1209 if(FAILED(format_hr
))
1211 InitFormatEtc(formatetc
, CF_HDROP
, TYMED_HGLOBAL
);
1212 format_hr
= IDataObject_GetData(pda
,&formatetc
,&medium
);
1213 if(SUCCEEDED(format_hr
))
1215 WCHAR path
[MAX_PATH
];
1219 TRACE("CF_HDROP=%p\n", medium
.u
.hGlobal
);
1220 count
= DragQueryFileW(medium
.u
.hGlobal
, -1, NULL
, 0);
1221 pidls
= SHAlloc(count
*sizeof(ITEMIDLIST
**));
1224 for (i
= 0; i
< count
; i
++)
1226 DragQueryFileW(medium
.u
.hGlobal
, i
, path
, ARRAY_SIZE(path
));
1227 if ((pidls
[i
] = ILCreateFromPathW(path
)) == NULL
)
1234 hr
= paste_pidls(This
, pidls
, count
);
1235 _ILFreeaPidl(pidls
, count
);
1238 hr
= HRESULT_FROM_WIN32(GetLastError());
1239 ReleaseStgMedium(&medium
);
1243 if (FAILED(format_hr
))
1245 ERR("there are no supported and retrievable clipboard formats\n");
1249 IDataObject_Release(pda
);
1254 OpenClipboard(NULL
);
1255 hMem
= GetClipboardData(CF_HDROP
);
1259 char * pDropFiles
= GlobalLock(hMem
);
1262 int len
, offset
= sizeof(DROPFILESTRUCT
);
1264 while( pDropFiles
[offset
] != 0)
1266 len
= strlen(pDropFiles
+ offset
);
1267 TRACE("%s\n", pDropFiles
+ offset
);
1278 static HRESULT WINAPI
BackgroundMenu_InvokeCommand(
1279 IContextMenu3
*iface
,
1280 LPCMINVOKECOMMANDINFO lpcmi
)
1282 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
1283 IShellBrowser
*browser
;
1284 IShellView
*view
= NULL
;
1287 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", This
, lpcmi
, lpcmi
->lpVerb
, lpcmi
->hwnd
);
1289 /* get the active IShellView */
1290 if ((browser
= (IShellBrowser
*)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0)))
1292 if (SUCCEEDED(IShellBrowser_QueryActiveShellView(browser
, &view
)))
1293 IShellView_GetWindow(view
, &hWnd
);
1296 if(HIWORD(lpcmi
->lpVerb
))
1298 TRACE("%s\n", debugstr_a(lpcmi
->lpVerb
));
1300 if (!strcmp(lpcmi
->lpVerb
, CMDSTR_NEWFOLDERA
))
1302 DoNewFolder(This
, view
);
1304 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWLISTA
))
1306 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW
, 0), 0);
1308 else if (!strcmp(lpcmi
->lpVerb
, CMDSTR_VIEWDETAILSA
))
1310 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW
, 0), 0);
1312 else if (!strcmp(lpcmi
->lpVerb
, "paste"))
1318 FIXME("please report: unknown verb %s\n", debugstr_a(lpcmi
->lpVerb
));
1323 switch (LOWORD(lpcmi
->lpVerb
) + FCIDM_BASE
)
1325 case FCIDM_SHVIEW_REFRESH
:
1326 if (view
) IShellView_Refresh(view
);
1329 case FCIDM_SHVIEW_NEWFOLDER
:
1330 DoNewFolder(This
, view
);
1333 case FCIDM_SHVIEW_INSERT
:
1337 case FCIDM_SHVIEW_PROPERTIES
:
1338 if (This
->desktop
) {
1339 ShellExecuteA(lpcmi
->hwnd
, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL
, NULL
, SW_SHOWNORMAL
);
1341 FIXME("launch item properties dialog\n");
1346 /* if it's an id just pass it to the parent shv */
1347 if (hWnd
) SendMessageA(hWnd
, WM_COMMAND
, MAKEWPARAM(LOWORD(lpcmi
->lpVerb
), 0), 0);
1353 IShellView_Release(view
);
1358 static HRESULT WINAPI
BackgroundMenu_GetCommandString(
1359 IContextMenu3
*iface
,
1366 ContextMenu
*This
= impl_from_IContextMenu3(iface
);
1367 const WCHAR
*cmdW
= NULL
;
1368 HRESULT hr
= E_FAIL
;
1370 TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n",This
, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
1381 switch (idCommand
+ FCIDM_BASE
)
1383 case FCIDM_SHVIEW_INSERT
:
1386 case FCIDM_SHVIEW_PROPERTIES
:
1387 cmdW
= L
"properties";
1397 if (uFlags
== GCS_VERBA
)
1398 WideCharToMultiByte(CP_ACP
, 0, cmdW
, -1, lpszName
, uMaxNameLen
, NULL
, NULL
);
1400 lstrcpynW((WCHAR
*)lpszName
, cmdW
, uMaxNameLen
);
1401 TRACE("name %s\n", uFlags
== GCS_VERBA
? debugstr_a(lpszName
) : debugstr_w((WCHAR
*)lpszName
));
1407 /* test the existence of the menu items, the file dialog enables
1408 the buttons according to this */
1409 if (HIWORD(idCommand
))
1411 if (!strcmp((LPSTR
)idCommand
, CMDSTR_VIEWLISTA
) ||
1412 !strcmp((LPSTR
)idCommand
, CMDSTR_VIEWDETAILSA
) ||
1413 !strcmp((LPSTR
)idCommand
, CMDSTR_NEWFOLDERA
))
1417 FIXME("unknown command string %s\n", uFlags
== GCS_VALIDATEA
? debugstr_a((LPSTR
)idCommand
) : debugstr_w((WCHAR
*)idCommand
));
1426 static const IContextMenu3Vtbl BackgroundContextMenuVtbl
=
1428 ContextMenu_QueryInterface
,
1430 ContextMenu_Release
,
1431 BackgroundMenu_QueryContextMenu
,
1432 BackgroundMenu_InvokeCommand
,
1433 BackgroundMenu_GetCommandString
,
1434 ContextMenu_HandleMenuMsg
,
1435 ContextMenu_HandleMenuMsg2
1438 HRESULT
BackgroundMenu_Constructor(IShellFolder
*parent
, BOOL desktop
, REFIID riid
, void **pObj
)
1443 This
= heap_alloc(sizeof(*This
));
1444 if (!This
) return E_OUTOFMEMORY
;
1446 This
->IContextMenu3_iface
.lpVtbl
= &BackgroundContextMenuVtbl
;
1447 This
->IShellExtInit_iface
.lpVtbl
= &ShellExtInitVtbl
;
1448 This
->IObjectWithSite_iface
.lpVtbl
= &ObjectWithSiteVtbl
;
1450 This
->parent
= parent
;
1455 This
->allvalues
= FALSE
;
1457 This
->desktop
= desktop
;
1458 if (parent
) IShellFolder_AddRef(parent
);
1460 hr
= IContextMenu3_QueryInterface(&This
->IContextMenu3_iface
, riid
, pObj
);
1461 IContextMenu3_Release(&This
->IContextMenu3_iface
);