Revert tree-restructure attempt: r66583, r66582, r66581, r66578, sauf ntdll changes...
[reactos.git] / reactos / dll / win32 / shell32 / CNewMenu.cpp
1 /*
2 * provides new shell item service
3 *
4 * Copyright 2007 Johannes Anderwald (johannes.anderwald@reactos.org)
5 * Copyright 2009 Andrew Hill
6 * Copyright 2012 Rafal Harabien
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include "precomp.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(shell);
26
27 CNewMenu::CNewMenu()
28 {
29 m_wszPath = NULL;
30 m_pItems = NULL;
31 m_pLinkItem = NULL;
32 m_pSite = NULL;
33 m_hbmFolder = NULL;
34 m_hbmLink = NULL;
35 }
36
37 CNewMenu::~CNewMenu()
38 {
39 UnloadAllItems();
40 if (m_hbmFolder)
41 DeleteObject(m_hbmFolder);
42 if (m_hbmLink)
43 DeleteObject(m_hbmLink);
44 }
45
46 void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem)
47 {
48 /* Note: free allows NULL as argument */
49 free(pItem->pData);
50 free(pItem->pwszDesc);
51 free(pItem->pwszExt);
52
53 if (pItem->hBitmap)
54 DeleteObject(pItem->hBitmap);
55
56 HeapFree(GetProcessHeap(), 0, pItem);
57 }
58
59 void CNewMenu::UnloadAllItems()
60 {
61 SHELLNEW_ITEM *pCurItem;
62
63 /* Unload normal items */
64 while (m_pItems)
65 {
66 pCurItem = m_pItems;
67 m_pItems = m_pItems->pNext;
68
69 UnloadItem(pCurItem);
70 }
71
72 /* Unload link item */
73 if (m_pLinkItem)
74 UnloadItem(m_pLinkItem);
75 m_pLinkItem = NULL;
76 }
77
78 static HBITMAP IconToBitmap(HICON hIcon)
79 {
80 HDC hdc, hdcScr;
81 HBITMAP hbm, hbmOld;
82 RECT rc;
83
84 hdcScr = GetDC(NULL);
85 hdc = CreateCompatibleDC(hdcScr);
86 SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK));
87 hbm = CreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
88 ReleaseDC(NULL, hdcScr);
89
90 hbmOld = (HBITMAP)SelectObject(hdc, hbm);
91 FillRect(hdc, &rc, (HBRUSH)(COLOR_MENU + 1));
92 if (!DrawIconEx(hdc, 0, 0, hIcon, rc.right, rc.bottom, 0, NULL, DI_NORMAL))
93 ERR("DrawIcon failed: %x\n", GetLastError());
94 SelectObject(hdc, hbmOld);
95
96 DeleteDC(hdc);
97
98 return hbm;
99 }
100
101 CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
102 {
103 HKEY hKey;
104 WCHAR wszBuf[MAX_PATH];
105 BYTE *pData = NULL;
106 DWORD cbData;
107
108 StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s\\ShellNew", pwszExt);
109
110 TRACE("LoadItem Keyname %s Name %s\n", debugstr_w(pwszExt), debugstr_w(wszBuf));
111
112 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszBuf, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
113 {
114 TRACE("Failed to open key\n");
115 return NULL;
116 }
117
118 /* Find first valid value */
119 struct
120 {
121 LPCWSTR pszName;
122 SHELLNEW_TYPE Type;
123 BOOL bNeedData;
124 BOOL bStr;
125 } Types[] = {
126 {L"FileName", SHELLNEW_TYPE_FILENAME, TRUE, TRUE},
127 {L"Command", SHELLNEW_TYPE_COMMAND, TRUE, TRUE},
128 {L"Data", SHELLNEW_TYPE_DATA, TRUE, FALSE},
129 {L"NullFile", SHELLNEW_TYPE_NULLFILE, FALSE},
130 {NULL}
131 };
132 UINT i;
133
134 for (i = 0; Types[i].pszName; ++i)
135 {
136 /* Note: We are using ANSI function because strings can be treated as data */
137 cbData = 0;
138 DWORD dwFlags = Types[i].bStr ? RRF_RT_REG_SZ : RRF_RT_ANY;
139 DWORD dwType;
140 if (RegGetValueW(hKey, NULL, Types[i].pszName, dwFlags, NULL, NULL, &cbData) == ERROR_SUCCESS)
141 {
142 if (Types[i].bNeedData && cbData > 0)
143 {
144 pData = (BYTE*)malloc(cbData);
145 RegGetValueW(hKey, NULL, Types[i].pszName, dwFlags, &dwType, pData, &cbData);
146 if (!Types[i].bStr && (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
147 {
148 PBYTE pData2 = (PBYTE)malloc(cbData);
149 cbData = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)pData, -1, (LPSTR)pData2, cbData, NULL, NULL);
150 free(pData);
151 pData = pData2;
152 }
153 }
154 break;
155 }
156 }
157 RegCloseKey(hKey);
158
159 /* Was any key found? */
160 if (!Types[i].pszName)
161 return NULL;
162
163 SHFILEINFO fi;
164 if (!SHGetFileInfoW(pwszExt, FILE_ATTRIBUTE_NORMAL, &fi, sizeof(fi), SHGFI_USEFILEATTRIBUTES|SHGFI_TYPENAME|SHGFI_ICON|SHGFI_SMALLICON))
165 return NULL;
166
167 /* Create new item */
168 SHELLNEW_ITEM *pNewItem = static_cast<SHELLNEW_ITEM *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHELLNEW_ITEM)));
169 if (!pNewItem)
170 {
171 free(pData);
172 return NULL;
173 }
174
175 TRACE("new item %ls\n", fi.szTypeName);
176 pNewItem->Type = Types[i].Type;
177 pNewItem->pData = pData;
178 pNewItem->cbData = pData ? cbData : 0;
179 pNewItem->pwszExt = _wcsdup(pwszExt);
180 pNewItem->pwszDesc = _wcsdup(fi.szTypeName);
181 if (fi.hIcon)
182 {
183 pNewItem->hBitmap = IconToBitmap(fi.hIcon);
184 DestroyIcon(fi.hIcon);
185 }
186
187 return pNewItem;
188 }
189
190 BOOL
191 CNewMenu::LoadAllItems()
192 {
193 DWORD dwIndex = 0;
194 WCHAR wszName[MAX_PATH];
195 SHELLNEW_ITEM *pNewItem;
196 SHELLNEW_ITEM *pCurItem = NULL;
197
198 /* If there are any unload them */
199 UnloadAllItems();
200
201 /* Enumerate all extesions */
202 while (RegEnumKeyW(HKEY_CLASSES_ROOT, dwIndex++, wszName, _countof(wszName)) == ERROR_SUCCESS)
203 {
204 if (wszName[0] != L'.')
205 continue;
206
207 pNewItem = LoadItem(wszName);
208 if (pNewItem)
209 {
210 if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
211 {
212 /* Link handler */
213 m_pLinkItem = pNewItem;
214 }
215 else
216 {
217 /* Add at the end of list */
218 if (pCurItem)
219 {
220 pCurItem->pNext = pNewItem;
221 pCurItem = pNewItem;
222 }
223 else
224 pCurItem = m_pItems = pNewItem;
225 }
226 }
227 }
228
229 if (!m_pLinkItem)
230 {
231 m_pLinkItem = static_cast<SHELLNEW_ITEM *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHELLNEW_ITEM)));
232 if (m_pLinkItem)
233 {
234 m_pLinkItem->Type = SHELLNEW_TYPE_NULLFILE;
235 m_pLinkItem->pwszDesc = _wcsdup(L"Link");
236 m_pLinkItem->pwszExt = _wcsdup(L".lnk");
237 }
238 }
239
240 if (m_pItems == NULL)
241 return FALSE;
242 else
243 return TRUE;
244 }
245
246 UINT
247 CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
248 {
249 MENUITEMINFOW mii;
250 WCHAR wszBuf[256];
251 UINT idCmd = idCmdFirst;
252
253 if (m_pItems == NULL)
254 {
255 if (!LoadAllItems())
256 return 0;
257 }
258
259 ZeroMemory(&mii, sizeof(mii));
260 mii.cbSize = sizeof(mii);
261
262 /* Insert new folder action */
263 if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWFOLDER, wszBuf, _countof(wszBuf)))
264 wszBuf[0] = 0;
265 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
266 mii.fType = MFT_STRING;
267 mii.dwTypeData = wszBuf;
268 mii.cch = wcslen(mii.dwTypeData);
269 mii.wID = idCmd;
270 if (m_hbmFolder)
271 {
272 mii.fMask |= MIIM_CHECKMARKS;
273 mii.hbmpChecked = mii.hbmpUnchecked = m_hbmFolder;
274 }
275 if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
276 ++idCmd;
277
278 /* Insert new shortcut action */
279 if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWLINK, wszBuf, _countof(wszBuf)))
280 wszBuf[0] = 0;
281 mii.dwTypeData = wszBuf;
282 mii.cch = wcslen(mii.dwTypeData);
283 mii.wID = idCmd;
284 if (m_hbmLink)
285 {
286 mii.fMask |= MIIM_CHECKMARKS;
287 mii.hbmpChecked = mii.hbmpUnchecked = m_hbmLink;
288 }
289 if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
290 ++idCmd;
291
292 /* Insert seperator for custom new action */
293 mii.fMask = MIIM_TYPE | MIIM_ID;
294 mii.fType = MFT_SEPARATOR;
295 mii.wID = -1;
296 InsertMenuItemW(hMenu, Pos++, TRUE, &mii);
297
298 /* Insert rest of items */
299 mii.fType = MFT_STRING;
300 mii.fState = MFS_ENABLED;
301
302 SHELLNEW_ITEM *pCurItem = m_pItems;
303 while (pCurItem)
304 {
305 TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
306 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
307 mii.dwTypeData = pCurItem->pwszDesc;
308 mii.cch = wcslen(mii.dwTypeData);
309 mii.wID = idCmd;
310 if (pCurItem->hBitmap)
311 {
312 mii.fMask |= MIIM_CHECKMARKS;
313 mii.hbmpChecked = mii.hbmpUnchecked = pCurItem->hBitmap;
314 }
315 if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
316 ++idCmd;
317 pCurItem = pCurItem->pNext;
318 }
319
320 return idCmd - idCmdFirst;
321 }
322
323 CNewMenu::SHELLNEW_ITEM *CNewMenu::FindItemFromIdOffset(UINT IdOffset)
324 {
325 if (IdOffset == 0)
326 return NULL; /* Folder */
327
328 if (IdOffset == 1)
329 return m_pLinkItem; /* shortcut */
330
331 /* Find shell new item */
332 SHELLNEW_ITEM *pItem = m_pItems;
333 for (UINT i = 2; pItem; ++i)
334 {
335 if (i == IdOffset)
336 break;
337
338 pItem = pItem->pNext;
339 }
340
341 return pItem;
342 }
343
344 HRESULT CNewMenu::CreateNewFolder(IShellView *psv)
345 {
346 WCHAR wszName[MAX_PATH];
347 CComPtr<ISFHelper> psfhlp;
348 CComPtr<IFolderView> pFolderView;
349 CComPtr<IShellFolder> pParentFolder;
350 HRESULT hr;
351
352 //if (m_pSite == NULL)
353 // return E_FAIL;
354
355 /* Get current folder */
356 hr = IUnknown_QueryService(psv, SID_IFolderView, IID_PPV_ARG(IFolderView, &pFolderView));
357 if (FAILED(hr))
358 return hr;
359
360 hr = pFolderView->GetFolder(IID_PPV_ARG(IShellFolder, &pParentFolder));
361 if (FAILED(hr))
362 return hr;
363
364 hr = pParentFolder->QueryInterface(IID_PPV_ARG(ISFHelper, &psfhlp));
365 if (FAILED(hr))
366 return hr;
367
368 LPITEMIDLIST pidl;
369
370 /* Get unique name and create a folder */
371 hr = psfhlp->GetUniqueName(wszName, _countof(wszName));
372 if (hr != S_OK)
373 return hr;
374 hr = psfhlp->AddFolder(0, wszName, &pidl);
375 if (hr != S_OK)
376 {
377 WCHAR wszBuf[256];
378 StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create folder: %s", wszName);
379 MessageBoxW(NULL, wszBuf, L"Cannot create folder", MB_OK|MB_ICONERROR);
380 return hr;
381 }
382
383 /* Do a labeledit */
384 psv->Refresh();
385 psv->SelectItem(pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
386 SVSI_FOCUSED | SVSI_SELECT);
387
388 SHFree(pidl);
389 return S_OK;
390 }
391
392 HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv)
393 {
394 LPITEMIDLIST pidl;
395 STRRET strTemp;
396 WCHAR wszBuf[MAX_PATH];
397 WCHAR wszPath[MAX_PATH];
398 CComPtr<IFolderView> pFolderView;
399 CComPtr<IShellFolder> pParentFolder;
400 CComPtr<IPersistFolder2> psf;
401 HRESULT hr;
402
403 /* Get current folder */
404 hr = IUnknown_QueryService(psv, SID_IFolderView, IID_PPV_ARG(IFolderView, &pFolderView));
405 if (FAILED(hr))
406 return hr;
407
408 hr = pFolderView->GetFolder(IID_PPV_ARG(IShellFolder, &pParentFolder));
409 if (FAILED(hr))
410 return hr;
411
412 if (pParentFolder->QueryInterface(IID_PPV_ARG(IPersistFolder2, &psf)) != S_OK)
413 {
414 ERR("Failed to get interface IID_IPersistFolder2\n");
415 return E_FAIL;
416 }
417
418 if (psf->GetCurFolder(&pidl) != S_OK)
419 {
420 ERR("IPersistFolder2_GetCurFolder failed\n");
421 return E_FAIL;
422 }
423
424 /* Get folder path */
425 if (pParentFolder == NULL || pParentFolder->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strTemp) != S_OK)
426 {
427 ERR("IShellFolder_GetDisplayNameOf failed\n");
428 return E_FAIL;
429 }
430 StrRetToBufW(&strTemp, pidl, wszPath, _countof(wszPath));
431
432 switch (pItem->Type)
433 {
434 case SHELLNEW_TYPE_COMMAND:
435 {
436 LPWSTR Ptr, pwszCmd;
437 WCHAR wszTemp[MAX_PATH];
438 STARTUPINFOW si;
439 PROCESS_INFORMATION pi;
440
441 if (!ExpandEnvironmentStringsW((LPWSTR)pItem->pData, wszBuf, MAX_PATH))
442 {
443 TRACE("ExpandEnvironmentStrings failed\n");
444 break;
445 }
446
447 /* Expand command parameter, FIXME: there can be more modifiers */
448 Ptr = wcsstr(wszBuf, L"%1");
449 if (Ptr)
450 {
451 Ptr[1] = 's';
452 StringCbPrintfW(wszTemp, sizeof(wszTemp), wszBuf, wszPath);
453 pwszCmd = wszTemp;
454 }
455 else
456 pwszCmd = wszBuf;
457
458 /* Create process */
459 ZeroMemory(&si, sizeof(si));
460 si.cb = sizeof(si);
461 if (CreateProcessW(NULL, pwszCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
462 {
463 CloseHandle(pi.hProcess);
464 CloseHandle(pi.hThread);
465 } else
466 ERR("Failed to create process\n");
467 break;
468 }
469 case SHELLNEW_TYPE_DATA:
470 case SHELLNEW_TYPE_FILENAME:
471 case SHELLNEW_TYPE_NULLFILE:
472 {
473 BOOL bSuccess = TRUE;
474 LPWSTR pwszFilename = NULL;
475 size_t cchFilenameMax = 0;
476
477 /* Build new file name */
478 LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, wszBuf, _countof(wszBuf));
479 StringCchCatExW(wszPath, _countof(wszPath), L"\\", &pwszFilename, &cchFilenameMax, 0);
480 StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s%s", wszBuf, pItem->pwszDesc, pItem->pwszExt);
481
482 /* Find unique name */
483 for (UINT i = 2; PathFileExistsW(wszPath); ++i)
484 {
485 StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s (%u)%s", wszBuf, pItem->pwszDesc, i, pItem->pwszExt);
486 TRACE("New Filename %ls\n", pwszFilename);
487 }
488
489 /* Create new file */
490 HANDLE hFile = CreateFileW(wszPath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
491 if (hFile != INVALID_HANDLE_VALUE)
492 {
493 if (pItem->Type == SHELLNEW_TYPE_DATA)
494 {
495 /* Write a content */
496 DWORD cbWritten;
497 WriteFile(hFile, pItem->pData, pItem->cbData, &cbWritten, NULL);
498 }
499
500 /* Close file now */
501 CloseHandle(hFile);
502 } else
503 bSuccess = FALSE;
504
505 if (pItem->Type == SHELLNEW_TYPE_FILENAME)
506 {
507 /* Copy file */
508 if (!CopyFileW((LPWSTR)pItem->pData, wszPath, FALSE))
509 ERR("Copy file failed: %ls\n", (LPWSTR)pItem->pData);
510 }
511
512 /* Show message if we failed */
513 if (bSuccess)
514 {
515 TRACE("Notifying fs %s\n", debugstr_w(wszPath));
516 SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, (LPCVOID)wszPath, NULL);
517 psv->Refresh();
518
519 LPITEMIDLIST pidl;
520 hr = _ILCreateFromPathW(wszPath, &pidl);
521 if (SUCCEEDED(hr))
522 {
523 psv->SelectItem(pidl, SVSI_DESELECTOTHERS|SVSI_EDIT|SVSI_ENSUREVISIBLE|SVSI_FOCUSED|SVSI_SELECT);
524 ILFree(pidl);
525 }
526 }
527 else
528 {
529 StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create file: %s", pwszFilename);
530 MessageBoxW(NULL, wszBuf, L"Cannot create file", MB_OK|MB_ICONERROR); // FIXME
531 }
532 break;
533 }
534 case SHELLNEW_TYPE_INVALID:
535 ERR("Invalid type\n");
536 break;
537 }
538
539 return S_OK;
540 }
541
542 HRESULT STDMETHODCALLTYPE CNewMenu::SetSite(IUnknown *pUnkSite)
543 {
544 m_pSite = pUnkSite;
545 return S_OK;
546 }
547
548 HRESULT STDMETHODCALLTYPE CNewMenu::GetSite(REFIID riid, void **ppvSite)
549 {
550 return m_pSite->QueryInterface(riid, ppvSite);
551 }
552
553 HRESULT
554 WINAPI
555 CNewMenu::QueryContextMenu(HMENU hMenu,
556 UINT indexMenu,
557 UINT idCmdFirst,
558 UINT idCmdLast,
559 UINT uFlags)
560 {
561 WCHAR wszNew[200];
562 MENUITEMINFOW mii;
563 UINT cItems = 0;
564
565 TRACE("%p %p %u %u %u %u\n", this,
566 hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
567
568 if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, wszNew, _countof(wszNew)))
569 return E_FAIL;
570
571 m_hSubMenu = CreateMenu();
572 if (!m_hSubMenu)
573 return E_FAIL;
574
575 cItems = InsertShellNewItems(m_hSubMenu, idCmdFirst, 0);
576
577 memset(&mii, 0, sizeof(mii));
578 mii.cbSize = sizeof(mii);
579 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
580 mii.fType = MFT_STRING;
581 mii.wID = -1;
582 mii.dwTypeData = wszNew;
583 mii.cch = wcslen(mii.dwTypeData);
584 mii.fState = MFS_ENABLED;
585 mii.hSubMenu = m_hSubMenu;
586
587 if (!InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
588 return E_FAIL;
589
590 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cItems);
591 }
592
593 HRESULT
594 WINAPI
595 CNewMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
596 {
597 CComPtr<IShellBrowser> lpSB;
598 CComPtr<IShellView> lpSV;
599 HRESULT hr = E_FAIL;
600
601 /* Note: CWM_GETISHELLBROWSER returns shell browser without adding reference */
602 lpSB = (LPSHELLBROWSER)SendMessageA(lpici->hwnd, CWM_GETISHELLBROWSER, 0, 0);
603 if (lpSB)
604 lpSB->QueryActiveShellView(&lpSV);
605
606 if (LOWORD(lpici->lpVerb) == 0)
607 hr = CreateNewFolder(lpSV);
608 else
609 {
610 SHELLNEW_ITEM *pItem = FindItemFromIdOffset(LOWORD(lpici->lpVerb));
611 if (pItem)
612 hr = CreateNewItem(pItem, lpici, lpSV);
613 }
614
615 TRACE("CNewMenu::InvokeCommand %x\n", hr);
616 return hr;
617 }
618
619 HRESULT
620 WINAPI
621 CNewMenu::GetCommandString(UINT_PTR idCmd,
622 UINT uType,
623 UINT *pwReserved,
624 LPSTR pszName,
625 UINT cchMax)
626 {
627 FIXME("%p %lu %u %p %p %u\n", this,
628 idCmd, uType, pwReserved, pszName, cchMax );
629
630 return E_NOTIMPL;
631 }
632
633 HRESULT
634 WINAPI
635 CNewMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
636 {
637 return S_OK;
638 }
639
640 HRESULT WINAPI
641 CNewMenu::Initialize(LPCITEMIDLIST pidlFolder,
642 IDataObject *pdtobj, HKEY hkeyProgID)
643 {
644 /* Load folder and shortcut icons */
645 HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON, 0, 0, LR_SHARED);
646 m_hbmFolder = hIcon ? IconToBitmap(hIcon) : NULL;
647 hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 0, 0, LR_SHARED);
648 m_hbmLink = hIcon ? IconToBitmap(hIcon) : NULL;
649
650 return S_OK;
651 }