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.

1347 lines
56 KiB

  1. /*
  2. * CONVERT.CPP
  3. *
  4. * Implements the OleUIConvert function which invokes the complete
  5. * Convert dialog.
  6. *
  7. * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  8. */
  9. #include "precomp.h"
  10. #include "common.h"
  11. #include <stdlib.h>
  12. #include "utility.h"
  13. #include "iconbox.h"
  14. #include "strsafe.h"
  15. #include <reghelp.hxx>
  16. OLEDBGDATA
  17. // Internally used structure
  18. typedef struct tagCONVERT
  19. {
  20. // Keep this item first as the Standard* functions depend on it here.
  21. LPOLEUICONVERT lpOCV; // Original structure passed.
  22. UINT nIDD; // IDD of dialog (used for help info)
  23. /*
  24. * What we store extra in this structure besides the original caller's
  25. * pointer are those fields that we need to modify during the life of
  26. * the dialog but that we don't want to change in the original structure
  27. * until the user presses OK.
  28. */
  29. DWORD dwFlags; // Flags passed in
  30. HWND hListVisible; // listbox that is currently visible
  31. HWND hListInvisible; // listbox that is currently hidden
  32. CLSID clsid; // Class ID sent in to dialog: IN only
  33. DWORD dvAspect;
  34. BOOL fCustomIcon;
  35. UINT IconIndex; // index (in exe) of current icon
  36. LPTSTR lpszIconSource; // path to current icon source
  37. LPTSTR lpszCurrentObject;
  38. LPTSTR lpszConvertDefault;
  39. LPTSTR lpszActivateDefault;
  40. } CONVERT, *PCONVERT, FAR *LPCONVERT;
  41. // Internal function prototypes
  42. // CONVERT.CPP
  43. INT_PTR CALLBACK ConvertDialogProc(HWND, UINT, WPARAM, LPARAM);
  44. BOOL FConvertInit(HWND hDlg, WPARAM, LPARAM);
  45. void SetConvertResults(HWND, LPCONVERT);
  46. UINT FillClassList(CLSID clsid, HWND hList, HWND hListInvisible,
  47. LPTSTR FAR *lplpszCurrentClass, BOOL fIsLinkedObject, WORD wFormat,
  48. UINT cClsidExclude, LPCLSID lpClsidExclude, BOOL bAddSameClass);
  49. BOOL FormatIncluded(LPTSTR szStringToSearch, WORD wFormat);
  50. void SwapWindows(HWND, HWND, HWND);
  51. void ConvertCleanup(HWND hDlg, LPCONVERT lpCV);
  52. static void UpdateClassIcon(HWND hDlg, LPCONVERT lpCV, HWND hList);
  53. /*
  54. * OleUIConvert
  55. *
  56. * Purpose:
  57. * Invokes the standard OLE Change Type dialog box allowing the user
  58. * to change the type of the single specified object, or change the
  59. * type of all OLE objects of a specified type.
  60. *
  61. * Parameters:
  62. * lpCV LPOLEUICONVERT pointing to the in-out structure
  63. * for this dialog.
  64. *
  65. * Return Value:
  66. * UINT One of the following codes, indicating success or error:
  67. * OLEUI_SUCCESS Success
  68. * OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
  69. */
  70. STDAPI_(UINT) OleUIConvert(LPOLEUICONVERT lpCV)
  71. {
  72. HGLOBAL hMemDlg = NULL;
  73. UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpCV, sizeof(OLEUICONVERT),
  74. &hMemDlg);
  75. if (OLEUI_SUCCESS != uRet)
  76. return uRet;
  77. if (lpCV->hMetaPict != NULL && !IsValidMetaPict(lpCV->hMetaPict))
  78. {
  79. return(OLEUI_CTERR_HMETAPICTINVALID);
  80. }
  81. if ((lpCV->dwFlags & CF_SETCONVERTDEFAULT)
  82. && (!IsValidClassID(lpCV->clsidConvertDefault)))
  83. uRet = OLEUI_CTERR_CLASSIDINVALID;
  84. if ((lpCV->dwFlags & CF_SETACTIVATEDEFAULT)
  85. && (!IsValidClassID(lpCV->clsidActivateDefault)))
  86. uRet = OLEUI_CTERR_CLASSIDINVALID;
  87. if ((lpCV->dvAspect != DVASPECT_ICON) && (lpCV->dvAspect != DVASPECT_CONTENT))
  88. uRet = OLEUI_CTERR_DVASPECTINVALID;
  89. if ((lpCV->wFormat >= CF_CLIPBOARDMIN) && (lpCV->wFormat <= CF_CLIPBOARDMAX))
  90. {
  91. TCHAR szTemp[8];
  92. if (0 == GetClipboardFormatName(lpCV->wFormat, szTemp, 8))
  93. uRet = OLEUI_CTERR_CBFORMATINVALID;
  94. }
  95. if ((NULL != lpCV->lpszUserType)
  96. && (IsBadReadPtr(lpCV->lpszUserType, 1)))
  97. uRet = OLEUI_CTERR_STRINGINVALID;
  98. if ( (NULL != lpCV->lpszDefLabel)
  99. && (IsBadReadPtr(lpCV->lpszDefLabel, 1)) )
  100. uRet = OLEUI_CTERR_STRINGINVALID;
  101. if (0 != lpCV->cClsidExclude &&
  102. IsBadReadPtr(lpCV->lpClsidExclude, lpCV->cClsidExclude * sizeof(CLSID)))
  103. {
  104. uRet = OLEUI_IOERR_LPCLSIDEXCLUDEINVALID;
  105. }
  106. if (OLEUI_ERR_STANDARDMIN <= uRet)
  107. {
  108. return uRet;
  109. }
  110. UINT nIDD;
  111. if (!bWin4)
  112. nIDD = lpCV->dwFlags & CF_CONVERTONLY ? IDD_CONVERTONLY : IDD_CONVERT;
  113. else
  114. nIDD = lpCV->dwFlags & CF_CONVERTONLY ? IDD_CONVERTONLY4 : IDD_CONVERT4;
  115. // Now that we've validated everything, we can invoke the dialog.
  116. uRet = UStandardInvocation(ConvertDialogProc, (LPOLEUISTANDARD)lpCV,
  117. hMemDlg, MAKEINTRESOURCE(nIDD));
  118. return uRet;
  119. }
  120. /*
  121. * ConvertDialogProc
  122. *
  123. * Purpose:
  124. * Implements the OLE Convert dialog as invoked through the
  125. * OleUIConvert function.
  126. *
  127. * Parameters:
  128. * Standard
  129. *
  130. * Return Value:
  131. * Standard
  132. *
  133. */
  134. INT_PTR CALLBACK ConvertDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  135. {
  136. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  137. COMMANDPARAMS(wID, wCode, hWndMsg);
  138. // This will fail under WM_INITDIALOG, where we allocate it.
  139. UINT uRet = 0;
  140. LPCONVERT lpCV = (LPCONVERT)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
  141. //If the hook processed the message, we're done.
  142. if (0 != uRet)
  143. return (INT_PTR)uRet;
  144. //Process the temination message
  145. if (iMsg == uMsgEndDialog)
  146. {
  147. EndDialog(hDlg, wParam);
  148. return TRUE;
  149. }
  150. // Process help message from Change Icon
  151. if (iMsg == uMsgHelp)
  152. {
  153. PostMessage(lpCV->lpOCV->hWndOwner, uMsgHelp, wParam, lParam);
  154. return FALSE;
  155. }
  156. switch (iMsg)
  157. {
  158. case WM_DESTROY:
  159. if (lpCV)
  160. {
  161. ConvertCleanup(hDlg, lpCV);
  162. StandardCleanup(lpCV, hDlg);
  163. }
  164. break;
  165. case WM_INITDIALOG:
  166. FConvertInit(hDlg, wParam, lParam);
  167. return TRUE;
  168. case WM_COMMAND:
  169. switch (wID)
  170. {
  171. case IDC_CV_ACTIVATELIST:
  172. case IDC_CV_CONVERTLIST:
  173. switch (wCode)
  174. {
  175. case LBN_SELCHANGE:
  176. // Change "Results" window to reflect current selection
  177. SetConvertResults(hDlg, lpCV);
  178. // Update the icon we display, if in display as icon mode
  179. if ((lpCV->dwFlags & CF_SELECTCONVERTTO) &&
  180. lpCV->dvAspect == DVASPECT_ICON && !lpCV->fCustomIcon)
  181. {
  182. UpdateClassIcon(hDlg, lpCV, hWndMsg);
  183. }
  184. break;
  185. case LBN_DBLCLK:
  186. SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
  187. break;
  188. }
  189. break;
  190. case IDC_CV_CONVERTTO:
  191. case IDC_CV_ACTIVATEAS:
  192. {
  193. HWND hList = lpCV->hListVisible;
  194. HWND hListInvisible = lpCV->hListInvisible;
  195. if (IDC_CV_CONVERTTO == wParam)
  196. {
  197. // User just click on the button again - it was
  198. // already selected.
  199. if (lpCV->dwFlags & CF_SELECTCONVERTTO)
  200. break;
  201. // If we're working with a linked object, don't
  202. // add the activate list - just the object's
  203. // class should appear in the listbox.
  204. SwapWindows(hDlg, hList, hListInvisible);
  205. lpCV->hListVisible = hListInvisible;
  206. lpCV->hListInvisible = hList;
  207. EnableWindow(lpCV->hListInvisible, FALSE);
  208. EnableWindow(lpCV->hListVisible, TRUE);
  209. // Update our flags.
  210. lpCV->dwFlags &= ~CF_SELECTACTIVATEAS;
  211. lpCV->dwFlags |= CF_SELECTCONVERTTO;
  212. }
  213. else
  214. {
  215. if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
  216. break;
  217. SwapWindows(hDlg, hList, hListInvisible);
  218. lpCV->hListVisible = hListInvisible;
  219. lpCV->hListInvisible = hList;
  220. EnableWindow(lpCV->hListInvisible, FALSE);
  221. EnableWindow(lpCV->hListVisible, TRUE);
  222. // Update our flags.
  223. lpCV->dwFlags |= CF_SELECTACTIVATEAS;
  224. lpCV->dwFlags &= ~CF_SELECTCONVERTTO;
  225. }
  226. LRESULT lRetVal;
  227. if (lpCV->dwFlags & CF_SELECTCONVERTTO)
  228. lRetVal = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszConvertDefault);
  229. else
  230. lRetVal = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszActivateDefault);
  231. if (LB_ERR == lRetVal)
  232. {
  233. TCHAR szCurrentObject[40];
  234. GetDlgItemText(hDlg, IDC_CV_OBJECTTYPE, szCurrentObject, 40);
  235. SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)szCurrentObject);
  236. }
  237. // Turn updates back on.
  238. SendMessage(hDlg, WM_SETREDRAW, TRUE, 0L);
  239. InvalidateRect(lpCV->hListVisible, NULL, TRUE);
  240. UpdateWindow(lpCV->hListVisible);
  241. if ((lpCV->dvAspect & DVASPECT_ICON) && (lpCV->dwFlags & CF_SELECTCONVERTTO))
  242. UpdateClassIcon(hDlg, lpCV, lpCV->hListVisible);
  243. // Hide the icon stuff when Activate is selected...show
  244. // it again when Convert is selected.
  245. BOOL fState = ((lpCV->dwFlags & CF_SELECTACTIVATEAS) ||
  246. (lpCV->dwFlags & CF_DISABLEDISPLAYASICON)) ?
  247. SW_HIDE : SW_SHOW;
  248. StandardShowDlgItem(hDlg, IDC_CV_DISPLAYASICON, fState);
  249. // Only display the icon if convert is selected AND
  250. // display as icon is checked.
  251. if ((SW_SHOW==fState) && (DVASPECT_ICON!=lpCV->dvAspect))
  252. fState = SW_HIDE;
  253. StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, fState);
  254. StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, fState);
  255. SetConvertResults(hDlg, lpCV);
  256. }
  257. break;
  258. case IDOK:
  259. {
  260. // Set output flags to current ones
  261. lpCV->lpOCV->dwFlags = lpCV->dwFlags;
  262. // Update the dvAspect and fObjectsIconChanged members
  263. // as appropriate.
  264. if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
  265. {
  266. // DON'T update aspect if activate as was selected.
  267. lpCV->lpOCV->fObjectsIconChanged = FALSE;
  268. }
  269. else
  270. lpCV->lpOCV->dvAspect = lpCV->dvAspect;
  271. // Get the new clsid
  272. TCHAR szBuffer[256];
  273. LRESULT iCurSel = SendMessage(lpCV->hListVisible, LB_GETCURSEL, 0, 0);
  274. SendMessage(lpCV->hListVisible, LB_GETTEXT, iCurSel, (LPARAM)szBuffer);
  275. LPTSTR lpszCLSID = PointerToNthField(szBuffer, 2, '\t');
  276. CLSIDFromString(lpszCLSID, (&(lpCV->lpOCV->clsidNew)));
  277. // Free the hMetaPict we got in.
  278. OleUIMetafilePictIconFree(lpCV->lpOCV->hMetaPict);
  279. // Get the hMetaPict (if display as icon is checked)
  280. if (DVASPECT_ICON == lpCV->dvAspect)
  281. lpCV->lpOCV->hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
  282. IDC_CV_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
  283. else
  284. lpCV->lpOCV->hMetaPict = (HGLOBAL)NULL;
  285. SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
  286. }
  287. break;
  288. case IDCANCEL:
  289. {
  290. HGLOBAL hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
  291. IDC_CV_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
  292. OleUIMetafilePictIconFree(hMetaPict);
  293. SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
  294. }
  295. break;
  296. case IDC_OLEUIHELP:
  297. PostMessage(lpCV->lpOCV->hWndOwner,
  298. uMsgHelp, (WPARAM)hDlg, MAKELPARAM(IDD_CONVERT, 0));
  299. break;
  300. case IDC_CV_DISPLAYASICON:
  301. {
  302. BOOL fCheck = IsDlgButtonChecked(hDlg, wID);
  303. if (fCheck)
  304. lpCV->dvAspect = DVASPECT_ICON;
  305. else
  306. lpCV->dvAspect = DVASPECT_CONTENT;
  307. if (fCheck && !lpCV->fCustomIcon)
  308. UpdateClassIcon(hDlg, lpCV, lpCV->hListVisible);
  309. // Show or hide the icon depending on the check state.
  310. int i = (fCheck) ? SW_SHOWNORMAL : SW_HIDE;
  311. StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, i);
  312. StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, i);
  313. SetConvertResults(hDlg, lpCV);
  314. }
  315. break;
  316. case IDC_CV_CHANGEICON:
  317. {
  318. // Initialize the structure for the hook.
  319. OLEUICHANGEICON ci; memset(&ci, 0, sizeof(ci));
  320. ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
  321. IDC_CV_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
  322. ci.cbStruct = sizeof(ci);
  323. ci.hWndOwner= hDlg;
  324. ci.dwFlags = CIF_SELECTCURRENT;
  325. // Only show help if we're showing it for this dialog.
  326. if (lpCV->dwFlags & CF_SHOWHELPBUTTON)
  327. ci.dwFlags |= CIF_SHOWHELP;
  328. int iSel = (INT)SendMessage(lpCV->hListVisible, LB_GETCURSEL, 0, 0);
  329. // Get whole string
  330. LPTSTR pszString = (LPTSTR)OleStdMalloc(
  331. OLEUI_CCHLABELMAX_SIZE + OLEUI_CCHCLSIDSTRING_SIZE);
  332. SendMessage(lpCV->hListVisible, LB_GETTEXT, iSel, (LPARAM)pszString);
  333. // Set pointer to CLSID (string)
  334. LPTSTR pszCLSID = PointerToNthField(pszString, 2, '\t');
  335. // Get the clsid to pass to change icon.
  336. CLSIDFromString(pszCLSID, &(ci.clsid));
  337. OleStdFree(pszString);
  338. // Let the hook in to customize Change Icon if desired.
  339. uRet = UStandardHook(lpCV, hDlg, uMsgChangeIcon, 0, (LPARAM)&ci);
  340. if (0 == uRet)
  341. uRet= (OLEUI_OK == OleUIChangeIcon(&ci));
  342. // Update the display if necessary.
  343. if (0 != uRet)
  344. {
  345. SendDlgItemMessage(hDlg, IDC_CV_ICONDISPLAY, IBXM_IMAGESET, 0,
  346. (LPARAM)ci.hMetaPict);
  347. // Update our custom/default flag
  348. if (ci.dwFlags & CIF_SELECTDEFAULT)
  349. lpCV->fCustomIcon = FALSE; // we're in default mode (icon changes on each LB selchange)
  350. else if (ci.dwFlags & CIF_SELECTFROMFILE)
  351. lpCV->fCustomIcon = TRUE; // we're in custom mode (icon doesn't change)
  352. // no change in fCustomIcon if user selected current
  353. lpCV->lpOCV->fObjectsIconChanged = TRUE;
  354. }
  355. }
  356. break;
  357. }
  358. break;
  359. }
  360. return FALSE;
  361. }
  362. /*
  363. * FConvertInit
  364. *
  365. * Purpose:
  366. * WM_INITIDIALOG handler for the Convert dialog box.
  367. *
  368. * Parameters:
  369. * hDlg HWND of the dialog
  370. * wParam WPARAM of the message
  371. * lParam LPARAM of the message
  372. *
  373. * Return Value:
  374. * BOOL Value to return for WM_INITDIALOG.
  375. */
  376. BOOL FConvertInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  377. {
  378. // Copy the structure at lParam into our instance memory.
  379. HFONT hFont; // non-bold version of dialog's font
  380. LPCONVERT lpCV = (LPCONVERT)LpvStandardInit(hDlg, sizeof(CONVERT), &hFont);
  381. // PvStandardInit send a termination to us already.
  382. if (NULL == lpCV)
  383. return FALSE;
  384. LPOLEUICONVERT lpOCV = (LPOLEUICONVERT)lParam;
  385. lpCV->lpOCV = lpOCV;
  386. lpCV->nIDD = IDD_CONVERT;
  387. lpCV->fCustomIcon = FALSE;
  388. // Copy other information from lpOCV that we might modify.
  389. lpCV->dwFlags = lpOCV->dwFlags;
  390. lpCV->clsid = lpOCV->clsid;
  391. lpCV->dvAspect = lpOCV->dvAspect;
  392. lpCV->hListVisible = GetDlgItem(hDlg, IDC_CV_ACTIVATELIST);
  393. lpCV->hListInvisible = GetDlgItem(hDlg, IDC_CV_CONVERTLIST);
  394. OleDbgAssert(lpCV->hListInvisible != NULL);
  395. lpCV->lpszCurrentObject = lpOCV->lpszUserType;
  396. lpOCV->clsidNew = CLSID_NULL;
  397. lpOCV->fObjectsIconChanged = FALSE;
  398. lpCV->lpszConvertDefault = (LPTSTR)OleStdMalloc(OLEUI_CCHLABELMAX_SIZE);
  399. lpCV->lpszActivateDefault = (LPTSTR)OleStdMalloc(OLEUI_CCHLABELMAX_SIZE);
  400. lpCV->lpszIconSource = (LPTSTR)OleStdMalloc(MAX_PATH_SIZE);
  401. if ((lpCV->lpszConvertDefault == NULL) ||
  402. (lpCV->lpszActivateDefault == NULL) ||
  403. (lpCV->lpszIconSource == NULL))
  404. {
  405. if (lpCV->lpszConvertDefault != NULL)
  406. OleStdFree (lpCV->lpszConvertDefault);
  407. if (lpCV->lpszActivateDefault != NULL)
  408. OleStdFree (lpCV->lpszActivateDefault);
  409. if (lpCV->lpszIconSource != NULL)
  410. OleStdFree (lpCV->lpszIconSource);
  411. // Gonna kill the window...
  412. PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
  413. return FALSE;
  414. }
  415. // If we got a font, send it to the necessary controls.
  416. if (NULL != hFont)
  417. {
  418. SendDlgItemMessage(hDlg, IDC_CV_OBJECTTYPE, WM_SETFONT, (WPARAM)hFont, 0L);
  419. SendDlgItemMessage(hDlg, IDC_CV_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L);
  420. }
  421. // Hide the help button if necessary
  422. if (!(lpCV->dwFlags & CF_SHOWHELPBUTTON))
  423. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  424. // Show or hide the Change icon button
  425. if (lpCV->dwFlags & CF_HIDECHANGEICON)
  426. DestroyWindow(GetDlgItem(hDlg, IDC_CV_CHANGEICON));
  427. // Fill the Object Type listbox with entries from the reg DB.
  428. UINT nRet = FillClassList(lpOCV->clsid, lpCV->hListVisible,
  429. lpCV->hListInvisible, &(lpCV->lpszCurrentObject),
  430. lpOCV->fIsLinkedObject, lpOCV->wFormat,
  431. lpOCV->cClsidExclude, lpOCV->lpClsidExclude,
  432. !(lpCV->dwFlags & CF_CONVERTONLY));
  433. if (nRet == -1)
  434. {
  435. // bring down dialog if error when filling list box
  436. PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L);
  437. }
  438. // Set the name of the current object.
  439. SetDlgItemText(hDlg, IDC_CV_OBJECTTYPE, lpCV->lpszCurrentObject);
  440. // Disable the "Activate As" button if the Activate list doesn't
  441. // have any objects in it.
  442. int cItemsActivate = (INT)SendMessage(lpCV->hListVisible, LB_GETCOUNT, 0, 0L);
  443. if (1 >= cItemsActivate || (lpCV->dwFlags & CF_DISABLEACTIVATEAS))
  444. StandardEnableDlgItem(hDlg, IDC_CV_ACTIVATEAS, FALSE);
  445. // Set the tab width in the list to push all the tabs off the side.
  446. RECT rect;
  447. if (lpCV->hListVisible != NULL)
  448. GetClientRect(lpCV->hListVisible, &rect);
  449. else
  450. GetClientRect(lpCV->hListInvisible, &rect);
  451. DWORD dw = GetDialogBaseUnits();
  452. rect.right = (8*rect.right)/LOWORD(dw); //Convert pixels to 2x dlg units.
  453. if (lpCV->hListVisible != NULL)
  454. SendMessage(lpCV->hListVisible, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)(&rect.right));
  455. SendMessage(lpCV->hListInvisible, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)(&rect.right));
  456. // Make sure that either "Convert To" or "Activate As" is selected
  457. // and initialize listbox contents and selection accordingly
  458. if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
  459. {
  460. // Don't need to adjust listbox here because FillClassList
  461. // initializes to the "Activate As" state.
  462. CheckRadioButton(hDlg, IDC_CV_CONVERTTO, IDC_CV_ACTIVATEAS, IDC_CV_ACTIVATEAS);
  463. // Hide the icon stuff when Activate is selected...it gets shown
  464. // again when Convert is selected.
  465. StandardShowDlgItem(hDlg, IDC_CV_DISPLAYASICON, SW_HIDE);
  466. StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, SW_HIDE);
  467. StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, SW_HIDE);
  468. }
  469. else
  470. {
  471. // Default case. If user hasn't selected either flag, we will
  472. // come here anyway.
  473. // swap listboxes.
  474. HWND hWndTemp = lpCV->hListVisible;
  475. if (lpCV->dwFlags & CF_DISABLEDISPLAYASICON)
  476. {
  477. StandardShowDlgItem(hDlg, IDC_CV_DISPLAYASICON, SW_HIDE);
  478. StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, SW_HIDE);
  479. StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, SW_HIDE);
  480. }
  481. lpCV->dwFlags |= CF_SELECTCONVERTTO; // Make sure flag is set
  482. if (!(lpCV->dwFlags & CF_CONVERTONLY))
  483. CheckRadioButton(hDlg, IDC_CV_CONVERTTO, IDC_CV_ACTIVATEAS, IDC_CV_CONVERTTO);
  484. SwapWindows(hDlg, lpCV->hListVisible, lpCV->hListInvisible);
  485. lpCV->hListVisible = lpCV->hListInvisible;
  486. lpCV->hListInvisible = hWndTemp;
  487. if (lpCV->hListInvisible)
  488. EnableWindow(lpCV->hListInvisible, FALSE);
  489. EnableWindow(lpCV->hListVisible, TRUE);
  490. }
  491. // Initialize Default strings.
  492. // Default convert string is easy...just user the user type name from
  493. // the clsid we got, or the current object
  494. if ((lpCV->dwFlags & CF_SETCONVERTDEFAULT)
  495. && (IsValidClassID(lpCV->lpOCV->clsidConvertDefault)))
  496. {
  497. LPOLESTR lpszTemp = NULL;
  498. if (OleRegGetUserType(lpCV->lpOCV->clsidConvertDefault, USERCLASSTYPE_FULL,
  499. &lpszTemp) == NOERROR)
  500. {
  501. StringCchCopy(lpCV->lpszConvertDefault, OLEUI_CCHLABELMAX, lpszTemp);
  502. OleStdFree(lpszTemp);
  503. }
  504. else
  505. {
  506. StringCchCopy(lpCV->lpszConvertDefault, OLEUI_CCHLABELMAX, lpCV->lpszCurrentObject);
  507. }
  508. }
  509. else
  510. StringCchCopy(lpCV->lpszConvertDefault, OLEUI_CCHLABELMAX,
  511. (lpCV->lpszCurrentObject ? lpCV->lpszCurrentObject : TEXT("")));
  512. // Default activate is a bit trickier. We want to use the user type
  513. // name if from the clsid we got (assuming we got one), or the current
  514. // object if it fails or we didn't get a clsid. But...if there's a
  515. // Treat As entry in the reg db, then we use that instead. So... the
  516. // logic boils down to this:
  517. //
  518. // if ("Treat As" in reg db)
  519. // use it;
  520. // else
  521. // if (CF_SETACTIVATEDEFAULT)
  522. // use it;
  523. // else
  524. // use current object;
  525. HKEY hKey;
  526. LONG lRet = OpenClassesRootKey(TEXT("CLSID"), &hKey);
  527. LPARAM lpRet;
  528. if (lRet != ERROR_SUCCESS)
  529. goto CheckInputFlag;
  530. LPOLESTR lpszCLSID;
  531. StringFromCLSID(lpCV->lpOCV->clsid, &lpszCLSID);
  532. TCHAR szKey[OLEUI_CCHKEYMAX];
  533. StringCchCopy(szKey, OLEUI_CCHCLSIDSTRING+1, lpszCLSID);
  534. StringCchCat(szKey, OLEUI_CCHKEYMAX, TEXT("\\TreatAs"));
  535. OleStdFree(lpszCLSID);
  536. TCHAR szValue[OLEUI_CCHKEYMAX];
  537. dw = OLEUI_CCHKEYMAX_SIZE;
  538. lRet = RegQueryValue(hKey, szKey, szValue, (LONG*)&dw);
  539. CLSID clsid;
  540. if (lRet != ERROR_SUCCESS)
  541. {
  542. RegCloseKey(hKey);
  543. goto CheckInputFlag;
  544. }
  545. else
  546. {
  547. CLSIDFromString(szValue, &clsid);
  548. LPOLESTR lpszTemp = NULL;
  549. if (OleRegGetUserType(clsid, USERCLASSTYPE_FULL, &lpszTemp) == NOERROR)
  550. {
  551. if (lpCV->lpszActivateDefault)
  552. {
  553. lstrcpyn(lpCV->lpszActivateDefault, lpszTemp, OLEUI_CCHLABELMAX);
  554. }
  555. OleStdFree(lpszTemp);
  556. }
  557. else
  558. {
  559. RegCloseKey(hKey);
  560. goto CheckInputFlag;
  561. }
  562. }
  563. RegCloseKey(hKey);
  564. goto SelectStringInListbox;
  565. CheckInputFlag:
  566. if ((lpCV->dwFlags & CF_SETACTIVATEDEFAULT)
  567. && (IsValidClassID(lpCV->lpOCV->clsidActivateDefault)))
  568. {
  569. LPOLESTR lpszTemp = NULL;
  570. if (OleRegGetUserType(lpCV->lpOCV->clsidActivateDefault, USERCLASSTYPE_FULL,
  571. &lpszTemp) == NOERROR)
  572. {
  573. lstrcpyn(lpCV->lpszActivateDefault, lpszTemp, OLEUI_CCHLABELMAX);
  574. OleStdFree(lpszTemp);
  575. }
  576. else
  577. {
  578. StringCchCopy(lpCV->lpszActivateDefault, OLEUI_CCHLABELMAX, lpCV->lpszCurrentObject);
  579. }
  580. }
  581. else
  582. if ((lpCV->lpszActivateDefault) && (lpCV->lpszCurrentObject))
  583. StringCchCopy((lpCV->lpszActivateDefault), OLEUI_CCHLABELMAX, lpCV->lpszCurrentObject);
  584. SelectStringInListbox:
  585. if (lpCV->dwFlags & CF_SELECTCONVERTTO)
  586. lpRet = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszConvertDefault);
  587. else
  588. lpRet = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszActivateDefault);
  589. if (LB_ERR == lpRet)
  590. SendMessage(lpCV->hListVisible, LB_SETCURSEL, (WPARAM)0, 0L);
  591. if ((HGLOBAL)NULL != lpOCV->hMetaPict)
  592. {
  593. HGLOBAL hMetaPict = OleDuplicateData(lpOCV->hMetaPict, CF_METAFILEPICT, NULL);
  594. SendDlgItemMessage(hDlg, IDC_CV_ICONDISPLAY, IBXM_IMAGESET,
  595. 0, (LPARAM)hMetaPict);
  596. lpCV->fCustomIcon = TRUE;
  597. }
  598. else
  599. {
  600. UpdateClassIcon(hDlg, lpCV, lpCV->hListVisible);
  601. }
  602. // Initialize icon stuff
  603. if (DVASPECT_ICON == lpCV->dvAspect )
  604. {
  605. SendDlgItemMessage(hDlg, IDC_CV_DISPLAYASICON, BM_SETCHECK, TRUE, 0L);
  606. }
  607. else
  608. {
  609. // Hide & disable icon stuff
  610. StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, SW_HIDE);
  611. StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, SW_HIDE);
  612. }
  613. // Call the hook with lCustData in lParam
  614. UStandardHook((LPVOID)lpCV, hDlg, WM_INITDIALOG, wParam, lpOCV->lCustData);
  615. // Update results window
  616. SetConvertResults(hDlg, lpCV);
  617. // Update caption if lpszCaption was specified
  618. if (lpCV->lpOCV->lpszCaption && !IsBadReadPtr(lpCV->lpOCV->lpszCaption, 1))
  619. {
  620. SetWindowText(hDlg, lpCV->lpOCV->lpszCaption);
  621. }
  622. return TRUE;
  623. }
  624. /*
  625. * FillClassList
  626. *
  627. * Purpose:
  628. * Enumerates available OLE object classes from the registration
  629. * database that we can convert or activate the specified clsid from.
  630. *
  631. * Note that this function removes any prior contents of the listbox.
  632. *
  633. * Parameters:
  634. * clsid Class ID for class to find convert classes for
  635. * hList HWND to the listbox to fill.
  636. * hListActivate HWND to invisible listbox that stores "activate as" list.
  637. * lpszClassName LPSTR to put the (hr) class name of the clsid; we
  638. * do it here since we've already got the reg db open.
  639. * fIsLinkedObject BOOL is the original object a linked object
  640. * wFormat WORD specifying the format of the original class.
  641. * cClsidExclude UINT number of entries in exclude list
  642. * lpClsidExclude LPCLSID array classes to exclude for list
  643. *
  644. * Return Value:
  645. * UINT Number of strings added to the listbox, -1 on failure.
  646. */
  647. UINT FillClassList(CLSID clsid, HWND hListActivate, HWND hListConvert,
  648. LPTSTR FAR *lplpszCurrentClass, BOOL fIsLinkedObject,
  649. WORD wFormat, UINT cClsidExclude, LPCLSID lpClsidExclude, BOOL bAddSameClass)
  650. {
  651. // Clean out the existing strings.
  652. if (hListActivate)
  653. SendMessage(hListActivate, LB_RESETCONTENT, 0, 0L);
  654. OleDbgAssert(hListConvert != NULL);
  655. SendMessage(hListConvert, LB_RESETCONTENT, 0, 0L);
  656. // Open up the root key.
  657. HKEY hKey;
  658. LONG lRet = OpenClassesRootKey(TEXT("CLSID"), &hKey);
  659. LPARAM lpRet;
  660. if (ERROR_SUCCESS != lRet)
  661. return (UINT)-1;
  662. if (NULL == *lplpszCurrentClass)
  663. {
  664. if (OleRegGetUserType(clsid, USERCLASSTYPE_FULL, lplpszCurrentClass) != NOERROR)
  665. {
  666. *lplpszCurrentClass = OleStdLoadString(_g_hOleStdResInst, IDS_PSUNKNOWNTYPE);
  667. if (*lplpszCurrentClass == NULL)
  668. {
  669. RegCloseKey(hKey);
  670. return (UINT)-1;
  671. }
  672. }
  673. }
  674. // Get the class name of the original class.
  675. LPTSTR lpszCLSID;
  676. StringFromCLSID(clsid, &lpszCLSID);
  677. // Here, we step through the entire registration db looking for
  678. // class that can read or write the original class' format. We
  679. // maintain two lists - an activate list and a convert list. The
  680. // activate list is a subset of the convert list - activate == read/write
  681. // and convert == read. We swap the listboxes as needed with
  682. // SwapWindows, and keep track of which is which in the lpCV structure.
  683. // Every item has the following format:
  684. //
  685. // Class Name\tclsid\0
  686. UINT cStrings = 0;
  687. TCHAR szClass[OLEUI_CCHKEYMAX];
  688. lRet = RegEnumKey(hKey, cStrings++, szClass, sizeof(szClass) / sizeof(TCHAR));
  689. TCHAR szFormatKey[OLEUI_CCHKEYMAX];
  690. TCHAR szFormat[OLEUI_CCHKEYMAX];
  691. TCHAR szHRClassName[OLEUI_CCHKEYMAX];
  692. CLSID clsidForList;
  693. while (ERROR_SUCCESS == lRet)
  694. {
  695. UINT j;
  696. BOOL fExclude = FALSE;
  697. //Check if this CLSID is in the exclusion list.
  698. HRESULT hr = CLSIDFromString(szClass, &clsidForList);
  699. if (SUCCEEDED(hr))
  700. {
  701. for (j = 0; j < cClsidExclude; j++)
  702. {
  703. if (IsEqualCLSID(clsidForList, lpClsidExclude[j]))
  704. {
  705. fExclude=TRUE;
  706. break;
  707. }
  708. }
  709. if (fExclude)
  710. goto Next; // don't add this class to list
  711. }
  712. // Check for a \Conversion\Readwritable\Main - if its
  713. // readwriteable, then the class can be added to the ActivateAs
  714. // list.
  715. // NOTE: the presence of this key should NOT automatically be
  716. // used to add the class to the CONVERT list.
  717. StringCchCopy(szFormatKey, OLEUI_CCHCLSIDSTRING+1, szClass);
  718. StringCchCat(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), TEXT("\\Conversion\\Readwritable\\Main"));
  719. DWORD dw; dw = OLEUI_CCHKEYMAX_SIZE;
  720. lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
  721. if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
  722. {
  723. // Here, we've got a list of formats that this class can read
  724. // and write. We need to see if the original class' format is
  725. // in this list. We do that by looking for wFormat in
  726. // szFormat - if it in there, then we add this class to the
  727. // ACTIVATEAS list only. we do NOT automatically add it to the
  728. // CONVERT list. Readable and Readwritable format lists should
  729. // be handled separately.
  730. dw=OLEUI_CCHKEYMAX_SIZE;
  731. lRet=RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
  732. if (ERROR_SUCCESS == lRet && hListActivate != NULL)
  733. {
  734. // only add if not already in list
  735. StringCchCat(szHRClassName, sizeof(szHRClassName)/sizeof(szHRClassName[0]), TEXT("\t"));
  736. if (LB_ERR == SendMessage(hListActivate, LB_FINDSTRING, 0, (LPARAM)szHRClassName))
  737. {
  738. StringCchCat(szHRClassName, sizeof(szHRClassName)/sizeof(szHRClassName[0]), szClass);
  739. SendMessage(hListActivate, LB_ADDSTRING, 0, (LPARAM)szHRClassName);
  740. }
  741. }
  742. }
  743. // Here we'll check to see if the original class' format is in the
  744. // readable list. if so, we will add the class to the CONVERTLIST
  745. // We've got a special case for a linked object here.
  746. // If an object is linked, then the only class that
  747. // should appear in the convert list is the object's
  748. // class. So, here we check to see if the object is
  749. // linked. If it is, then we compare the classes. If
  750. // they aren't the same, then we just go to the next key.
  751. if (!fIsLinkedObject || lstrcmp(lpszCLSID, szClass) == 0)
  752. {
  753. //Check for a \Conversion\Readable\Main entry
  754. StringCchCopy(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), szClass);
  755. StringCchCat(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), TEXT("\\Conversion\\Readable\\Main"));
  756. // Check to see if this class can read the original class
  757. // format. If it can, add the string to the listbox as
  758. // CONVERT_LIST.
  759. dw = OLEUI_CCHKEYMAX_SIZE;
  760. lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
  761. if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
  762. {
  763. dw = OLEUI_CCHKEYMAX_SIZE;
  764. lRet = RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
  765. if (ERROR_SUCCESS == lRet)
  766. {
  767. // only add if not already in list
  768. StringCchCat(szHRClassName, sizeof(szHRClassName)/sizeof(szHRClassName[0]), TEXT("\t"));
  769. if (LB_ERR == SendMessage(hListConvert, LB_FINDSTRING, 0, (LPARAM)szHRClassName))
  770. {
  771. StringCchCat(szHRClassName, sizeof(szHRClassName)/sizeof(szHRClassName[0]), szClass);
  772. SendMessage(hListConvert, LB_ADDSTRING, 0, (LPARAM)szHRClassName);
  773. }
  774. }
  775. }
  776. }
  777. Next:
  778. //Continue with the next key.
  779. lRet = RegEnumKey(hKey, cStrings++, szClass, sizeof(szClass) / sizeof(TCHAR));
  780. } // end while
  781. // If the original class isn't already in the list, add it.
  782. if (bAddSameClass)
  783. {
  784. StringCchCopy(szHRClassName, sizeof(szHRClassName)/sizeof(szHRClassName[0]), *lplpszCurrentClass); // -1 so we know we have enough room for "\t"
  785. StringCchCat(szHRClassName, sizeof(szHRClassName)/sizeof(szHRClassName[0]), TEXT("\t"));
  786. StringCchCat(szHRClassName, sizeof(szHRClassName)/sizeof(szHRClassName[0]), lpszCLSID);
  787. if (hListActivate != NULL)
  788. {
  789. // only add it if it's not there already.
  790. lpRet = SendMessage(hListActivate, LB_FINDSTRING, (WPARAM)-1, (LPARAM)szHRClassName);
  791. if (LB_ERR == lpRet)
  792. SendMessage(hListActivate, LB_ADDSTRING, 0, (LPARAM)szHRClassName);
  793. }
  794. // only add it if it's not there already.
  795. lpRet = SendMessage(hListConvert, LB_FINDSTRING, (WPARAM)-1, (LPARAM)szHRClassName);
  796. if (LB_ERR == lpRet)
  797. SendMessage(hListConvert, LB_ADDSTRING, 0, (LPARAM)szHRClassName);
  798. }
  799. // Free the string we got from StringFromCLSID.
  800. OleStdFree(lpszCLSID);
  801. RegCloseKey(hKey);
  802. return cStrings; // return # of strings added
  803. }
  804. /*
  805. * OleUICanConvertOrActivateAs
  806. *
  807. * Purpose:
  808. * Determine if there is any OLE object class from the registration
  809. * database that we can convert or activate the specified clsid from.
  810. *
  811. * Parameters:
  812. * rClsid REFCLSID Class ID for class to find convert classes for
  813. * fIsLinkedObject BOOL is the original object a linked object
  814. * wFormat WORD specifying the format of the original class.
  815. *
  816. * Return Value:
  817. * BOOL TRUE if Convert command should be enabled, else FALSE
  818. */
  819. STDAPI_(BOOL) OleUICanConvertOrActivateAs(
  820. REFCLSID rClsid, BOOL fIsLinkedObject, WORD wFormat)
  821. {
  822. // Open up the root key.
  823. HKEY hKey;
  824. HRESULT hr;
  825. LONG lRet = OpenClassesRootKey(TEXT("CLSID"), &hKey);
  826. if (ERROR_SUCCESS != lRet)
  827. return FALSE;
  828. // Get the class name of the original class.
  829. LPTSTR lpszCLSID = NULL;
  830. hr = StringFromCLSID(rClsid, &lpszCLSID);
  831. if (FAILED(hr) || lpszCLSID == NULL) //out of memory, most likely
  832. return FALSE;
  833. // Here, we step through the entire registration db looking for
  834. // class that can read or write the original class' format.
  835. // This loop stops if a single class is found.
  836. UINT cStrings = 0;
  837. TCHAR szClass[OLEUI_CCHKEYMAX];
  838. lRet = RegEnumKey(hKey, cStrings++, szClass, sizeof(szClass) / sizeof(TCHAR));
  839. TCHAR szFormatKey[OLEUI_CCHKEYMAX];
  840. TCHAR szFormat[OLEUI_CCHKEYMAX];
  841. TCHAR szHRClassName[OLEUI_CCHKEYMAX];
  842. BOOL fEnableConvert = FALSE;
  843. while (ERROR_SUCCESS == lRet)
  844. {
  845. if (lstrcmp(lpszCLSID, szClass) == 0)
  846. goto next; // we don't want to consider the source class
  847. // Check for a \Conversion\ReadWriteable\Main entry first - if its
  848. // readwriteable, then we don't need to bother checking to see if
  849. // its readable.
  850. StringCchCopy(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), szClass);
  851. StringCchCat(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), TEXT("\\Conversion\\Readwritable\\Main"));
  852. DWORD dw; dw = OLEUI_CCHKEYMAX_SIZE;
  853. lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
  854. if (ERROR_SUCCESS != lRet)
  855. {
  856. // Try \\DataFormats\DefaultFile too
  857. StringCchCopy(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), szClass);
  858. StringCchCat(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), TEXT("\\DataFormats\\DefaultFile"));
  859. dw = OLEUI_CCHKEYMAX_SIZE;
  860. lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
  861. }
  862. if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
  863. {
  864. // Here, we've got a list of formats that this class can read
  865. // and write. We need to see if the original class' format is
  866. // in this list. We do that by looking for wFormat in
  867. // szFormat - if it in there, then we add this class to the
  868. // both lists and continue. If not, then we look at the
  869. // class' readable formats.
  870. dw = OLEUI_CCHKEYMAX_SIZE;
  871. lRet = RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
  872. if (ERROR_SUCCESS == lRet)
  873. {
  874. fEnableConvert = TRUE;
  875. break; // STOP -- found one!
  876. }
  877. }
  878. // We either didn't find the readwritable key, or the
  879. // list of readwritable formats didn't include the
  880. // original class format. So, here we'll check to
  881. // see if its in the readable list.
  882. // We've got a special case for a linked object here.
  883. // If an object is linked, then the only class that
  884. // should appear in the convert list is the object's
  885. // class. So, here we check to see if the object is
  886. // linked. If it is, then we compare the classes. If
  887. // they aren't the same, then we just go to the next key.
  888. else if (!fIsLinkedObject || lstrcmp(lpszCLSID, szClass) == 0)
  889. {
  890. // Check for a \Conversion\Readable\Main entry
  891. StringCchCopy(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), szClass);
  892. StringCchCat(szFormatKey, sizeof(szFormatKey)/sizeof(szFormatKey[0]), TEXT("\\Conversion\\Readable\\Main"));
  893. // Check to see if this class can read the original class format.
  894. dw = OLEUI_CCHKEYMAX_SIZE;
  895. lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
  896. if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
  897. {
  898. dw = OLEUI_CCHKEYMAX_SIZE;
  899. lRet = RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
  900. if (ERROR_SUCCESS == lRet)
  901. {
  902. fEnableConvert = TRUE;
  903. break; // STOP -- found one!
  904. }
  905. }
  906. }
  907. next:
  908. // Continue with the next key.
  909. lRet = RegEnumKey(hKey, cStrings++, szClass, sizeof(szClass) / sizeof(TCHAR));
  910. }
  911. // Free the string we got from StringFromCLSID.
  912. OleStdFree(lpszCLSID);
  913. RegCloseKey(hKey);
  914. return fEnableConvert;
  915. }
  916. /*
  917. * FormatIncluded
  918. *
  919. * Purpose:
  920. * Parses the string for format from the word.
  921. *
  922. * Parameters:
  923. * szStringToSearch String to parse
  924. * wFormat format to find
  925. *
  926. * Return Value:
  927. * BOOL TRUE if format is found in string,
  928. * FALSE otherwise.
  929. */
  930. BOOL FormatIncluded(LPTSTR szStringToSearch, WORD wFormat)
  931. {
  932. TCHAR szFormat[255];
  933. if (wFormat < 0xC000)
  934. StringCchPrintf(szFormat, sizeof(szFormat)/sizeof(szFormat[0]), TEXT("%d"), wFormat);
  935. else
  936. GetClipboardFormatName(wFormat, szFormat, 255);
  937. LPTSTR lpToken = szStringToSearch;
  938. while (lpToken != NULL)
  939. {
  940. LPTSTR lpTokenNext = FindChar(lpToken, TEXT(','));
  941. if (lpTokenNext != NULL)
  942. {
  943. *lpTokenNext = 0;
  944. ++lpTokenNext;
  945. }
  946. if (0 == lstrcmpi(lpToken, szFormat))
  947. return TRUE;
  948. lpToken = lpTokenNext;
  949. }
  950. return FALSE;
  951. }
  952. /*
  953. * UpdateClassIcon
  954. *
  955. * Purpose:
  956. * Handles LBN_SELCHANGE for the Object Type listbox. On a selection
  957. * change, we extract an icon from the server handling the currently
  958. * selected object type using the utility function HIconFromClass.
  959. * Note that we depend on the behavior of FillClassList to stuff the
  960. * object class after a tab in the listbox string that we hide from
  961. * view (see WM_INITDIALOG).
  962. *
  963. * Parameters
  964. * hDlg HWND of the dialog box.
  965. * lpCV LPCONVERT pointing to the dialog structure
  966. * hList HWND of the Object Type listbox.
  967. *
  968. * Return Value:
  969. * None
  970. */
  971. static void UpdateClassIcon(HWND hDlg, LPCONVERT lpCV, HWND hList)
  972. {
  973. if (GetDlgItem(hDlg, IDC_CV_ICONDISPLAY) == NULL)
  974. return;
  975. // Get current selection in the list box
  976. int iSel= (UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
  977. if (LB_ERR == iSel)
  978. return;
  979. // Allocate a string to hold the entire listbox string
  980. DWORD cb = (DWORD)SendMessage(hList, LB_GETTEXTLEN, iSel, 0L);
  981. LPTSTR pszName = (LPTSTR)OleStdMalloc((cb+1) * sizeof(TCHAR));
  982. if (pszName == NULL)
  983. return;
  984. // Get whole string
  985. SendMessage(hList, LB_GETTEXT, iSel, (LPARAM)pszName);
  986. // Set pointer to CLSID (string)
  987. LPTSTR pszCLSID = PointerToNthField(pszName, 2, '\t');
  988. // Create the class ID with this string.
  989. CLSID clsid;
  990. HRESULT hr = CLSIDFromString(pszCLSID, &clsid);
  991. if (SUCCEEDED(hr))
  992. {
  993. // Get Icon for that CLSID
  994. HGLOBAL hMetaPict = OleGetIconOfClass(clsid, NULL, TRUE);
  995. // Replace current icon with the new one.
  996. SendDlgItemMessage(hDlg, IDC_CV_ICONDISPLAY, IBXM_IMAGESET, 1,
  997. (LPARAM)hMetaPict);
  998. }
  999. OleStdFree(pszName);
  1000. }
  1001. /*
  1002. * SetConvertResults
  1003. *
  1004. * Purpose:
  1005. * Centralizes setting of the Result display in the Convert
  1006. * dialog. Handles loading the appropriate string from the module's
  1007. * resources and setting the text, displaying the proper result picture,
  1008. * and showing the proper icon.
  1009. *
  1010. * Parameters:
  1011. * hDlg HWND of the dialog box so we can access controls.
  1012. * lpCV LPCONVERT in which we assume that the dwFlags is
  1013. * set to the appropriate radio button selection, and
  1014. * the list box has the appropriate class selected.
  1015. *
  1016. * Return Value:
  1017. * None
  1018. */
  1019. void SetConvertResults(HWND hDlg, LPCONVERT lpCV)
  1020. {
  1021. HWND hList = lpCV->hListVisible;
  1022. /*
  1023. * We need scratch memory for loading the stringtable string, loading
  1024. * the object type from the listbox, loading the source object
  1025. * type, and constructing the final string. We therefore allocate
  1026. * four buffers as large as the maximum message length (512) plus
  1027. * the object type, guaranteeing that we have enough
  1028. * in all cases.
  1029. */
  1030. UINT i = (UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
  1031. UINT cch = 512+(UINT)SendMessage(hList, LB_GETTEXTLEN, i, 0L);
  1032. HGLOBAL hMem = GlobalAlloc(GHND, (DWORD)(4*cch)*sizeof(TCHAR));
  1033. if (NULL == hMem)
  1034. return;
  1035. LPTSTR lpszOutput = (LPTSTR)GlobalLock(hMem);
  1036. LPTSTR lpszSelObj = lpszOutput + cch;
  1037. LPTSTR lpszDefObj = lpszSelObj + cch;
  1038. LPTSTR lpszString = lpszDefObj + cch;
  1039. // Get selected object and null terminate human-readable name (1st field).
  1040. SendMessage(hList, LB_GETTEXT, i, (LPARAM)lpszSelObj);
  1041. LPTSTR pszT = PointerToNthField(lpszSelObj, 2, '\t');
  1042. pszT = CharPrev(lpszSelObj, pszT);
  1043. *pszT = '\0';
  1044. // Get default object
  1045. GetDlgItemText(hDlg, IDC_CV_OBJECTTYPE, lpszDefObj, 512);
  1046. //Default is an empty string.
  1047. *lpszOutput=0;
  1048. if (lpCV->dwFlags & CF_SELECTCONVERTTO)
  1049. {
  1050. if (lpCV->lpOCV->fIsLinkedObject) // working with linked object
  1051. LoadString(_g_hOleStdResInst, IDS_CVRESULTCONVERTLINK, lpszOutput, cch);
  1052. else
  1053. {
  1054. if (0 !=lstrcmp(lpszDefObj, lpszSelObj))
  1055. {
  1056. // converting to a new class
  1057. if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTCONVERTTO, lpszString, cch))
  1058. FormatString2(lpszOutput, lpszString, lpszDefObj, lpszSelObj, cch);
  1059. }
  1060. else
  1061. {
  1062. // converting to the same class (no conversion)
  1063. if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTNOCHANGE, lpszString, cch))
  1064. StringCchPrintf(lpszOutput, cch, lpszString, lpszDefObj);
  1065. }
  1066. }
  1067. if (lpCV->dvAspect == DVASPECT_ICON) // Display as icon is checked
  1068. {
  1069. if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTDISPLAYASICON, lpszString, cch))
  1070. StringCchCat(lpszOutput, cch, lpszString);
  1071. }
  1072. }
  1073. if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
  1074. {
  1075. if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTACTIVATEAS, lpszString, cch))
  1076. FormatString2(lpszOutput, lpszString, lpszDefObj, lpszSelObj, cch);
  1077. // activating as a new class
  1078. if (0 != lstrcmp(lpszDefObj, lpszSelObj))
  1079. {
  1080. if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTACTIVATEDIFF, lpszString, cch))
  1081. StringCchCat(lpszOutput, cch, lpszString);
  1082. }
  1083. else // activating as itself.
  1084. {
  1085. StringCchCat(lpszOutput, cch, TEXT("."));
  1086. }
  1087. }
  1088. // If LoadString failed, we simply clear out the results (*lpszOutput=0 above)
  1089. SetDlgItemText(hDlg, IDC_CV_RESULTTEXT, lpszOutput);
  1090. GlobalUnlock(hMem);
  1091. GlobalFree(hMem);
  1092. }
  1093. /*
  1094. * ConvertCleanup
  1095. *
  1096. * Purpose:
  1097. * Performs convert-specific cleanup before Convert termination.
  1098. *
  1099. * Parameters:
  1100. * hDlg HWND of the dialog box so we can access controls.
  1101. *
  1102. * Return Value:
  1103. * None
  1104. */
  1105. void ConvertCleanup(HWND hDlg, LPCONVERT lpCV)
  1106. {
  1107. // Free our strings. Zero out the user type name string
  1108. // the the calling app doesn't free to it.
  1109. OleStdFree((LPVOID)lpCV->lpszConvertDefault);
  1110. OleStdFree((LPVOID)lpCV->lpszActivateDefault);
  1111. OleStdFree((LPVOID)lpCV->lpszIconSource);
  1112. if (lpCV->lpOCV->lpszUserType)
  1113. {
  1114. OleStdFree((LPVOID)lpCV->lpOCV->lpszUserType);
  1115. lpCV->lpOCV->lpszUserType = NULL;
  1116. }
  1117. if (lpCV->lpOCV->lpszDefLabel)
  1118. {
  1119. OleStdFree((LPVOID)lpCV->lpOCV->lpszDefLabel);
  1120. lpCV->lpOCV->lpszDefLabel = NULL;
  1121. }
  1122. }
  1123. /*
  1124. * SwapWindows
  1125. *
  1126. * Purpose:
  1127. * Moves hWnd1 to hWnd2's position and hWnd2 to hWnd1's position.
  1128. * Does NOT change sizes.
  1129. *
  1130. * Parameters:
  1131. * hDlg HWND of the dialog box so we can turn redraw off
  1132. *
  1133. * Return Value:
  1134. * None
  1135. */
  1136. void SwapWindows(HWND hDlg, HWND hWnd1, HWND hWnd2)
  1137. {
  1138. if (hWnd1 != NULL && hWnd2 != NULL)
  1139. {
  1140. RECT rect1; GetWindowRect(hWnd1, &rect1);
  1141. MapWindowPoints(NULL, hDlg, (LPPOINT)&rect1, 2);
  1142. RECT rect2; GetWindowRect(hWnd2, &rect2);
  1143. MapWindowPoints(NULL, hDlg, (LPPOINT)&rect2, 2);
  1144. SetWindowPos(hWnd1, NULL,
  1145. rect2.left, rect2.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
  1146. SetWindowPos(hWnd2, NULL,
  1147. rect1.left, rect1.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
  1148. }
  1149. }