Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

922 lines
23 KiB

  1. /**************************************************************************
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright 1998 Microsoft Corporation. All Rights Reserved.
  7. **************************************************************************/
  8. /**************************************************************************
  9. File: Utility.cpp
  10. Description: Utility function implementation
  11. **************************************************************************/
  12. /**************************************************************************
  13. #include statements
  14. **************************************************************************/
  15. #include "Utility.h"
  16. #include "ShlFldr.h"
  17. #include "resource.h"
  18. #include "Commands.h"
  19. /**************************************************************************
  20. global variables
  21. **************************************************************************/
  22. #define MAIN_KEY_STRING (TEXT("Software\\SampleView"))
  23. #define VALUE_STRING (TEXT("Display Settings"))
  24. #define DISPLAY_SETTINGS_COUNT 1
  25. /**************************************************************************
  26. CompareItems()
  27. **************************************************************************/
  28. int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
  29. {
  30. CShellFolder *pFolder = (CShellFolder*)lpData;
  31. if(!pFolder)
  32. return 0;
  33. HRESULT hr = pFolder->CompareIDs(0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
  34. return (SHORT)HRESULT_CODE(hr);
  35. }
  36. /**************************************************************************
  37. SaveGlobalSettings()
  38. **************************************************************************/
  39. BOOL SaveGlobalSettings(void)
  40. {
  41. HKEY hKey;
  42. LONG lResult;
  43. DWORD dwDisp;
  44. lResult = RegCreateKeyEx( HKEY_CURRENT_USER,
  45. MAIN_KEY_STRING,
  46. 0,
  47. NULL,
  48. REG_OPTION_NON_VOLATILE,
  49. KEY_ALL_ACCESS,
  50. NULL,
  51. &hKey,
  52. &dwDisp);
  53. if(lResult != ERROR_SUCCESS)
  54. return FALSE;
  55. //create an array to put our data in
  56. DWORD dwArray[DISPLAY_SETTINGS_COUNT];
  57. dwArray[0] = g_nColumn;
  58. //save the last printer selected
  59. lResult = RegSetValueEx( hKey,
  60. VALUE_STRING,
  61. 0,
  62. REG_BINARY,
  63. (LPBYTE)dwArray,
  64. sizeof(dwArray));
  65. RegCloseKey(hKey);
  66. if(lResult != ERROR_SUCCESS)
  67. return FALSE;
  68. return TRUE;
  69. }
  70. /**************************************************************************
  71. GetGlobalSettings()
  72. **************************************************************************/
  73. VOID GetGlobalSettings(VOID)
  74. {
  75. LPITEMIDLIST pidl = NULL;
  76. g_nColumn = INITIAL_COLUMN_SIZE;
  77. LoadString(g_hInst, IDS_EXT_TITLE, g_szExtTitle, TITLE_SIZE);
  78. *g_szStoragePath = 0;
  79. SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl);
  80. if(pidl)
  81. {
  82. IMalloc *pMalloc;
  83. SHGetPathFromIDList(pidl, g_szStoragePath);
  84. SHGetMalloc(&pMalloc);
  85. if(pMalloc)
  86. {
  87. pMalloc->Free(pidl);
  88. pMalloc->Release();
  89. }
  90. }
  91. else
  92. {
  93. GetWindowsDirectory(g_szStoragePath, MAX_PATH);
  94. }
  95. SmartAppendBackslash(g_szStoragePath);
  96. lstrcat(g_szStoragePath, g_szExtTitle);
  97. SmartAppendBackslash(g_szStoragePath);
  98. CreateDirectory(g_szStoragePath, NULL);
  99. HKEY hKey;
  100. LRESULT lResult;
  101. lResult = RegOpenKeyEx( HKEY_CURRENT_USER,
  102. MAIN_KEY_STRING,
  103. 0,
  104. KEY_ALL_ACCESS,
  105. &hKey);
  106. if(lResult != ERROR_SUCCESS)
  107. return;
  108. //create an array to put our data in
  109. DWORD dwArray[DISPLAY_SETTINGS_COUNT];
  110. DWORD dwType;
  111. DWORD dwSize = sizeof(dwArray);
  112. //get the saved data
  113. lResult = RegQueryValueEx( hKey,
  114. VALUE_STRING,
  115. NULL,
  116. &dwType,
  117. (LPBYTE)dwArray,
  118. &dwSize);
  119. RegCloseKey(hKey);
  120. if(lResult != ERROR_SUCCESS)
  121. return;
  122. g_nColumn = dwArray[0];
  123. }
  124. /**************************************************************************
  125. CreateImageLists()
  126. **************************************************************************/
  127. VOID CreateImageLists(VOID)
  128. {
  129. int cx;
  130. int cy;
  131. cx = GetSystemMetrics(SM_CXSMICON);
  132. cy = GetSystemMetrics(SM_CYSMICON);
  133. if(g_himlSmall)
  134. ImageList_Destroy(g_himlSmall);
  135. //set the small image list
  136. g_himlSmall = ImageList_Create(cx, cy, ILC_COLORDDB | ILC_MASK, 3, 0);
  137. if(g_himlSmall)
  138. {
  139. HICON hIcon;
  140. TCHAR szFolder[MAX_PATH];
  141. SHFILEINFO sfi;
  142. //add the item icon
  143. hIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR);
  144. ImageList_AddIcon(g_himlSmall, hIcon);
  145. //add the closed folder icon
  146. GetWindowsDirectory(szFolder, MAX_PATH);
  147. SHGetFileInfo( szFolder,
  148. 0,
  149. &sfi,
  150. sizeof(sfi),
  151. SHGFI_ICON | SHGFI_SMALLICON);
  152. ImageList_AddIcon(g_himlSmall, sfi.hIcon);
  153. //add the open folder icon
  154. SHGetFileInfo( szFolder,
  155. 0,
  156. &sfi,
  157. sizeof(sfi),
  158. SHGFI_ICON | SHGFI_SMALLICON | SHGFI_OPENICON);
  159. ImageList_AddIcon(g_himlSmall, sfi.hIcon);
  160. }
  161. if(g_himlLarge)
  162. ImageList_Destroy(g_himlLarge);
  163. cx = GetSystemMetrics(SM_CXICON);
  164. cy = GetSystemMetrics(SM_CYICON);
  165. //set the large image list
  166. g_himlLarge = ImageList_Create(cx, cy, ILC_COLORDDB | ILC_MASK, 4, 0);
  167. if(g_himlLarge)
  168. {
  169. HICON hIcon;
  170. TCHAR szFolder[MAX_PATH];
  171. SHFILEINFO sfi;
  172. //add the item icon
  173. hIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR);
  174. ImageList_AddIcon(g_himlLarge, hIcon);
  175. //add the closed folder icon
  176. GetWindowsDirectory(szFolder, MAX_PATH);
  177. ZeroMemory(&sfi, sizeof(sfi));
  178. SHGetFileInfo( szFolder,
  179. 0,
  180. &sfi,
  181. sizeof(sfi),
  182. SHGFI_ICON);
  183. ImageList_AddIcon(g_himlLarge, sfi.hIcon);
  184. //add the open folder icon
  185. GetWindowsDirectory(szFolder, MAX_PATH);
  186. ZeroMemory(&sfi, sizeof(sfi));
  187. SHGetFileInfo( szFolder,
  188. 0,
  189. &sfi,
  190. sizeof(sfi),
  191. SHGFI_ICON | SHGFI_OPENICON);
  192. ImageList_AddIcon(g_himlLarge, sfi.hIcon);
  193. }
  194. }
  195. /**************************************************************************
  196. AddIconImageLists()
  197. **************************************************************************/
  198. int AddIconImageList(HIMAGELIST himl, LPCTSTR szImagePath)
  199. {
  200. if(himl)
  201. {
  202. HICON hIcon;
  203. //add the item icon
  204. hIcon = (HICON)LoadImage(NULL, szImagePath, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_LOADFROMFILE | LR_DEFAULTSIZE);
  205. return ImageList_AddIcon(himl, hIcon);
  206. }
  207. else
  208. return -1;
  209. }
  210. /**************************************************************************
  211. DestroyImageLists()
  212. **************************************************************************/
  213. VOID DestroyImageLists(VOID)
  214. {
  215. if(g_himlSmall)
  216. ImageList_Destroy(g_himlSmall);
  217. if(g_himlLarge)
  218. ImageList_Destroy(g_himlLarge);
  219. }
  220. /**************************************************************************
  221. WideCharToLocal()
  222. **************************************************************************/
  223. int WideCharToLocal(LPTSTR pLocal, LPWSTR pWide, DWORD dwChars)
  224. {
  225. *pLocal = 0;
  226. #ifdef UNICODE
  227. lstrcpyn(pLocal, pWide, dwChars);
  228. #else
  229. WideCharToMultiByte( CP_ACP,
  230. 0,
  231. pWide,
  232. -1,
  233. pLocal,
  234. dwChars,
  235. NULL,
  236. NULL);
  237. #endif
  238. return lstrlen(pLocal);
  239. }
  240. /**************************************************************************
  241. LocalToWideChar()
  242. **************************************************************************/
  243. int LocalToWideChar(LPWSTR pWide, LPTSTR pLocal, DWORD dwChars)
  244. {
  245. *pWide = 0;
  246. #ifdef UNICODE
  247. lstrcpyn(pWide, pLocal, dwChars);
  248. #else
  249. MultiByteToWideChar( CP_ACP,
  250. 0,
  251. pLocal,
  252. -1,
  253. pWide,
  254. dwChars);
  255. #endif
  256. return lstrlenW(pWide);
  257. }
  258. /**************************************************************************
  259. LocalToAnsi()
  260. **************************************************************************/
  261. int LocalToAnsi(LPSTR pAnsi, LPCTSTR pLocal, DWORD dwChars)
  262. {
  263. *pAnsi = 0;
  264. #ifdef UNICODE
  265. WideCharToMultiByte( CP_ACP,
  266. 0,
  267. pLocal,
  268. -1,
  269. pAnsi,
  270. dwChars,
  271. NULL,
  272. NULL);
  273. #else
  274. lstrcpyn(pAnsi, pLocal, dwChars);
  275. #endif
  276. return lstrlenA(pAnsi);
  277. }
  278. /**************************************************************************
  279. SmartAppendBackslash()
  280. **************************************************************************/
  281. VOID SmartAppendBackslash(LPTSTR pszPath)
  282. {
  283. if(*(pszPath + lstrlen(pszPath) - 1) != '\\')
  284. lstrcat(pszPath, TEXT("\\"));
  285. }
  286. /**************************************************************************
  287. BuildDataFileName()
  288. **************************************************************************/
  289. int BuildDataFileName(LPTSTR pszDataFile, LPCTSTR pszPath, DWORD dwChars)
  290. {
  291. if(dwChars < (DWORD)(lstrlen(pszPath) + 1 + lstrlen(c_szDataFile)))
  292. return 0;
  293. if(IsBadWritePtr(pszDataFile, dwChars))
  294. return 0;
  295. lstrcpy(pszDataFile, pszPath);
  296. SmartAppendBackslash(pszDataFile);
  297. lstrcat(pszDataFile, c_szDataFile);
  298. return lstrlen(pszDataFile);
  299. }
  300. /**************************************************************************
  301. AnsiToLocal()
  302. **************************************************************************/
  303. int AnsiToLocal(LPTSTR pLocal, LPSTR pAnsi, DWORD dwChars)
  304. {
  305. *pLocal = 0;
  306. #ifdef UNICODE
  307. MultiByteToWideChar( CP_ACP,
  308. 0,
  309. pAnsi,
  310. -1,
  311. pLocal,
  312. dwChars);
  313. #else
  314. lstrcpyn(pLocal, pAnsi, dwChars);
  315. #endif
  316. return lstrlen(pLocal);
  317. }
  318. /**************************************************************************
  319. GetTextFromSTRRET()
  320. **************************************************************************/
  321. BOOL GetTextFromSTRRET( IMalloc * pMalloc,
  322. LPSTRRET pStrRet,
  323. LPCITEMIDLIST pidl,
  324. LPTSTR pszText,
  325. DWORD dwSize)
  326. {
  327. if(IsBadReadPtr(pStrRet, sizeof(UINT)))
  328. return FALSE;
  329. if(IsBadWritePtr(pszText, dwSize))
  330. return FALSE;
  331. switch(pStrRet->uType)
  332. {
  333. case STRRET_CSTR:
  334. AnsiToLocal(pszText, pStrRet->cStr, dwSize);
  335. break;
  336. case STRRET_OFFSET:
  337. lstrcpyn(pszText, (LPTSTR)(((LPBYTE)pidl) + pStrRet->uOffset), dwSize);
  338. break;
  339. case STRRET_WSTR:
  340. {
  341. WideCharToLocal(pszText, pStrRet->pOleStr, dwSize);
  342. if(!pMalloc)
  343. {
  344. SHGetMalloc(&pMalloc);
  345. }
  346. else
  347. {
  348. pMalloc->AddRef();
  349. }
  350. if(pMalloc)
  351. {
  352. pMalloc->Free(pStrRet->pOleStr);
  353. pMalloc->Release();
  354. }
  355. }
  356. break;
  357. default:
  358. return FALSE;
  359. }
  360. return TRUE;
  361. }
  362. /**************************************************************************
  363. IsViewWindow()
  364. **************************************************************************/
  365. BOOL IsViewWindow(HWND hWnd)
  366. {
  367. if(!hWnd)
  368. return FALSE;
  369. TCHAR szClass[MAX_PATH] = TEXT("");
  370. GetClassName(hWnd, szClass, MAX_PATH);
  371. if(0 == lstrcmpi(szClass, NS_CLASS_NAME))
  372. return TRUE;
  373. return FALSE;
  374. }
  375. /**************************************************************************
  376. DeleteDirectory()
  377. **************************************************************************/
  378. BOOL DeleteDirectory(LPCTSTR pszDir)
  379. {
  380. BOOL fReturn = FALSE;
  381. HANDLE hFind;
  382. WIN32_FIND_DATA wfd;
  383. TCHAR szTemp[MAX_PATH];
  384. lstrcpy(szTemp, pszDir);
  385. SmartAppendBackslash(szTemp);
  386. lstrcat(szTemp, TEXT("*.*"));
  387. hFind = FindFirstFile(szTemp, &wfd);
  388. if(INVALID_HANDLE_VALUE != hFind)
  389. {
  390. do
  391. {
  392. if(lstrcmpi(wfd.cFileName, TEXT(".")) &&
  393. lstrcmpi(wfd.cFileName, TEXT("..")))
  394. {
  395. //build the path of the directory or file found
  396. lstrcpy(szTemp, pszDir);
  397. SmartAppendBackslash(szTemp);
  398. lstrcat(szTemp, wfd.cFileName);
  399. if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
  400. {
  401. //we found a directory - call this function recursively
  402. DeleteDirectory(szTemp);
  403. }
  404. else
  405. {
  406. /*
  407. We found a file. Only delete the data file to prevent us from
  408. deleteting something that the user has placed in the folder.
  409. */
  410. if(0 == lstrcmpi(wfd.cFileName, c_szDataFile))
  411. {
  412. DeleteFile(szTemp);
  413. }
  414. }
  415. }
  416. }
  417. while(FindNextFile(hFind, &wfd));
  418. FindClose(hFind);
  419. /*
  420. If this fails it means the directory is not empty, so just remove our
  421. attributes so the enumerator won't see it.
  422. */
  423. fReturn = RemoveDirectory(pszDir);
  424. if(!fReturn)
  425. {
  426. DWORD dwAttr = GetFileAttributes(pszDir);
  427. dwAttr &= ~FILTER_ATTRIBUTES;
  428. fReturn = SetFileAttributes(pszDir, dwAttr);
  429. }
  430. }
  431. return fReturn;
  432. }
  433. /**************************************************************************
  434. CreatePrivateClipboardData()
  435. **************************************************************************/
  436. HGLOBAL CreatePrivateClipboardData( LPITEMIDLIST pidlParent,
  437. LPITEMIDLIST *aPidls,
  438. UINT uItemCount,
  439. BOOL fCut)
  440. {
  441. HGLOBAL hGlobal = NULL;
  442. LPPRIVCLIPDATA pData;
  443. UINT iCurPos;
  444. UINT cbPidl;
  445. UINT i;
  446. CPidlMgr *pPidlMgr;
  447. pPidlMgr = new CPidlMgr();
  448. if(!pPidlMgr)
  449. return NULL;
  450. //get the size of the parent folder's PIDL
  451. cbPidl = pPidlMgr->GetSize(pidlParent);
  452. //get the total size of all of the PIDLs
  453. for(i = 0; i < uItemCount; i++)
  454. {
  455. cbPidl += pPidlMgr->GetSize(aPidls[i]);
  456. }
  457. /*
  458. Find the end of the PRIVCLIPDATA structure. This is the size of the
  459. PRIVCLIPDATA structure itself (which includes one element of aoffset) plus the
  460. additional number of elements in aoffset.
  461. */
  462. iCurPos = sizeof(PRIVCLIPDATA) + (uItemCount * sizeof(UINT));
  463. /*
  464. Allocate the memory for the PRIVCLIPDATA structure and it's variable length members.
  465. */
  466. hGlobal = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)
  467. (iCurPos + // size of the PRIVCLIPDATA structure and the additional aoffset elements
  468. (cbPidl + 1))); // size of the pidls
  469. if (NULL == hGlobal)
  470. return (hGlobal);
  471. pData = (LPPRIVCLIPDATA)GlobalLock(hGlobal);
  472. if(pData)
  473. {
  474. pData->fCut = fCut;
  475. pData->cidl = uItemCount + 1;
  476. pData->aoffset[0] = iCurPos;
  477. //add the PIDL for the parent folder
  478. cbPidl = pPidlMgr->GetSize(pidlParent);
  479. CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)pidlParent, cbPidl);
  480. iCurPos += cbPidl;
  481. for(i = 0; i < uItemCount; i++)
  482. {
  483. //get the size of the PIDL
  484. cbPidl = pPidlMgr->GetSize(aPidls[i]);
  485. //fill out the members of the PRIVCLIPDATA structure.
  486. pData->aoffset[i + 1] = iCurPos;
  487. //copy the contents of the PIDL
  488. CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)aPidls[i], cbPidl);
  489. //set up the position of the next PIDL
  490. iCurPos += cbPidl;
  491. }
  492. GlobalUnlock(hGlobal);
  493. }
  494. delete pPidlMgr;
  495. return (hGlobal);
  496. }
  497. /**************************************************************************
  498. CreateShellIDList()
  499. **************************************************************************/
  500. HGLOBAL CreateShellIDList( LPITEMIDLIST pidlParent,
  501. LPITEMIDLIST *aPidls,
  502. UINT uItemCount)
  503. {
  504. HGLOBAL hGlobal = NULL;
  505. LPIDA pData;
  506. UINT iCurPos;
  507. UINT cbPidl;
  508. UINT i;
  509. CPidlMgr *pPidlMgr;
  510. pPidlMgr = new CPidlMgr();
  511. if(!pPidlMgr)
  512. return NULL;
  513. //get the size of the parent folder's PIDL
  514. cbPidl = pPidlMgr->GetSize(pidlParent);
  515. //get the total size of all of the PIDLs
  516. for(i = 0; i < uItemCount; i++)
  517. {
  518. cbPidl += pPidlMgr->GetSize(aPidls[i]);
  519. }
  520. /*
  521. Find the end of the CIDA structure. This is the size of the
  522. CIDA structure itself (which includes one element of aoffset) plus the
  523. additional number of elements in aoffset.
  524. */
  525. iCurPos = sizeof(CIDA) + (uItemCount * sizeof(UINT));
  526. /*
  527. Allocate the memory for the CIDA structure and it's variable length members.
  528. */
  529. hGlobal = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)
  530. (iCurPos + // size of the CIDA structure and the additional aoffset elements
  531. (cbPidl + 1))); // size of the pidls
  532. if (NULL == hGlobal)
  533. return (hGlobal);
  534. pData = (LPIDA)GlobalLock(hGlobal);
  535. if(pData)
  536. {
  537. pData->cidl = uItemCount + 1;
  538. pData->aoffset[0] = iCurPos;
  539. //add the PIDL for the parent folder
  540. cbPidl = pPidlMgr->GetSize(pidlParent);
  541. CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)pidlParent, cbPidl);
  542. iCurPos += cbPidl;
  543. for(i = 0; i < uItemCount; i++)
  544. {
  545. //get the size of the PIDL
  546. cbPidl = pPidlMgr->GetSize(aPidls[i]);
  547. //fill out the members of the CIDA structure.
  548. pData->aoffset[i + 1] = iCurPos;
  549. //copy the contents of the PIDL
  550. CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)aPidls[i], cbPidl);
  551. //set up the position of the next PIDL
  552. iCurPos += cbPidl;
  553. }
  554. GlobalUnlock(hGlobal);
  555. }
  556. delete pPidlMgr;
  557. return (hGlobal);
  558. }
  559. /**************************************************************************
  560. ItemDataDlgProc()
  561. **************************************************************************/
  562. BOOL CALLBACK ItemDataDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  563. {
  564. static LPTSTR pszData;
  565. switch(uMsg)
  566. {
  567. case WM_INITDIALOG:
  568. pszData = (LPTSTR)lParam;
  569. if(IsBadWritePtr((LPVOID)pszData, MAX_DATA))
  570. {
  571. EndDialog(hWnd, IDCANCEL);
  572. break;
  573. }
  574. SendDlgItemMessage(hWnd, IDC_DATA, EM_LIMITTEXT, MAX_DATA - 1, 0);
  575. SetDlgItemText(hWnd, IDC_DATA, pszData);
  576. break;
  577. case WM_COMMAND:
  578. switch(GET_WM_COMMAND_ID(wParam, lParam))
  579. {
  580. case IDCANCEL:
  581. EndDialog(hWnd, IDCANCEL);
  582. break;
  583. case IDOK:
  584. GetDlgItemText(hWnd, IDC_DATA, pszData, MAX_DATA);
  585. EndDialog(hWnd, IDOK);
  586. break;
  587. }
  588. break;
  589. default:
  590. break;
  591. }
  592. return FALSE;
  593. }
  594. /**************************************************************************
  595. GetViewInterface()
  596. **************************************************************************/
  597. LPVOID GetViewInterface(HWND hWnd)
  598. {
  599. IUnknown *pRet = NULL;
  600. if(IsViewWindow(hWnd))
  601. {
  602. pRet = (IUnknown*)GetWindowLong(hWnd, VIEW_POINTER_OFFSET);
  603. }
  604. if(pRet)
  605. pRet->AddRef();
  606. return (LPVOID)pRet;
  607. }
  608. /**************************************************************************
  609. AddViewMenuItems()
  610. **************************************************************************/
  611. UINT AddViewMenuItems( HMENU hMenu,
  612. UINT uOffset,
  613. UINT uInsertBefore,
  614. BOOL fByPosition)
  615. {
  616. MENUITEMINFO mii;
  617. TCHAR szText[MAX_PATH] = TEXT("");
  618. UINT uAdded = 0;
  619. ZeroMemory(&mii, sizeof(mii));
  620. mii.cbSize = sizeof(mii);
  621. //add the view menu items at the correct position in the menu
  622. LoadString(g_hInst, IDS_VIEW_LARGE, szText, sizeof(szText));
  623. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  624. mii.fType = MFT_STRING;
  625. mii.fState = MFS_ENABLED;
  626. mii.dwTypeData = szText;
  627. mii.wID = uOffset + IDM_VIEW_LARGE;
  628. InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
  629. uAdded++;
  630. LoadString(g_hInst, IDS_VIEW_SMALL, szText, sizeof(szText));
  631. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  632. mii.fType = MFT_STRING;
  633. mii.fState = MFS_ENABLED;
  634. mii.dwTypeData = szText;
  635. mii.wID = uOffset + IDM_VIEW_SMALL;
  636. InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
  637. uAdded++;
  638. LoadString(g_hInst, IDS_VIEW_LIST, szText, sizeof(szText));
  639. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  640. mii.fType = MFT_STRING;
  641. mii.fState = MFS_ENABLED;
  642. mii.dwTypeData = szText;
  643. mii.wID = uOffset + IDM_VIEW_LIST;
  644. InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
  645. uAdded++;
  646. LoadString(g_hInst, IDS_VIEW_DETAILS, szText, sizeof(szText));
  647. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  648. mii.fType = MFT_STRING;
  649. mii.fState = MFS_ENABLED;
  650. mii.dwTypeData = szText;
  651. mii.wID = uOffset + IDM_VIEW_DETAILS;
  652. InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
  653. uAdded++;
  654. return uAdded;
  655. }
  656. /**************************************************************************
  657. AddFileMenuItems()
  658. **************************************************************************/
  659. UINT AddFileMenuItems( HMENU hMenu,
  660. UINT uOffset,
  661. UINT uInsertBefore,
  662. BOOL fByPosition)
  663. {
  664. //add the file menu items
  665. TCHAR szText[MAX_PATH] = TEXT("");
  666. MENUITEMINFO mii;
  667. HMENU hPopup;
  668. UINT uAdded = 0;
  669. hPopup = CreatePopupMenu();
  670. if(hPopup)
  671. {
  672. ZeroMemory(&mii, sizeof(mii));
  673. mii.cbSize = sizeof(mii);
  674. LoadString(g_hInst, IDS_NEW_FOLDER, szText, sizeof(szText));
  675. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  676. mii.fType = MFT_STRING;
  677. mii.fState = MFS_ENABLED;
  678. mii.dwTypeData = szText;
  679. mii.wID = uOffset + IDM_NEW_FOLDER;
  680. InsertMenuItem(hPopup, -1, FALSE, &mii);
  681. LoadString(g_hInst, IDS_NEW_ITEM, szText, sizeof(szText));
  682. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
  683. mii.fType = MFT_STRING;
  684. mii.fState = MFS_ENABLED;
  685. mii.dwTypeData = szText;
  686. mii.wID = uOffset + IDM_NEW_ITEM;
  687. InsertMenuItem(hPopup, -1, FALSE, &mii);
  688. LoadString(g_hInst, IDS_NEW, szText, sizeof(szText));
  689. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
  690. mii.fType = MFT_STRING;
  691. mii.fState = MFS_ENABLED;
  692. mii.dwTypeData = szText;
  693. mii.wID = uOffset + IDM_NEW;
  694. mii.hSubMenu = hPopup;
  695. InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
  696. uAdded++;
  697. }
  698. return uAdded;
  699. }