Source code of Windows XP (NT5)
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.

1392 lines
55 KiB

  1. /*
  2. * OBJPROP.CPP
  3. *
  4. * Implements the OleUIObjectProperties function which invokes the complete
  5. * Object Properties dialog.
  6. *
  7. * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  8. */
  9. #include "precomp.h"
  10. #include "common.h"
  11. #include "utility.h"
  12. #include "iconbox.h"
  13. #include "resimage.h"
  14. #include <stddef.h>
  15. OLEDBGDATA
  16. // Internally used structure
  17. typedef struct tagGNRLPROPS
  18. {
  19. // Keep this item first as the Standard* functions depend on it here.
  20. LPOLEUIGNRLPROPS lpOGP; // Original structure passed.
  21. UINT nIDD; // IDD of dialog (used for help info)
  22. CLSID clsidNew; // new class ID (if conversion done)
  23. } GNRLPROPS, *PGNRLPROPS, FAR* LPGNRLPROPS;
  24. typedef struct tagVIEWPROPS
  25. {
  26. // Keep this item first as the Standard* functions depend on it here.
  27. LPOLEUIVIEWPROPS lpOVP; // Original structure passed.
  28. UINT nIDD; // IDD of dialog (used for help info)
  29. BOOL bIconChanged;
  30. int nCurrentScale;
  31. BOOL bRelativeToOrig;
  32. DWORD dvAspect;
  33. } VIEWPROPS, *PVIEWPROPS, FAR* LPVIEWPROPS;
  34. typedef struct tagLINKPROPS
  35. {
  36. // Keep this item first as the Standard* functions depend on it here.
  37. LPOLEUILINKPROPS lpOLP; // Original structure passed.
  38. UINT nIDD; // IDD of dialog (used for help info)
  39. DWORD dwUpdate; // original update mode
  40. LPTSTR lpszDisplayName;// new link source
  41. ULONG nFileLength; // file name part of source
  42. } LINKPROPS, *PLINKPROPS, FAR* LPLINKPROPS;
  43. // Internal function prototypes
  44. // OBJPROP.CPP
  45. /*
  46. * OleUIObjectProperties
  47. *
  48. * Purpose:
  49. * Invokes the standard OLE Object Properties dialog box allowing the user
  50. * to change General, View, and Link properties of an OLE object. This
  51. * dialog uses the new Windows 95 tabbed dialogs.
  52. *
  53. * Parameters:
  54. * lpOP LPOLEUIObjectProperties pointing to the in-out structure
  55. * for this dialog.
  56. *
  57. * Return Value:
  58. * UINT One of the following codes, indicating success or error:
  59. * OLEUI_SUCCESS Success
  60. * OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
  61. *
  62. */
  63. static UINT WINAPI ValidateObjectProperties(LPOLEUIOBJECTPROPS);
  64. static UINT WINAPI PrepareObjectProperties(LPOLEUIOBJECTPROPS);
  65. STDAPI_(UINT) OleUIObjectProperties(LPOLEUIOBJECTPROPS lpOP)
  66. {
  67. #ifdef UNICODE
  68. return (InternalObjectProperties(lpOP, TRUE));
  69. #else
  70. return (InternalObjectProperties(lpOP, FALSE));
  71. #endif
  72. }
  73. UINT InternalObjectProperties(LPOLEUIOBJECTPROPS lpOP, BOOL fWide)
  74. {
  75. // Validate Parameters
  76. UINT uRet = ValidateObjectProperties(lpOP);
  77. if (OLEUI_SUCCESS != uRet)
  78. return uRet;
  79. if (NULL == lpOP->lpObjInfo)
  80. {
  81. return(OLEUI_OPERR_OBJINFOINVALID);
  82. }
  83. if (IsBadReadPtr(lpOP->lpObjInfo, sizeof(IOleUIObjInfo)))
  84. {
  85. return(OLEUI_OPERR_OBJINFOINVALID);
  86. }
  87. if (lpOP->dwFlags & OPF_OBJECTISLINK)
  88. {
  89. if (NULL == lpOP->lpLinkInfo)
  90. {
  91. return(OLEUI_OPERR_LINKINFOINVALID);
  92. }
  93. if (IsBadReadPtr(lpOP->lpLinkInfo, sizeof(IOleUILinkInfo)))
  94. {
  95. return(OLEUI_OPERR_LINKINFOINVALID);
  96. }
  97. }
  98. // Fill Missing values in lpPS
  99. LPPROPSHEETHEADER lpPS = (LPPROPSHEETHEADER)lpOP->lpPS;
  100. LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lpPS->ppsp;
  101. uRet = PrepareObjectProperties(lpOP);
  102. if (OLEUI_SUCCESS != uRet)
  103. return uRet;
  104. LPTSTR lpszShortType = NULL;
  105. lpOP->lpObjInfo->GetObjectInfo(lpOP->dwObject, NULL, NULL,
  106. NULL, &lpszShortType, NULL);
  107. if (lpszShortType == NULL)
  108. return OLEUI_ERR_OLEMEMALLOC;
  109. TCHAR szCaption[256];
  110. if (lpPS->pszCaption == NULL)
  111. {
  112. TCHAR szTemp[256];
  113. LoadString(_g_hOleStdResInst,
  114. (lpOP->dwFlags & OPF_OBJECTISLINK) ?
  115. IDS_LINKOBJECTPROPERTIES : IDS_OBJECTPROPERTIES,
  116. szTemp, sizeof(szTemp) / sizeof(TCHAR));
  117. wsprintf(szCaption, szTemp, lpszShortType);
  118. #ifdef UNICODE
  119. if (!fWide)
  120. {
  121. // We're going to actually call the ANSI version of PropertySheet,
  122. // so we need to store the caption as an ANSI string.
  123. lstrcpy(szTemp, szCaption);
  124. WTOA((char *)szCaption, szTemp, 256);
  125. }
  126. #endif
  127. lpPS->pszCaption = szCaption;
  128. }
  129. OleStdFree(lpszShortType);
  130. // Invoke the property sheet
  131. int nResult = StandardPropertySheet(lpOP->lpPS, fWide);
  132. // Cleanup any temporary memory allocated during the process
  133. if (lpPP == NULL)
  134. {
  135. OleStdFree((LPVOID)lpOP->lpPS->ppsp);
  136. lpOP->lpPS->ppsp = NULL;
  137. }
  138. // map PropertPage return value to OLEUI_ return code
  139. if (nResult < 0)
  140. uRet = OLEUI_OPERR_PROPERTYSHEET;
  141. else if (nResult == 0)
  142. uRet = OLEUI_CANCEL;
  143. else
  144. uRet = OLEUI_OK;
  145. return uRet;
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // Validation code
  149. static UINT WINAPI ValidateGnrlProps(LPOLEUIGNRLPROPS lpGP)
  150. {
  151. OleDbgAssert(lpGP != NULL);
  152. if (lpGP->cbStruct != sizeof(OLEUIGNRLPROPS))
  153. return OLEUI_ERR_CBSTRUCTINCORRECT;
  154. if (lpGP->lpfnHook && IsBadCodePtr((FARPROC)lpGP->lpfnHook))
  155. return OLEUI_ERR_LPFNHOOKINVALID;
  156. return OLEUI_SUCCESS;
  157. }
  158. static UINT WINAPI ValidateViewProps(LPOLEUIVIEWPROPS lpVP)
  159. {
  160. OleDbgAssert(lpVP != NULL);
  161. if (lpVP->cbStruct != sizeof(OLEUIVIEWPROPS))
  162. return OLEUI_ERR_CBSTRUCTINCORRECT;
  163. if (lpVP->lpfnHook && IsBadCodePtr((FARPROC)lpVP->lpfnHook))
  164. return OLEUI_ERR_LPFNHOOKINVALID;
  165. return OLEUI_SUCCESS;
  166. }
  167. static UINT WINAPI ValidateLinkProps(LPOLEUILINKPROPS lpLP)
  168. {
  169. OleDbgAssert(lpLP != NULL);
  170. if (lpLP->cbStruct != sizeof(OLEUILINKPROPS))
  171. return OLEUI_ERR_CBSTRUCTINCORRECT;
  172. if (lpLP->lpfnHook && IsBadCodePtr((FARPROC)lpLP->lpfnHook))
  173. return OLEUI_ERR_LPFNHOOKINVALID;
  174. return OLEUI_SUCCESS;
  175. }
  176. static UINT WINAPI ValidateObjectProperties(LPOLEUIOBJECTPROPS lpOP)
  177. {
  178. // Validate LPOLEUIOBJECTPROPS lpOP
  179. if (lpOP == NULL)
  180. return OLEUI_ERR_STRUCTURENULL;
  181. if (IsBadWritePtr(lpOP, sizeof(OLEUIOBJECTPROPS)))
  182. return OLEUI_ERR_STRUCTUREINVALID;
  183. // Validate cbStruct field of OLEUIOBJECTPROPS
  184. if (lpOP->cbStruct != sizeof(OLEUIOBJECTPROPS))
  185. return OLEUI_ERR_CBSTRUCTINCORRECT;
  186. // Validate "sub" property pointers
  187. if (lpOP->lpGP == NULL || lpOP->lpVP == NULL ||
  188. ((lpOP->dwFlags & OPF_OBJECTISLINK) && lpOP->lpLP == NULL))
  189. return OLEUI_OPERR_SUBPROPNULL;
  190. if (IsBadWritePtr(lpOP->lpGP, sizeof(OLEUIGNRLPROPS)) ||
  191. IsBadWritePtr(lpOP->lpVP, sizeof(OLEUIVIEWPROPS)) ||
  192. ((lpOP->dwFlags & OPF_OBJECTISLINK) &&
  193. IsBadWritePtr(lpOP->lpLP, sizeof(OLEUILINKPROPS))))
  194. return OLEUI_OPERR_SUBPROPINVALID;
  195. // Validate property sheet data pointers
  196. LPPROPSHEETHEADER lpPS = lpOP->lpPS;
  197. if (lpPS == NULL)
  198. return OLEUI_OPERR_PROPSHEETNULL;
  199. // Size of PROPSHEEDHEADER has changed, meaning that if we check for
  200. // the size of PROPSHEETHEADER as we used to, we will break older code.
  201. if ( IsBadWritePtr(lpPS, sizeof(DWORD)) )
  202. return OLEUI_OPERR_PROPSHEETINVALID;
  203. if (IsBadWritePtr(lpPS, lpPS->dwSize))
  204. return OLEUI_OPERR_PROPSHEETINVALID;
  205. // DWORD dwSize = lpPS->dwSize;
  206. // if (dwSize < sizeof(PROPSHEETHEADER))
  207. // return OLEUI_ERR_CBSTRUCTINCORRECT;
  208. // If links specified, validate "sub" link property pointer
  209. if (lpOP->dwFlags & OPF_OBJECTISLINK)
  210. {
  211. if (lpPS->ppsp != NULL && lpPS->nPages < 3)
  212. return OLEUI_OPERR_PAGESINCORRECT;
  213. }
  214. else
  215. {
  216. if (lpPS->ppsp != NULL && lpPS->nPages < 2)
  217. return OLEUI_OPERR_PAGESINCORRECT;
  218. }
  219. // Size of PROPSHEETPAGE has changed, meaning that if we check for
  220. // the size of the new PROPSHEETPAGE we will break old code.
  221. // if (lpPS->ppsp != NULL &&
  222. // IsBadWritePtr((PROPSHEETPAGE*)lpPS->ppsp,
  223. // lpPS->nPages * sizeof(PROPSHEETPAGE)))
  224. // {
  225. // return OLEUI_OPERR_INVALIDPAGES;
  226. // }
  227. // not setting PSH_PROPSHEETPAGE is not supported
  228. if (lpOP->dwFlags & OPF_NOFILLDEFAULT)
  229. {
  230. if (!(lpPS->dwFlags & PSH_PROPSHEETPAGE))
  231. return OLEUI_OPERR_NOTSUPPORTED;
  232. }
  233. else if (lpPS->dwFlags != 0)
  234. {
  235. return OLEUI_OPERR_NOTSUPPORTED;
  236. }
  237. // Sanity check any pages provided
  238. LPCPROPSHEETPAGE lpPP = lpPS->ppsp;
  239. for (UINT nPage = 0; nPage < lpPS->nPages; nPage++)
  240. {
  241. // Size of PROPSHEETPAGE has changed, meaning that if we check for
  242. // the size of the new PROPSHEETPAGE we will break old code.
  243. // if (lpPP->dwSize != sizeof(PROPSHEETPAGE))
  244. // return OLEUI_ERR_CBSTRUCTINCORRECT;
  245. if (lpPP->pfnDlgProc != NULL)
  246. return OLEUI_OPERR_DLGPROCNOTNULL;
  247. if (lpPP->lParam != 0)
  248. return OLEUI_OPERR_LPARAMNOTZERO;
  249. lpPP = (LPCPROPSHEETPAGE)((LPBYTE)lpPP+lpPP->dwSize);
  250. }
  251. // validate individual prop page structures
  252. UINT uRet = ValidateGnrlProps(lpOP->lpGP);
  253. if (uRet != OLEUI_SUCCESS)
  254. return uRet;
  255. uRet = ValidateViewProps(lpOP->lpVP);
  256. if (uRet != OLEUI_SUCCESS)
  257. return uRet;
  258. if ((lpOP->dwFlags & OPF_OBJECTISLINK) && lpOP->lpLP != NULL)
  259. {
  260. uRet = ValidateLinkProps(lpOP->lpLP);
  261. if (uRet != OLEUI_SUCCESS)
  262. return uRet;
  263. }
  264. return OLEUI_SUCCESS;
  265. }
  266. /////////////////////////////////////////////////////////////////////////////
  267. // GnrlPropsDialogProc and helpers
  268. // takes a DWORD add commas etc to it and puts the result in the buffer
  269. LPTSTR AddCommas(DWORD dw, LPTSTR pszResult, UINT nMax)
  270. {
  271. NUMBERFMT numberFmt;
  272. numberFmt.NumDigits = 0;
  273. numberFmt.LeadingZero = 0;
  274. TCHAR szSep[5];
  275. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szSep, sizeof(szSep) / sizeof(TCHAR));
  276. numberFmt.Grouping = Atol(szSep);
  277. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, sizeof(szSep) / sizeof(TCHAR));
  278. numberFmt.lpDecimalSep = numberFmt.lpThousandSep = szSep;
  279. numberFmt.NegativeOrder= 0;
  280. TCHAR szTemp[64];
  281. wsprintf(szTemp, TEXT("%lu"), dw);
  282. GetNumberFormat(LOCALE_USER_DEFAULT, 0, szTemp, &numberFmt, pszResult, nMax);
  283. return pszResult;
  284. }
  285. const short pwOrders[] = {IDS_BYTES, IDS_ORDERKB, IDS_ORDERMB, IDS_ORDERGB, IDS_ORDERTB};
  286. /* converts numbers into short formats
  287. * 532 -> 523 bytes
  288. * 1340 -> 1.3KB
  289. * 23506 -> 23.5KB
  290. * -> 2.4MB
  291. * -> 5.2GB
  292. */
  293. LPTSTR ShortSizeFormat64(__int64 dw64, LPTSTR szBuf)
  294. {
  295. int i;
  296. UINT wInt, wLen, wDec;
  297. TCHAR szTemp[10], szOrder[20], szFormat[5];
  298. if (dw64 < 1000)
  299. {
  300. wsprintf(szTemp, TEXT("%d"), DWORD(dw64));
  301. i = 0;
  302. }
  303. else
  304. {
  305. for (i = 1; i < (sizeof(pwOrders) - 1)
  306. && dw64 >= 1000L * 1024L; dw64 >>= 10, i++)
  307. ; /* do nothing */
  308. wInt = DWORD(dw64 >> 10);
  309. AddCommas(wInt, szTemp, sizeof(szTemp)/sizeof(TCHAR));
  310. wLen = lstrlen(szTemp);
  311. if (wLen < 3)
  312. {
  313. wDec = DWORD(dw64 - (__int64)wInt * 1024L) * 1000 / 1024;
  314. // At this point, wDec should be between 0 and 1000
  315. // we want get the top one (or two) digits.
  316. wDec /= 10;
  317. if (wLen == 2)
  318. wDec /= 10;
  319. // Note that we need to set the format before getting the
  320. // intl char.
  321. lstrcpy(szFormat, TEXT("%02d"));
  322. szFormat[2] = '0' + 3 - wLen;
  323. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
  324. szTemp+wLen, sizeof(szTemp)-wLen);
  325. wLen = lstrlen(szTemp);
  326. wLen += wsprintf(szTemp+wLen, szFormat, wDec);
  327. }
  328. }
  329. LoadString(_g_hOleStdResInst, pwOrders[i], szOrder,
  330. sizeof(szOrder)/sizeof(szOrder[0]));
  331. wsprintf(szBuf, szOrder, (LPSTR)szTemp);
  332. return szBuf;
  333. }
  334. LPTSTR WINAPI ShortSizeFormat(DWORD dw, LPTSTR szBuf)
  335. {
  336. return ShortSizeFormat64((__int64)dw, szBuf);
  337. }
  338. BOOL FGnrlPropsRefresh(HWND hDlg, LPGNRLPROPS lpGP)
  339. {
  340. // get object information and fill in default fields
  341. LPOLEUIOBJECTPROPS lpOP = lpGP->lpOGP->lpOP;
  342. LPOLEUIOBJINFO lpObjInfo = lpOP->lpObjInfo;
  343. // get object's icon
  344. HGLOBAL hMetaPict;
  345. lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict, NULL, NULL);
  346. if (hMetaPict != NULL)
  347. {
  348. HICON hIcon = OleUIMetafilePictExtractIcon(hMetaPict);
  349. SendDlgItemMessage(hDlg, IDC_GP_OBJECTICON, STM_SETICON,
  350. (WPARAM)hIcon, 0);
  351. }
  352. OleUIMetafilePictIconFree(hMetaPict);
  353. // get type, short type, location, and size of object
  354. DWORD dwObjSize;
  355. LPTSTR lpszLabel = NULL;
  356. LPTSTR lpszType = NULL;
  357. LPTSTR lpszShortType = NULL;
  358. LPTSTR lpszLocation = NULL;
  359. lpObjInfo->GetObjectInfo(lpOP->dwObject, &dwObjSize, &lpszLabel,
  360. &lpszType, &lpszShortType, &lpszLocation);
  361. // set name, type, and size of object
  362. SetDlgItemText(hDlg, IDC_GP_OBJECTNAME, lpszLabel);
  363. SetDlgItemText(hDlg, IDC_GP_OBJECTTYPE, lpszType);
  364. SetDlgItemText(hDlg, IDC_GP_OBJECTLOCATION, lpszLocation);
  365. TCHAR szTemp[128];
  366. if (dwObjSize == (DWORD)-1)
  367. {
  368. LoadString(_g_hOleStdResInst, IDS_OLE2UIUNKNOWN, szTemp, 64);
  369. SetDlgItemText(hDlg, IDC_GP_OBJECTSIZE, szTemp);
  370. }
  371. else
  372. {
  373. // get the master formatting string
  374. TCHAR szFormat[64];
  375. LoadString(_g_hOleStdResInst, IDS_OBJECTSIZE, szFormat, 64);
  376. // format the size in two ways (short, and with commas)
  377. TCHAR szNum1[20], szNum2[32];
  378. ShortSizeFormat(dwObjSize, szNum1);
  379. AddCommas(dwObjSize, szNum2, 32);
  380. FormatString2(szTemp, szFormat, szNum1, szNum2);
  381. // set the control's text
  382. SetDlgItemText(hDlg, IDC_GP_OBJECTSIZE, szTemp);
  383. }
  384. // enable/disable convert button as necessary
  385. BOOL bEnable = TRUE;
  386. if (lpOP->dwFlags & (OPF_OBJECTISLINK|OPF_DISABLECONVERT))
  387. bEnable = FALSE;
  388. else
  389. {
  390. CLSID clsid; WORD wFormat;
  391. lpObjInfo->GetConvertInfo(lpOP->dwObject, &clsid, &wFormat, NULL, NULL, NULL);
  392. bEnable = OleUICanConvertOrActivateAs(clsid, FALSE, wFormat);
  393. }
  394. StandardEnableDlgItem(hDlg, IDC_GP_CONVERT, bEnable);
  395. // cleanup temporary info strings
  396. OleStdFree(lpszLabel);
  397. OleStdFree(lpszType);
  398. OleStdFree(lpszShortType);
  399. OleStdFree(lpszLocation);
  400. return TRUE;
  401. }
  402. BOOL FGnrlPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  403. {
  404. // Copy the structure at lParam into our instance memory.
  405. HFONT hFont;
  406. LPGNRLPROPS lpGP = (LPGNRLPROPS)LpvStandardInit(hDlg, sizeof(GNRLPROPS), &hFont);
  407. // LpvStandardInit send a termination to us already.
  408. if (NULL == lpGP)
  409. return FALSE;
  410. LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
  411. LPOLEUIGNRLPROPS lpOGP = (LPOLEUIGNRLPROPS)lpPP->lParam;
  412. lpGP->lpOGP = lpOGP;
  413. lpGP->nIDD = IDD_GNRLPROPS;
  414. // If we got a font, send it to the necessary controls.
  415. if (NULL != hFont)
  416. {
  417. SendDlgItemMessage(hDlg, IDC_GP_OBJECTNAME, WM_SETFONT, (WPARAM)hFont, 0L);
  418. SendDlgItemMessage(hDlg, IDC_GP_OBJECTTYPE, WM_SETFONT, (WPARAM)hFont, 0L);
  419. SendDlgItemMessage(hDlg, IDC_GP_OBJECTLOCATION, WM_SETFONT, (WPARAM)hFont, 0L);
  420. SendDlgItemMessage(hDlg, IDC_GP_OBJECTSIZE, WM_SETFONT, (WPARAM)hFont, 0L);
  421. }
  422. // Show or hide the help button
  423. if (!(lpOGP->lpOP->dwFlags & OPF_SHOWHELP))
  424. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  425. // Initialize the controls
  426. FGnrlPropsRefresh(hDlg, lpGP);
  427. // Call the hook with lCustData in lParam
  428. UStandardHook((PVOID)lpGP, hDlg, WM_INITDIALOG, wParam, lpOGP->lCustData);
  429. return TRUE;
  430. }
  431. INT_PTR CALLBACK GnrlPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  432. {
  433. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  434. COMMANDPARAMS(wID, wCode, hWndMsg);
  435. // This will fail under WM_INITDIALOG, where we allocate it.
  436. UINT uHook = 0;
  437. LPGNRLPROPS lpGP = (LPGNRLPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
  438. // If the hook processed the message, we're done.
  439. if (0 != uHook)
  440. return (INT_PTR)uHook;
  441. // Get pointers to important info
  442. LPOLEUIGNRLPROPS lpOGP = NULL;
  443. LPOLEUIOBJECTPROPS lpOP = NULL;
  444. LPOLEUIOBJINFO lpObjInfo = NULL;
  445. if (lpGP != NULL)
  446. {
  447. lpOGP = lpGP->lpOGP;
  448. if (lpOGP != NULL)
  449. {
  450. lpObjInfo = lpOGP->lpOP->lpObjInfo;
  451. lpOP = lpOGP->lpOP;
  452. }
  453. }
  454. switch (iMsg)
  455. {
  456. case WM_INITDIALOG:
  457. FGnrlPropsInit(hDlg, wParam, lParam);
  458. return TRUE;
  459. case WM_COMMAND:
  460. switch (wID)
  461. {
  462. case IDC_GP_CONVERT:
  463. {
  464. if(!lpGP)
  465. return TRUE;
  466. // Call up convert dialog to obtain new CLSID
  467. OLEUICONVERT cv; memset(&cv, 0, sizeof(cv));
  468. cv.cbStruct = sizeof(cv);
  469. cv.dwFlags |= CF_CONVERTONLY;
  470. if (lpOP->dwFlags & OPF_SHOWHELP)
  471. cv.dwFlags |= CF_SHOWHELPBUTTON;
  472. cv.clsidConvertDefault = lpGP->clsidNew;
  473. cv.dvAspect = DVASPECT_CONTENT;
  474. lpObjInfo->GetObjectInfo(lpOP->dwObject,
  475. NULL, NULL, &cv.lpszUserType, NULL, NULL);
  476. lpObjInfo->GetConvertInfo(lpOP->dwObject,
  477. &cv.clsid, &cv.wFormat, &cv.clsidConvertDefault,
  478. &cv.lpClsidExclude, &cv.cClsidExclude);
  479. cv.fIsLinkedObject =
  480. (lpOGP->lpOP->dwFlags & OPF_OBJECTISLINK);
  481. if (cv.clsidConvertDefault != CLSID_NULL)
  482. cv.dwFlags |= CF_SETCONVERTDEFAULT;
  483. cv.hWndOwner = GetParent(GetParent(hDlg));
  484. // allow caller to hook the convert structure
  485. uHook = UStandardHook(lpGP, hDlg, uMsgConvert, 0, (LPARAM)&cv);
  486. if (0 == uHook)
  487. {
  488. uHook = (OLEUI_OK == OleUIConvert(&cv));
  489. SetFocus(hDlg);
  490. }
  491. // check to see dialog results
  492. if (uHook != 0 && (cv.dwFlags & CF_SELECTCONVERTTO))
  493. {
  494. lpGP->clsidNew = cv.clsidNew;
  495. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  496. }
  497. }
  498. return TRUE;
  499. case IDC_OLEUIHELP:
  500. PostMessage(GetParent(GetParent(hDlg)),
  501. uMsgHelp,
  502. (WPARAM)hDlg,
  503. MAKELPARAM(IDD_GNRLPROPS, 0));
  504. return TRUE;
  505. }
  506. break;
  507. case PSM_QUERYSIBLINGS:
  508. if(!lpGP)
  509. break;
  510. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  511. switch (wParam)
  512. {
  513. case OLEUI_QUERY_GETCLASSID:
  514. *(CLSID*)lParam = lpGP->clsidNew;
  515. SetWindowLong(hDlg, DWLP_MSGRESULT, 1);
  516. return TRUE;
  517. case OLEUI_QUERY_LINKBROKEN:
  518. FGnrlPropsRefresh(hDlg, lpGP);
  519. return TRUE;
  520. }
  521. break;
  522. case WM_NOTIFY:
  523. switch (((NMHDR*)lParam)->code)
  524. {
  525. case PSN_HELP:
  526. PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
  527. (WPARAM)hDlg, MAKELPARAM(IDD_GNRLPROPS, 0));
  528. break;
  529. case PSN_APPLY:
  530. if(!lpGP)
  531. return TRUE;
  532. // apply changes if changes made
  533. if (lpGP->clsidNew != CLSID_NULL)
  534. {
  535. // convert the object -- fail the apply if convert fails
  536. if (NOERROR != lpObjInfo->ConvertObject(lpOP->dwObject,
  537. lpGP->clsidNew))
  538. {
  539. SetWindowLong(hDlg, DWLP_MSGRESULT, 1);
  540. return TRUE;
  541. }
  542. lpGP->clsidNew = CLSID_NULL;
  543. }
  544. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  545. PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  546. return TRUE;
  547. }
  548. break;
  549. case WM_DESTROY:
  550. {
  551. HICON hIcon = (HICON)SendDlgItemMessage(hDlg, IDC_GP_OBJECTICON,
  552. STM_GETICON, 0, 0);
  553. if (hIcon != NULL)
  554. DestroyIcon(hIcon);
  555. StandardCleanup((PVOID)lpGP, hDlg);
  556. }
  557. return TRUE;
  558. }
  559. return FALSE;
  560. }
  561. /////////////////////////////////////////////////////////////////////////////
  562. // ViewPropsDialogProc and helpers
  563. void EnableDisableScaleControls(LPVIEWPROPS lpVP, HWND hDlg)
  564. {
  565. LPOLEUIVIEWPROPS lpOVP = lpVP->lpOVP;
  566. BOOL bEnable = !(lpOVP->dwFlags & VPF_DISABLESCALE) &&
  567. SendDlgItemMessage(hDlg, IDC_VP_ASICON, BM_GETCHECK, 0, 0) == 0;
  568. StandardEnableDlgItem(hDlg, IDC_VP_SPIN, bEnable);
  569. StandardEnableDlgItem(hDlg, IDC_VP_PERCENT, bEnable);
  570. StandardEnableDlgItem(hDlg, IDC_VP_SCALETXT, bEnable);
  571. bEnable = bEnable && !(lpOVP->dwFlags & VPF_DISABLERELATIVE);
  572. StandardEnableDlgItem(hDlg, IDC_VP_RELATIVE, bEnable);
  573. }
  574. BOOL FViewPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  575. {
  576. // Copy the structure at lParam into our instance memory.
  577. LPVIEWPROPS lpVP = (LPVIEWPROPS)LpvStandardInit(hDlg, sizeof(VIEWPROPS));
  578. // LpvStandardInit send a termination to us already.
  579. if (NULL == lpVP)
  580. return FALSE;
  581. LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
  582. LPOLEUIVIEWPROPS lpOVP = (LPOLEUIVIEWPROPS)lpPP->lParam;
  583. lpVP->lpOVP = lpOVP;
  584. lpVP->nIDD = IDD_VIEWPROPS;
  585. // get object information and fill in default fields
  586. LPOLEUIOBJECTPROPS lpOP = lpOVP->lpOP;
  587. LPOLEUIOBJINFO lpObjInfo = lpOP->lpObjInfo;
  588. // initialize icon and scale variables
  589. HGLOBAL hMetaPict;
  590. DWORD dvAspect;
  591. int nCurrentScale;
  592. lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict,
  593. &dvAspect, &nCurrentScale);
  594. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET,
  595. 0, (LPARAM)hMetaPict);
  596. lpVP->nCurrentScale = nCurrentScale;
  597. lpVP->dvAspect = dvAspect;
  598. // Initialize the result image
  599. SendDlgItemMessage(hDlg, IDC_VP_RESULTIMAGE,
  600. RIM_IMAGESET, RESULTIMAGE_EDITABLE, 0L);
  601. // Initialize controls
  602. CheckRadioButton(hDlg, IDC_VP_EDITABLE, IDC_VP_ASICON,
  603. dvAspect == DVASPECT_CONTENT ? IDC_VP_EDITABLE : IDC_VP_ASICON);
  604. SendDlgItemMessage(hDlg, IDC_VP_RELATIVE, BM_SETCHECK,
  605. (lpOVP->dwFlags & VPF_SELECTRELATIVE) != 0, 0L);
  606. if (!(lpOVP->dwFlags & VPF_DISABLESCALE))
  607. SetDlgItemInt(hDlg, IDC_VP_PERCENT, nCurrentScale, FALSE);
  608. lpVP->bRelativeToOrig = SendDlgItemMessage(hDlg, IDC_VP_RELATIVE,
  609. BM_GETCHECK, 0, 0) != 0;
  610. // Setup up-down control as buddy to IDC_VP_PERCENT
  611. HWND hWndSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL,
  612. WS_CHILD|UDS_SETBUDDYINT|UDS_ARROWKEYS|UDS_ALIGNRIGHT, 0, 0, 0, 0,
  613. hDlg, (HMENU)IDC_VP_SPIN, _g_hOleStdInst, NULL);
  614. if (hWndSpin != NULL)
  615. {
  616. SendMessage(hWndSpin, UDM_SETRANGE, 0,
  617. MAKELPARAM(lpOVP->nScaleMax, lpOVP->nScaleMin));
  618. SendMessage(hWndSpin, UDM_SETPOS, 0, nCurrentScale);
  619. SendMessage(hWndSpin, UDM_SETBUDDY,
  620. (WPARAM)GetDlgItem(hDlg, IDC_VP_PERCENT), 0);
  621. ShowWindow(hWndSpin, SW_SHOW);
  622. }
  623. EnableDisableScaleControls(lpVP, hDlg);
  624. if (!(lpOP->dwFlags & OPF_SHOWHELP))
  625. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  626. // Call the hook with lCustData in lParam
  627. UStandardHook((PVOID)lpVP, hDlg, WM_INITDIALOG, wParam, lpOVP->lCustData);
  628. return TRUE;
  629. }
  630. INT_PTR CALLBACK ViewPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  631. {
  632. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  633. COMMANDPARAMS(wID, wCode, hWndMsg);
  634. // This will fail under WM_INITDIALOG, where we allocate it.
  635. UINT uHook = 0;
  636. LPVIEWPROPS lpVP = (LPVIEWPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
  637. // If the hook processed the message, we're done.
  638. if (0 != uHook)
  639. return (INT_PTR)uHook;
  640. // Get pointers to important info
  641. LPOLEUIVIEWPROPS lpOVP = NULL;
  642. LPOLEUIOBJECTPROPS lpOP = NULL;
  643. LPOLEUIOBJINFO lpObjInfo = NULL;
  644. if (lpVP != NULL)
  645. {
  646. lpOVP = lpVP->lpOVP;
  647. if (lpOVP != NULL)
  648. {
  649. lpObjInfo = lpOVP->lpOP->lpObjInfo;
  650. lpOP = lpOVP->lpOP;
  651. }
  652. }
  653. switch (iMsg)
  654. {
  655. case WM_INITDIALOG:
  656. FViewPropsInit(hDlg, wParam, lParam);
  657. return TRUE;
  658. case WM_COMMAND:
  659. switch (wID)
  660. {
  661. case IDC_VP_ASICON:
  662. case IDC_VP_EDITABLE:
  663. EnableDisableScaleControls(lpVP, hDlg);
  664. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  665. return TRUE;
  666. case IDC_VP_CHANGEICON:
  667. {
  668. // Call up Change Icon dialog to obtain new icon
  669. OLEUICHANGEICON ci; memset(&ci, 0, sizeof(ci));
  670. ci.cbStruct = sizeof(ci);
  671. ci.dwFlags = CIF_SELECTCURRENT;
  672. ci.hWndOwner = GetParent(GetParent(hDlg));
  673. ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY,
  674. IBXM_IMAGEGET, 0, 0L);
  675. // get classid to look for (may be new class if conversion applied)
  676. SendMessage(GetParent(hDlg), PSM_QUERYSIBLINGS,
  677. OLEUI_QUERY_GETCLASSID, (LPARAM)&ci.clsid);
  678. lpObjInfo->GetConvertInfo(lpOP->dwObject,
  679. &ci.clsid, NULL, NULL, NULL, NULL);
  680. if (lpOP->dwFlags & OPF_SHOWHELP)
  681. ci.dwFlags |= CIF_SHOWHELP;
  682. // allow the caller to hook the change icon
  683. uHook = UStandardHook(lpVP, hDlg, uMsgChangeIcon, 0, (LPARAM)&ci);
  684. if (0 == uHook)
  685. {
  686. uHook = (OLEUI_OK == OleUIChangeIcon(&ci));
  687. SetFocus(hDlg);
  688. }
  689. if (0 != uHook)
  690. {
  691. // apply the changes
  692. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET, 1,
  693. (LPARAM)ci.hMetaPict);
  694. lpVP->bIconChanged = TRUE;
  695. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  696. }
  697. }
  698. return TRUE;
  699. case IDC_VP_PERCENT:
  700. case IDC_VP_RELATIVE:
  701. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  702. return TRUE;
  703. case IDC_OLEUIHELP:
  704. PostMessage(GetParent(GetParent(hDlg)),
  705. uMsgHelp,
  706. (WPARAM)hDlg,
  707. MAKELPARAM(IDD_VIEWPROPS, 0));
  708. return TRUE;
  709. }
  710. break;
  711. case WM_VSCROLL:
  712. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  713. break;
  714. case PSM_QUERYSIBLINGS:
  715. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  716. switch (wParam)
  717. {
  718. case OLEUI_QUERY_LINKBROKEN:
  719. // lpVP could be NULL in low memory situations-- in this case don't handle
  720. // the message.
  721. if (lpVP != NULL)
  722. {
  723. if (!lpVP->bIconChanged)
  724. {
  725. // re-init icon, since user hasn't changed it
  726. HGLOBAL hMetaPict;
  727. lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict, NULL, NULL);
  728. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET,
  729. 1, (LPARAM)hMetaPict);
  730. }
  731. return TRUE;
  732. }
  733. }
  734. break;
  735. case WM_NOTIFY:
  736. switch (((NMHDR*)lParam)->code)
  737. {
  738. case PSN_HELP:
  739. PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
  740. (WPARAM)hDlg, MAKELPARAM(IDD_VIEWPROPS, 0));
  741. break;
  742. case PSN_APPLY:
  743. {
  744. HGLOBAL hMetaPict = NULL;
  745. int nCurrentScale = -1;
  746. DWORD dvAspect = (DWORD)-1;
  747. BOOL bRelativeToOrig = FALSE;
  748. // handle icon change
  749. if (lpVP->bIconChanged)
  750. {
  751. hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
  752. IDC_VP_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
  753. lpVP->bIconChanged = FALSE;
  754. }
  755. // handle scale changes
  756. if (IsWindowEnabled(GetDlgItem(hDlg, IDC_VP_PERCENT)))
  757. {
  758. // parse the percentage entered
  759. BOOL bValid;
  760. nCurrentScale = GetDlgItemInt(hDlg, IDC_VP_PERCENT, &bValid, FALSE);
  761. if (!bValid)
  762. {
  763. PopupMessage(GetParent(hDlg), IDS_VIEWPROPS,
  764. IDS_INVALIDPERCENTAGE, MB_OK|MB_ICONEXCLAMATION);
  765. // cancel the call
  766. SetWindowLong(hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  767. return TRUE;
  768. }
  769. // normalize range
  770. int nScaleMin, nScaleMax;
  771. if (lpOVP->nScaleMin > lpOVP->nScaleMax)
  772. {
  773. nScaleMin = lpOVP->nScaleMax;
  774. nScaleMax = lpOVP->nScaleMin;
  775. }
  776. else
  777. {
  778. nScaleMin = lpOVP->nScaleMin;
  779. nScaleMax = lpOVP->nScaleMax;
  780. }
  781. // check range for validity
  782. if (nCurrentScale < nScaleMin || nCurrentScale > nScaleMax)
  783. {
  784. // format appropriate message
  785. TCHAR szCaption[128];
  786. LoadString(_g_hOleStdResInst, IDS_VIEWPROPS, szCaption, 128);
  787. TCHAR szFormat[128];
  788. LoadString(_g_hOleStdResInst, IDS_RANGEERROR, szFormat, 128);
  789. TCHAR szTemp[256], szNum1[32], szNum2[32];
  790. wsprintf(szNum1, _T("%d"), lpOVP->nScaleMin);
  791. wsprintf(szNum2, _T("%d"), lpOVP->nScaleMax);
  792. FormatString2(szTemp, szFormat, szNum1, szNum2);
  793. MessageBox(GetParent(hDlg), szTemp, szCaption, MB_OK|MB_ICONEXCLAMATION);
  794. // and cancel the call
  795. SetWindowLong(hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  796. return TRUE;
  797. }
  798. // otherwise scale is in correct range
  799. bRelativeToOrig =
  800. SendDlgItemMessage(hDlg, IDC_VP_RELATIVE, BM_GETCHECK, 0, 0) != 0;
  801. if (nCurrentScale != lpVP->nCurrentScale ||
  802. bRelativeToOrig != lpVP->bRelativeToOrig)
  803. {
  804. lpVP->nCurrentScale = nCurrentScale;
  805. lpVP->bRelativeToOrig = bRelativeToOrig;
  806. }
  807. }
  808. // handle aspect changes
  809. if (SendDlgItemMessage(hDlg, IDC_VP_ASICON, BM_GETCHECK, 0, 0L))
  810. dvAspect = DVASPECT_ICON;
  811. else
  812. dvAspect = DVASPECT_CONTENT;
  813. if (dvAspect == lpVP->dvAspect)
  814. dvAspect = (DWORD)-1;
  815. else
  816. {
  817. lpVP->dvAspect = dvAspect;
  818. bRelativeToOrig = 1;
  819. }
  820. lpObjInfo->SetViewInfo(lpOP->dwObject, hMetaPict, dvAspect,
  821. nCurrentScale, bRelativeToOrig);
  822. }
  823. SetWindowLong(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  824. PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  825. return TRUE;
  826. }
  827. break;
  828. case WM_DESTROY:
  829. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0);
  830. StandardCleanup((PVOID)lpVP, hDlg);
  831. return TRUE;
  832. }
  833. return FALSE;
  834. }
  835. /////////////////////////////////////////////////////////////////////////////
  836. // LinkPropsDialogProc and helpers
  837. static BOOL IsNullTime(const FILETIME* lpFileTime)
  838. {
  839. FILETIME fileTimeNull = { 0, 0 };
  840. return CompareFileTime(&fileTimeNull, lpFileTime) == 0;
  841. }
  842. static BOOL SetDlgItemDate(HWND hDlg, int nID, const FILETIME* lpFileTime)
  843. {
  844. if (IsNullTime(lpFileTime))
  845. return FALSE;
  846. // convert UTC file time to system time
  847. FILETIME localTime;
  848. FileTimeToLocalFileTime(lpFileTime, &localTime);
  849. SYSTEMTIME systemTime;
  850. FileTimeToSystemTime(&localTime, &systemTime);
  851. TCHAR szDate[80];
  852. GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemTime,
  853. NULL, szDate, sizeof(szDate) / sizeof(TCHAR));
  854. SetDlgItemText(hDlg, nID, szDate);
  855. return TRUE;
  856. }
  857. static BOOL SetDlgItemTime(HWND hDlg, int nID, const FILETIME* lpFileTime)
  858. {
  859. if (IsNullTime(lpFileTime))
  860. return FALSE;
  861. // convert UTC file time to system time
  862. FILETIME localTime;
  863. FileTimeToLocalFileTime(lpFileTime, &localTime);
  864. SYSTEMTIME systemTime;
  865. FileTimeToSystemTime(&localTime, &systemTime);
  866. if (systemTime.wHour || systemTime.wMinute || systemTime.wSecond)
  867. {
  868. TCHAR szTime[80];
  869. GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systemTime,
  870. NULL, szTime, sizeof(szTime)/sizeof(TCHAR));
  871. SetDlgItemText(hDlg, nID, szTime);
  872. }
  873. return TRUE;
  874. }
  875. BOOL FLinkPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  876. {
  877. // Copy the structure at lParam into our instance memory.
  878. HFONT hFont;
  879. LPLINKPROPS lpLP = (LPLINKPROPS)LpvStandardInit(hDlg, sizeof(LINKPROPS), &hFont);
  880. // LpvStandardInit send a termination to us already.
  881. if (NULL == lpLP)
  882. return FALSE;
  883. LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
  884. LPOLEUILINKPROPS lpOLP = (LPOLEUILINKPROPS)lpPP->lParam;
  885. lpLP->lpOLP = lpOLP;
  886. lpLP->nIDD = IDD_LINKPROPS;
  887. // If we got a font, send it to the necessary controls.
  888. if (NULL != hFont)
  889. {
  890. // Do this for as many controls as you need it for.
  891. SendDlgItemMessage(hDlg, IDC_LP_LINKSOURCE, WM_SETFONT, (WPARAM)hFont, 0);
  892. SendDlgItemMessage(hDlg, IDC_LP_DATE, WM_SETFONT, (WPARAM)hFont, 0);
  893. SendDlgItemMessage(hDlg, IDC_LP_TIME, WM_SETFONT, (WPARAM)hFont, 0);
  894. }
  895. // general "Unknown" string for unknown items
  896. TCHAR szUnknown[64];
  897. LoadString(_g_hOleStdResInst, IDS_OLE2UIUNKNOWN, szUnknown, 64);
  898. // get object information and fill in default fields
  899. LPOLEUIOBJECTPROPS lpOP = lpOLP->lpOP;
  900. LPOLEUILINKINFO lpLinkInfo = lpOP->lpLinkInfo;
  901. FILETIME lastUpdate; memset(&lastUpdate, 0, sizeof(lastUpdate));
  902. lpLinkInfo->GetLastUpdate(lpOP->dwLink, &lastUpdate);
  903. // initialize time and date static text
  904. if (IsNullTime(&lastUpdate))
  905. {
  906. // time and date are unknown
  907. SetDlgItemText(hDlg, IDC_LP_DATE, szUnknown);
  908. SetDlgItemText(hDlg, IDC_LP_TIME, szUnknown);
  909. }
  910. else
  911. {
  912. // time and date are known
  913. SetDlgItemDate(hDlg, IDC_LP_DATE, &lastUpdate);
  914. SetDlgItemTime(hDlg, IDC_LP_TIME, &lastUpdate);
  915. }
  916. // initialize source display name
  917. LPTSTR lpszDisplayName;
  918. lpLinkInfo->GetLinkSource(lpOP->dwLink, &lpszDisplayName,
  919. &lpLP->nFileLength, NULL, NULL, NULL, NULL);
  920. SetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpszDisplayName);
  921. OleStdFree(lpszDisplayName);
  922. // initialize automatic/manual update field
  923. DWORD dwUpdate;
  924. lpLinkInfo->GetLinkUpdateOptions(lpOP->dwLink, &dwUpdate);
  925. CheckRadioButton(hDlg, IDC_LP_AUTOMATIC, IDC_LP_MANUAL,
  926. dwUpdate == OLEUPDATE_ALWAYS ? IDC_LP_AUTOMATIC : IDC_LP_MANUAL);
  927. lpLP->dwUpdate = dwUpdate;
  928. if (!(lpOP->dwFlags & OPF_SHOWHELP))
  929. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  930. // Call the hook with lCustData in lParam
  931. UStandardHook((PVOID)lpLP, hDlg, WM_INITDIALOG, wParam, lpOLP->lCustData);
  932. return TRUE;
  933. }
  934. INT_PTR CALLBACK LinkPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  935. {
  936. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  937. COMMANDPARAMS(wID, wCode, hWndMsg);
  938. // This will fail under WM_INITDIALOG, where we allocate it.
  939. UINT uHook = 0;
  940. LPLINKPROPS lpLP = (LPLINKPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
  941. // If the hook processed the message, we're done.
  942. if (0 != uHook)
  943. return (INT_PTR)uHook;
  944. // Get pointers to important info
  945. LPOLEUILINKPROPS lpOLP = NULL;
  946. LPOLEUIOBJECTPROPS lpOP = NULL;
  947. LPOLEUILINKINFO lpLinkInfo;
  948. if (lpLP != NULL)
  949. {
  950. lpOLP = lpLP->lpOLP;
  951. if (lpOLP != NULL)
  952. {
  953. lpLinkInfo = lpOLP->lpOP->lpLinkInfo;
  954. lpOP = lpOLP->lpOP;
  955. }
  956. }
  957. switch (iMsg)
  958. {
  959. case WM_INITDIALOG:
  960. FLinkPropsInit(hDlg, wParam, lParam);
  961. return TRUE;
  962. case WM_COMMAND:
  963. switch (wID)
  964. {
  965. case IDC_LP_OPENSOURCE:
  966. // force update
  967. SendMessage(GetParent(hDlg), PSM_APPLY, 0, 0);
  968. // launch the object
  969. lpLinkInfo->OpenLinkSource(lpOP->dwLink);
  970. // close the dialog
  971. SendMessage(GetParent(hDlg), WM_COMMAND, IDOK, 0);
  972. break;
  973. case IDC_LP_UPDATENOW:
  974. {
  975. // force update
  976. SendMessage(GetParent(hDlg), PSM_APPLY, 0, 0);
  977. // update the link via container provided callback
  978. if (lpLinkInfo->UpdateLink(lpOP->dwLink, TRUE, FALSE) != NOERROR)
  979. break;
  980. // since link was updated, update the time/date display
  981. SYSTEMTIME systemTime; GetSystemTime(&systemTime);
  982. FILETIME localTime; SystemTimeToFileTime(&systemTime, &localTime);
  983. FILETIME lastUpdate; LocalFileTimeToFileTime(&localTime, &lastUpdate);
  984. lpLinkInfo->GetLastUpdate(lpOP->dwLink, &lastUpdate);
  985. SetDlgItemDate(hDlg, IDC_LP_DATE, &lastUpdate);
  986. SetDlgItemTime(hDlg, IDC_LP_TIME, &lastUpdate);
  987. // modification that cannot be undone
  988. SendMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  989. }
  990. break;
  991. case IDC_LP_BREAKLINK:
  992. {
  993. UINT uRet = PopupMessage(GetParent(hDlg), IDS_LINKPROPS,
  994. IDS_CONFIRMBREAKLINK, MB_YESNO|MB_ICONQUESTION);
  995. if (uRet == IDYES)
  996. {
  997. // cancel the link turning it into a picture
  998. lpLinkInfo->CancelLink(lpOP->dwLink);
  999. // allow other pages to refresh
  1000. lpOP->dwFlags &= ~OPF_OBJECTISLINK;
  1001. SendMessage(GetParent(hDlg), PSM_QUERYSIBLINGS,
  1002. OLEUI_QUERY_LINKBROKEN, 0);
  1003. // remove the links page (since this is no longer a link)
  1004. SendMessage(GetParent(hDlg), PSM_REMOVEPAGE, 2, 0);
  1005. }
  1006. }
  1007. break;
  1008. case IDC_LP_CHANGESOURCE:
  1009. {
  1010. // get current source in OLE memory
  1011. UINT nLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_LP_LINKSOURCE));
  1012. LPTSTR lpszDisplayName = (LPTSTR)OleStdMalloc((nLen+1) * sizeof(TCHAR));
  1013. GetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpszDisplayName, nLen+1);
  1014. if (lpszDisplayName == NULL)
  1015. break;
  1016. // fill in the OLEUICHANGESOURCE struct
  1017. OLEUICHANGESOURCE cs; memset(&cs, 0, sizeof(cs));
  1018. cs.cbStruct = sizeof(cs);
  1019. cs.hWndOwner = GetParent(GetParent(hDlg));
  1020. cs.dwFlags = CSF_ONLYGETSOURCE;
  1021. if (lpOP->dwFlags & OPF_SHOWHELP)
  1022. cs.dwFlags |= CSF_SHOWHELP;
  1023. cs.lpOleUILinkContainer = lpLinkInfo;
  1024. cs.dwLink = lpOP->dwLink;
  1025. cs.lpszDisplayName = lpszDisplayName;
  1026. cs.nFileLength = lpLP->nFileLength;
  1027. // allow the Change Souce dialog to be hooked
  1028. UINT uRet = UStandardHook(lpLP, hDlg, uMsgChangeSource, 0,
  1029. (LPARAM)&cs);
  1030. if (!uRet)
  1031. {
  1032. uRet = (OLEUI_OK == OleUIChangeSource(&cs));
  1033. SetFocus(hDlg);
  1034. }
  1035. if (uRet)
  1036. {
  1037. OleStdFree(lpLP->lpszDisplayName);
  1038. lpLP->lpszDisplayName = cs.lpszDisplayName;
  1039. lpLP->nFileLength = cs.nFileLength;
  1040. SetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpLP->lpszDisplayName);
  1041. OleStdFree(cs.lpszTo);
  1042. OleStdFree(cs.lpszFrom);
  1043. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  1044. }
  1045. }
  1046. break;
  1047. case IDC_LP_MANUAL:
  1048. case IDC_LP_AUTOMATIC:
  1049. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  1050. break;
  1051. case IDC_OLEUIHELP:
  1052. PostMessage(GetParent(GetParent(hDlg)),
  1053. uMsgHelp,
  1054. (WPARAM)hDlg,
  1055. MAKELPARAM(IDD_LINKPROPS, 0));
  1056. return TRUE;
  1057. }
  1058. break;
  1059. case WM_NOTIFY:
  1060. switch (((NMHDR*)lParam)->code)
  1061. {
  1062. case PSN_HELP:
  1063. PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
  1064. (WPARAM)hDlg, MAKELPARAM(IDD_LINKPROPS, 0));
  1065. break;
  1066. case PSN_APPLY:
  1067. {
  1068. // update link update options first
  1069. DWORD dwUpdate;
  1070. if (SendDlgItemMessage(hDlg, IDC_LP_AUTOMATIC, BM_GETCHECK, 0, 0))
  1071. dwUpdate = OLEUPDATE_ALWAYS;
  1072. else
  1073. dwUpdate = OLEUPDATE_ONCALL;
  1074. if (dwUpdate != lpLP->dwUpdate)
  1075. lpLinkInfo->SetLinkUpdateOptions(lpOP->dwLink, dwUpdate);
  1076. // set the link source
  1077. if (lpLP->lpszDisplayName != NULL)
  1078. {
  1079. // try setting with validation first
  1080. ULONG chEaten;
  1081. if (NOERROR != lpLinkInfo->SetLinkSource(lpOP->dwLink,
  1082. lpLP->lpszDisplayName, lpLP->nFileLength, &chEaten,
  1083. TRUE))
  1084. {
  1085. UINT uRet = PopupMessage(GetParent(hDlg), IDS_LINKPROPS,
  1086. IDS_INVALIDSOURCE, MB_ICONQUESTION|MB_YESNO);
  1087. if (uRet == IDYES)
  1088. {
  1089. // user wants to correct the link source
  1090. SetWindowLong(hDlg, DWLP_MSGRESULT, 1);
  1091. return TRUE;
  1092. }
  1093. // user doesn't care if link source is bogus
  1094. lpLinkInfo->SetLinkSource(lpOP->dwLink,
  1095. lpLP->lpszDisplayName, lpLP->nFileLength, &chEaten,
  1096. FALSE);
  1097. }
  1098. OleStdFree(lpLP->lpszDisplayName);
  1099. lpLP->lpszDisplayName = NULL;
  1100. }
  1101. }
  1102. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  1103. PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  1104. return TRUE;
  1105. }
  1106. break;
  1107. case WM_DESTROY:
  1108. if (lpLP != NULL)
  1109. {
  1110. OleStdFree(lpLP->lpszDisplayName);
  1111. lpLP->lpszDisplayName = NULL;
  1112. }
  1113. StandardCleanup((PVOID)lpLP, hDlg);
  1114. return TRUE;
  1115. default:
  1116. if (lpOP != NULL && lpOP->lpPS->hwndParent && iMsg == uMsgBrowseOFN)
  1117. {
  1118. SendMessage(lpOP->lpPS->hwndParent, uMsgBrowseOFN, wParam, lParam);
  1119. }
  1120. break;
  1121. }
  1122. return FALSE;
  1123. }
  1124. /////////////////////////////////////////////////////////////////////////////
  1125. // Property Page initialization code
  1126. struct PROPPAGEDATA
  1127. {
  1128. UINT nTemplateID;
  1129. UINT nTemplateID4;
  1130. DLGPROC pfnDlgProc;
  1131. size_t nPtrOffset;
  1132. };
  1133. #define PTR_OFFSET(x) offsetof(OLEUIOBJECTPROPS, x)
  1134. static PROPPAGEDATA pageData[3] =
  1135. {
  1136. { IDD_GNRLPROPS,IDD_GNRLPROPS4, GnrlPropsDialogProc, PTR_OFFSET(lpGP), },
  1137. { IDD_VIEWPROPS,IDD_VIEWPROPS, ViewPropsDialogProc, PTR_OFFSET(lpVP), },
  1138. { IDD_LINKPROPS,IDD_LINKPROPS4, LinkPropsDialogProc, PTR_OFFSET(lpLP), },
  1139. };
  1140. #undef PTR_OFFSET
  1141. static UINT WINAPI PrepareObjectProperties(LPOLEUIOBJECTPROPS lpOP)
  1142. {
  1143. // setup back pointers from page structs to sheet structs
  1144. lpOP->lpGP->lpOP = lpOP;
  1145. lpOP->lpVP->lpOP = lpOP;
  1146. if ((lpOP->dwFlags & OPF_OBJECTISLINK) && lpOP->lpLP != NULL)
  1147. lpOP->lpLP->lpOP = lpOP;
  1148. // pre-init GNRLPROPS struct
  1149. LPOLEUIGNRLPROPS lpGP = lpOP->lpGP;
  1150. // get ready to initialize PROPSHEET structs
  1151. LPPROPSHEETHEADER lpPS = lpOP->lpPS;
  1152. LPPROPSHEETPAGE lpPPs = (LPPROPSHEETPAGE)lpPS->ppsp;
  1153. UINT nMaxPage = (lpOP->dwFlags & OPF_OBJECTISLINK ? 3 : 2);
  1154. // setting OPF_NOFILLDEFAULT allows you to control almost everything
  1155. if (!(lpOP->dwFlags & OPF_NOFILLDEFAULT))
  1156. {
  1157. // get array of 3 PROPSHEETPAGE structs if not provided
  1158. if (lpPS->ppsp == NULL)
  1159. {
  1160. lpPS->nPages = nMaxPage;
  1161. lpPPs = (LPPROPSHEETPAGE)
  1162. OleStdMalloc(nMaxPage * sizeof(PROPSHEETPAGE));
  1163. if (lpPPs == NULL)
  1164. return OLEUI_ERR_OLEMEMALLOC;
  1165. memset(lpPPs, 0, nMaxPage * sizeof(PROPSHEETPAGE));
  1166. lpPS->ppsp = lpPPs;
  1167. }
  1168. // fill in defaults for lpPS
  1169. lpPS->dwFlags |= PSH_PROPSHEETPAGE;
  1170. if (lpPS->hInstance == NULL)
  1171. lpPS->hInstance = _g_hOleStdResInst;
  1172. // fill Defaults for Standard Property Pages
  1173. LPPROPSHEETPAGE lpPP = lpPPs;
  1174. for (UINT nPage = 0; nPage < nMaxPage; nPage++)
  1175. {
  1176. PROPPAGEDATA* pPageData = &pageData[nPage];
  1177. if (lpPP->dwSize == 0)
  1178. lpPP->dwSize = sizeof(PROPSHEETPAGE);
  1179. if (lpPP->hInstance == NULL)
  1180. lpPP->hInstance = _g_hOleStdResInst;
  1181. UINT nIDD = bWin4 ?
  1182. pPageData->nTemplateID4 : pPageData->nTemplateID;
  1183. if (lpPP->pszTemplate == NULL)
  1184. lpPP->pszTemplate = MAKEINTRESOURCE(nIDD);
  1185. lpPP = (LPPROPSHEETPAGE)((LPBYTE)lpPP+lpPP->dwSize);
  1186. }
  1187. }
  1188. // fill Property Page info which cannot be overridden
  1189. LPPROPSHEETPAGE lpPP = lpPPs;
  1190. for (UINT nPage = 0; nPage < nMaxPage; nPage++)
  1191. {
  1192. PROPPAGEDATA* pPageData = &pageData[nPage];
  1193. lpPP->pfnDlgProc = pPageData->pfnDlgProc;
  1194. lpPP->lParam = (LPARAM)
  1195. *(OLEUIGNRLPROPS**)((LPBYTE)lpOP + pPageData->nPtrOffset);
  1196. lpPP = (LPPROPSHEETPAGE)((LPBYTE)lpPP+lpPP->dwSize);
  1197. }
  1198. return OLEUI_SUCCESS;
  1199. }
  1200. /////////////////////////////////////////////////////////////////////////////