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.

1396 lines
57 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)/sizeof(*szTemp)-wLen);
  325. szTemp[sizeof(szTemp)/sizeof(*szTemp)-1] = 0;
  326. wLen = lstrlen(szTemp);
  327. wLen += _snwprintf(szTemp+wLen, sizeof(szTemp)/sizeof(*szTemp)-wLen, szFormat, wDec);
  328. szTemp[sizeof(szTemp)/sizeof(*szTemp)-1] = 0;
  329. }
  330. }
  331. LoadString(_g_hOleStdResInst, pwOrders[i], szOrder,
  332. sizeof(szOrder)/sizeof(szOrder[0]));
  333. wsprintf(szBuf, szOrder, (LPSTR)szTemp);
  334. return szBuf;
  335. }
  336. LPTSTR WINAPI ShortSizeFormat(DWORD dw, LPTSTR szBuf)
  337. {
  338. return ShortSizeFormat64((__int64)dw, szBuf);
  339. }
  340. BOOL FGnrlPropsRefresh(HWND hDlg, LPGNRLPROPS lpGP)
  341. {
  342. // get object information and fill in default fields
  343. LPOLEUIOBJECTPROPS lpOP = lpGP->lpOGP->lpOP;
  344. LPOLEUIOBJINFO lpObjInfo = lpOP->lpObjInfo;
  345. // get object's icon
  346. HGLOBAL hMetaPict;
  347. lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict, NULL, NULL);
  348. if (hMetaPict != NULL)
  349. {
  350. HICON hIcon = OleUIMetafilePictExtractIcon(hMetaPict);
  351. SendDlgItemMessage(hDlg, IDC_GP_OBJECTICON, STM_SETICON,
  352. (WPARAM)hIcon, 0);
  353. }
  354. OleUIMetafilePictIconFree(hMetaPict);
  355. // get type, short type, location, and size of object
  356. DWORD dwObjSize;
  357. LPTSTR lpszLabel = NULL;
  358. LPTSTR lpszType = NULL;
  359. LPTSTR lpszShortType = NULL;
  360. LPTSTR lpszLocation = NULL;
  361. lpObjInfo->GetObjectInfo(lpOP->dwObject, &dwObjSize, &lpszLabel,
  362. &lpszType, &lpszShortType, &lpszLocation);
  363. // set name, type, and size of object
  364. SetDlgItemText(hDlg, IDC_GP_OBJECTNAME, lpszLabel);
  365. SetDlgItemText(hDlg, IDC_GP_OBJECTTYPE, lpszType);
  366. SetDlgItemText(hDlg, IDC_GP_OBJECTLOCATION, lpszLocation);
  367. TCHAR szTemp[128];
  368. if (dwObjSize == (DWORD)-1)
  369. {
  370. LoadString(_g_hOleStdResInst, IDS_OLE2UIUNKNOWN, szTemp, 64);
  371. SetDlgItemText(hDlg, IDC_GP_OBJECTSIZE, szTemp);
  372. }
  373. else
  374. {
  375. // get the master formatting string
  376. TCHAR szFormat[64];
  377. LoadString(_g_hOleStdResInst, IDS_OBJECTSIZE, szFormat, 64);
  378. // format the size in two ways (short, and with commas)
  379. TCHAR szNum1[20], szNum2[32];
  380. ShortSizeFormat(dwObjSize, szNum1);
  381. AddCommas(dwObjSize, szNum2, 32);
  382. FormatString2(szTemp, szFormat, szNum1, szNum2, sizeof(szTemp)/sizeof(TCHAR));
  383. // set the control's text
  384. SetDlgItemText(hDlg, IDC_GP_OBJECTSIZE, szTemp);
  385. }
  386. // enable/disable convert button as necessary
  387. BOOL bEnable = TRUE;
  388. if (lpOP->dwFlags & (OPF_OBJECTISLINK|OPF_DISABLECONVERT))
  389. bEnable = FALSE;
  390. else
  391. {
  392. CLSID clsid; WORD wFormat;
  393. lpObjInfo->GetConvertInfo(lpOP->dwObject, &clsid, &wFormat, NULL, NULL, NULL);
  394. bEnable = OleUICanConvertOrActivateAs(clsid, FALSE, wFormat);
  395. }
  396. StandardEnableDlgItem(hDlg, IDC_GP_CONVERT, bEnable);
  397. // cleanup temporary info strings
  398. OleStdFree(lpszLabel);
  399. OleStdFree(lpszType);
  400. OleStdFree(lpszShortType);
  401. OleStdFree(lpszLocation);
  402. return TRUE;
  403. }
  404. BOOL FGnrlPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  405. {
  406. // Copy the structure at lParam into our instance memory.
  407. HFONT hFont;
  408. LPGNRLPROPS lpGP = (LPGNRLPROPS)LpvStandardInit(hDlg, sizeof(GNRLPROPS), &hFont);
  409. // LpvStandardInit send a termination to us already.
  410. if (NULL == lpGP)
  411. return FALSE;
  412. LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
  413. LPOLEUIGNRLPROPS lpOGP = (LPOLEUIGNRLPROPS)lpPP->lParam;
  414. lpGP->lpOGP = lpOGP;
  415. lpGP->nIDD = IDD_GNRLPROPS;
  416. // If we got a font, send it to the necessary controls.
  417. if (NULL != hFont)
  418. {
  419. SendDlgItemMessage(hDlg, IDC_GP_OBJECTNAME, WM_SETFONT, (WPARAM)hFont, 0L);
  420. SendDlgItemMessage(hDlg, IDC_GP_OBJECTTYPE, WM_SETFONT, (WPARAM)hFont, 0L);
  421. SendDlgItemMessage(hDlg, IDC_GP_OBJECTLOCATION, WM_SETFONT, (WPARAM)hFont, 0L);
  422. SendDlgItemMessage(hDlg, IDC_GP_OBJECTSIZE, WM_SETFONT, (WPARAM)hFont, 0L);
  423. }
  424. // Show or hide the help button
  425. if (!(lpOGP->lpOP->dwFlags & OPF_SHOWHELP))
  426. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  427. // Initialize the controls
  428. FGnrlPropsRefresh(hDlg, lpGP);
  429. // Call the hook with lCustData in lParam
  430. UStandardHook((PVOID)lpGP, hDlg, WM_INITDIALOG, wParam, lpOGP->lCustData);
  431. return TRUE;
  432. }
  433. INT_PTR CALLBACK GnrlPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  434. {
  435. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  436. COMMANDPARAMS(wID, wCode, hWndMsg);
  437. // This will fail under WM_INITDIALOG, where we allocate it.
  438. UINT uHook = 0;
  439. LPGNRLPROPS lpGP = (LPGNRLPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
  440. // If the hook processed the message, we're done.
  441. if (0 != uHook)
  442. return (INT_PTR)uHook;
  443. // Get pointers to important info
  444. LPOLEUIGNRLPROPS lpOGP = NULL;
  445. LPOLEUIOBJECTPROPS lpOP = NULL;
  446. LPOLEUIOBJINFO lpObjInfo = NULL;
  447. if (lpGP != NULL)
  448. {
  449. lpOGP = lpGP->lpOGP;
  450. if (lpOGP != NULL)
  451. {
  452. lpObjInfo = lpOGP->lpOP->lpObjInfo;
  453. lpOP = lpOGP->lpOP;
  454. }
  455. }
  456. switch (iMsg)
  457. {
  458. case WM_INITDIALOG:
  459. FGnrlPropsInit(hDlg, wParam, lParam);
  460. return TRUE;
  461. case WM_COMMAND:
  462. switch (wID)
  463. {
  464. case IDC_GP_CONVERT:
  465. {
  466. if(!lpGP)
  467. return TRUE;
  468. // Call up convert dialog to obtain new CLSID
  469. OLEUICONVERT cv; memset(&cv, 0, sizeof(cv));
  470. cv.cbStruct = sizeof(cv);
  471. cv.dwFlags |= CF_CONVERTONLY;
  472. if (lpOP->dwFlags & OPF_SHOWHELP)
  473. cv.dwFlags |= CF_SHOWHELPBUTTON;
  474. cv.clsidConvertDefault = lpGP->clsidNew;
  475. cv.dvAspect = DVASPECT_CONTENT;
  476. lpObjInfo->GetObjectInfo(lpOP->dwObject,
  477. NULL, NULL, &cv.lpszUserType, NULL, NULL);
  478. lpObjInfo->GetConvertInfo(lpOP->dwObject,
  479. &cv.clsid, &cv.wFormat, &cv.clsidConvertDefault,
  480. &cv.lpClsidExclude, &cv.cClsidExclude);
  481. cv.fIsLinkedObject =
  482. (lpOGP->lpOP->dwFlags & OPF_OBJECTISLINK);
  483. if (cv.clsidConvertDefault != CLSID_NULL)
  484. cv.dwFlags |= CF_SETCONVERTDEFAULT;
  485. cv.hWndOwner = GetParent(GetParent(hDlg));
  486. // allow caller to hook the convert structure
  487. uHook = UStandardHook(lpGP, hDlg, uMsgConvert, 0, (LPARAM)&cv);
  488. if (0 == uHook)
  489. {
  490. uHook = (OLEUI_OK == OleUIConvert(&cv));
  491. SetFocus(hDlg);
  492. }
  493. // check to see dialog results
  494. if (uHook != 0 && (cv.dwFlags & CF_SELECTCONVERTTO))
  495. {
  496. lpGP->clsidNew = cv.clsidNew;
  497. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  498. }
  499. }
  500. return TRUE;
  501. case IDC_OLEUIHELP:
  502. PostMessage(GetParent(GetParent(hDlg)),
  503. uMsgHelp,
  504. (WPARAM)hDlg,
  505. MAKELPARAM(IDD_GNRLPROPS, 0));
  506. return TRUE;
  507. }
  508. break;
  509. case PSM_QUERYSIBLINGS:
  510. if(!lpGP)
  511. break;
  512. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  513. switch (wParam)
  514. {
  515. case OLEUI_QUERY_GETCLASSID:
  516. *(CLSID*)lParam = lpGP->clsidNew;
  517. SetWindowLong(hDlg, DWLP_MSGRESULT, 1);
  518. return TRUE;
  519. case OLEUI_QUERY_LINKBROKEN:
  520. FGnrlPropsRefresh(hDlg, lpGP);
  521. return TRUE;
  522. }
  523. break;
  524. case WM_NOTIFY:
  525. switch (((NMHDR*)lParam)->code)
  526. {
  527. case PSN_HELP:
  528. PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
  529. (WPARAM)hDlg, MAKELPARAM(IDD_GNRLPROPS, 0));
  530. break;
  531. case PSN_APPLY:
  532. if(!lpGP)
  533. return TRUE;
  534. // apply changes if changes made
  535. if (lpGP->clsidNew != CLSID_NULL)
  536. {
  537. // convert the object -- fail the apply if convert fails
  538. if (NOERROR != lpObjInfo->ConvertObject(lpOP->dwObject,
  539. lpGP->clsidNew))
  540. {
  541. SetWindowLong(hDlg, DWLP_MSGRESULT, 1);
  542. return TRUE;
  543. }
  544. lpGP->clsidNew = CLSID_NULL;
  545. }
  546. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  547. PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  548. return TRUE;
  549. }
  550. break;
  551. case WM_DESTROY:
  552. {
  553. HICON hIcon = (HICON)SendDlgItemMessage(hDlg, IDC_GP_OBJECTICON,
  554. STM_GETICON, 0, 0);
  555. if (hIcon != NULL)
  556. DestroyIcon(hIcon);
  557. StandardCleanup((PVOID)lpGP, hDlg);
  558. }
  559. return TRUE;
  560. }
  561. return FALSE;
  562. }
  563. /////////////////////////////////////////////////////////////////////////////
  564. // ViewPropsDialogProc and helpers
  565. void EnableDisableScaleControls(LPVIEWPROPS lpVP, HWND hDlg)
  566. {
  567. LPOLEUIVIEWPROPS lpOVP = lpVP->lpOVP;
  568. BOOL bEnable = !(lpOVP->dwFlags & VPF_DISABLESCALE) &&
  569. SendDlgItemMessage(hDlg, IDC_VP_ASICON, BM_GETCHECK, 0, 0) == 0;
  570. StandardEnableDlgItem(hDlg, IDC_VP_SPIN, bEnable);
  571. StandardEnableDlgItem(hDlg, IDC_VP_PERCENT, bEnable);
  572. StandardEnableDlgItem(hDlg, IDC_VP_SCALETXT, bEnable);
  573. bEnable = bEnable && !(lpOVP->dwFlags & VPF_DISABLERELATIVE);
  574. StandardEnableDlgItem(hDlg, IDC_VP_RELATIVE, bEnable);
  575. }
  576. BOOL FViewPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  577. {
  578. // Copy the structure at lParam into our instance memory.
  579. LPVIEWPROPS lpVP = (LPVIEWPROPS)LpvStandardInit(hDlg, sizeof(VIEWPROPS));
  580. // LpvStandardInit send a termination to us already.
  581. if (NULL == lpVP)
  582. return FALSE;
  583. LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
  584. LPOLEUIVIEWPROPS lpOVP = (LPOLEUIVIEWPROPS)lpPP->lParam;
  585. lpVP->lpOVP = lpOVP;
  586. lpVP->nIDD = IDD_VIEWPROPS;
  587. // get object information and fill in default fields
  588. LPOLEUIOBJECTPROPS lpOP = lpOVP->lpOP;
  589. LPOLEUIOBJINFO lpObjInfo = lpOP->lpObjInfo;
  590. // initialize icon and scale variables
  591. HGLOBAL hMetaPict;
  592. DWORD dvAspect;
  593. int nCurrentScale;
  594. lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict,
  595. &dvAspect, &nCurrentScale);
  596. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET,
  597. 0, (LPARAM)hMetaPict);
  598. lpVP->nCurrentScale = nCurrentScale;
  599. lpVP->dvAspect = dvAspect;
  600. // Initialize the result image
  601. SendDlgItemMessage(hDlg, IDC_VP_RESULTIMAGE,
  602. RIM_IMAGESET, RESULTIMAGE_EDITABLE, 0L);
  603. // Initialize controls
  604. CheckRadioButton(hDlg, IDC_VP_EDITABLE, IDC_VP_ASICON,
  605. dvAspect == DVASPECT_CONTENT ? IDC_VP_EDITABLE : IDC_VP_ASICON);
  606. SendDlgItemMessage(hDlg, IDC_VP_RELATIVE, BM_SETCHECK,
  607. (lpOVP->dwFlags & VPF_SELECTRELATIVE) != 0, 0L);
  608. if (!(lpOVP->dwFlags & VPF_DISABLESCALE))
  609. SetDlgItemInt(hDlg, IDC_VP_PERCENT, nCurrentScale, FALSE);
  610. lpVP->bRelativeToOrig = SendDlgItemMessage(hDlg, IDC_VP_RELATIVE,
  611. BM_GETCHECK, 0, 0) != 0;
  612. // Setup up-down control as buddy to IDC_VP_PERCENT
  613. HWND hWndSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL,
  614. WS_CHILD|UDS_SETBUDDYINT|UDS_ARROWKEYS|UDS_ALIGNRIGHT, 0, 0, 0, 0,
  615. hDlg, (HMENU)IDC_VP_SPIN, _g_hOleStdInst, NULL);
  616. if (hWndSpin != NULL)
  617. {
  618. SendMessage(hWndSpin, UDM_SETRANGE, 0,
  619. MAKELPARAM(lpOVP->nScaleMax, lpOVP->nScaleMin));
  620. SendMessage(hWndSpin, UDM_SETPOS, 0, nCurrentScale);
  621. SendMessage(hWndSpin, UDM_SETBUDDY,
  622. (WPARAM)GetDlgItem(hDlg, IDC_VP_PERCENT), 0);
  623. ShowWindow(hWndSpin, SW_SHOW);
  624. }
  625. EnableDisableScaleControls(lpVP, hDlg);
  626. if (!(lpOP->dwFlags & OPF_SHOWHELP))
  627. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  628. // Call the hook with lCustData in lParam
  629. UStandardHook((PVOID)lpVP, hDlg, WM_INITDIALOG, wParam, lpOVP->lCustData);
  630. return TRUE;
  631. }
  632. INT_PTR CALLBACK ViewPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  633. {
  634. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  635. COMMANDPARAMS(wID, wCode, hWndMsg);
  636. // This will fail under WM_INITDIALOG, where we allocate it.
  637. UINT uHook = 0;
  638. LPVIEWPROPS lpVP = (LPVIEWPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
  639. // If the hook processed the message, we're done.
  640. if (0 != uHook)
  641. return (INT_PTR)uHook;
  642. // Get pointers to important info
  643. LPOLEUIVIEWPROPS lpOVP = NULL;
  644. LPOLEUIOBJECTPROPS lpOP = NULL;
  645. LPOLEUIOBJINFO lpObjInfo = NULL;
  646. if (lpVP != NULL)
  647. {
  648. lpOVP = lpVP->lpOVP;
  649. if (lpOVP != NULL)
  650. {
  651. lpObjInfo = lpOVP->lpOP->lpObjInfo;
  652. lpOP = lpOVP->lpOP;
  653. }
  654. }
  655. switch (iMsg)
  656. {
  657. case WM_INITDIALOG:
  658. FViewPropsInit(hDlg, wParam, lParam);
  659. return TRUE;
  660. case WM_COMMAND:
  661. switch (wID)
  662. {
  663. case IDC_VP_ASICON:
  664. case IDC_VP_EDITABLE:
  665. EnableDisableScaleControls(lpVP, hDlg);
  666. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  667. return TRUE;
  668. case IDC_VP_CHANGEICON:
  669. {
  670. // Call up Change Icon dialog to obtain new icon
  671. OLEUICHANGEICON ci; memset(&ci, 0, sizeof(ci));
  672. ci.cbStruct = sizeof(ci);
  673. ci.dwFlags = CIF_SELECTCURRENT;
  674. ci.hWndOwner = GetParent(GetParent(hDlg));
  675. ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY,
  676. IBXM_IMAGEGET, 0, 0L);
  677. // get classid to look for (may be new class if conversion applied)
  678. SendMessage(GetParent(hDlg), PSM_QUERYSIBLINGS,
  679. OLEUI_QUERY_GETCLASSID, (LPARAM)&ci.clsid);
  680. lpObjInfo->GetConvertInfo(lpOP->dwObject,
  681. &ci.clsid, NULL, NULL, NULL, NULL);
  682. if (lpOP->dwFlags & OPF_SHOWHELP)
  683. ci.dwFlags |= CIF_SHOWHELP;
  684. // allow the caller to hook the change icon
  685. uHook = UStandardHook(lpVP, hDlg, uMsgChangeIcon, 0, (LPARAM)&ci);
  686. if (0 == uHook)
  687. {
  688. uHook = (OLEUI_OK == OleUIChangeIcon(&ci));
  689. SetFocus(hDlg);
  690. }
  691. if (0 != uHook)
  692. {
  693. // apply the changes
  694. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET, 1,
  695. (LPARAM)ci.hMetaPict);
  696. lpVP->bIconChanged = TRUE;
  697. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  698. }
  699. }
  700. return TRUE;
  701. case IDC_VP_PERCENT:
  702. case IDC_VP_RELATIVE:
  703. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  704. return TRUE;
  705. case IDC_OLEUIHELP:
  706. PostMessage(GetParent(GetParent(hDlg)),
  707. uMsgHelp,
  708. (WPARAM)hDlg,
  709. MAKELPARAM(IDD_VIEWPROPS, 0));
  710. return TRUE;
  711. }
  712. break;
  713. case WM_VSCROLL:
  714. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  715. break;
  716. case PSM_QUERYSIBLINGS:
  717. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  718. switch (wParam)
  719. {
  720. case OLEUI_QUERY_LINKBROKEN:
  721. // lpVP could be NULL in low memory situations-- in this case don't handle
  722. // the message.
  723. if (lpVP != NULL)
  724. {
  725. if (!lpVP->bIconChanged)
  726. {
  727. // re-init icon, since user hasn't changed it
  728. HGLOBAL hMetaPict;
  729. lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict, NULL, NULL);
  730. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET,
  731. 1, (LPARAM)hMetaPict);
  732. }
  733. return TRUE;
  734. }
  735. }
  736. break;
  737. case WM_NOTIFY:
  738. switch (((NMHDR*)lParam)->code)
  739. {
  740. case PSN_HELP:
  741. PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
  742. (WPARAM)hDlg, MAKELPARAM(IDD_VIEWPROPS, 0));
  743. break;
  744. case PSN_APPLY:
  745. {
  746. HGLOBAL hMetaPict = NULL;
  747. int nCurrentScale = -1;
  748. DWORD dvAspect = (DWORD)-1;
  749. BOOL bRelativeToOrig = FALSE;
  750. // handle icon change
  751. if (lpVP->bIconChanged)
  752. {
  753. hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
  754. IDC_VP_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
  755. lpVP->bIconChanged = FALSE;
  756. }
  757. // handle scale changes
  758. if (IsWindowEnabled(GetDlgItem(hDlg, IDC_VP_PERCENT)))
  759. {
  760. // parse the percentage entered
  761. BOOL bValid;
  762. nCurrentScale = GetDlgItemInt(hDlg, IDC_VP_PERCENT, &bValid, FALSE);
  763. if (!bValid)
  764. {
  765. PopupMessage(GetParent(hDlg), IDS_VIEWPROPS,
  766. IDS_INVALIDPERCENTAGE, MB_OK|MB_ICONEXCLAMATION);
  767. // cancel the call
  768. SetWindowLong(hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  769. return TRUE;
  770. }
  771. // normalize range
  772. int nScaleMin, nScaleMax;
  773. if (lpOVP->nScaleMin > lpOVP->nScaleMax)
  774. {
  775. nScaleMin = lpOVP->nScaleMax;
  776. nScaleMax = lpOVP->nScaleMin;
  777. }
  778. else
  779. {
  780. nScaleMin = lpOVP->nScaleMin;
  781. nScaleMax = lpOVP->nScaleMax;
  782. }
  783. // check range for validity
  784. if (nCurrentScale < nScaleMin || nCurrentScale > nScaleMax)
  785. {
  786. // format appropriate message
  787. TCHAR szCaption[128];
  788. LoadString(_g_hOleStdResInst, IDS_VIEWPROPS, szCaption, 128);
  789. TCHAR szFormat[128];
  790. LoadString(_g_hOleStdResInst, IDS_RANGEERROR, szFormat, 128);
  791. TCHAR szTemp[256], szNum1[32], szNum2[32];
  792. wsprintf(szNum1, _T("%d"), lpOVP->nScaleMin);
  793. wsprintf(szNum2, _T("%d"), lpOVP->nScaleMax);
  794. FormatString2(szTemp, szFormat, szNum1, szNum2, sizeof(szTemp)/sizeof(TCHAR));
  795. MessageBox(GetParent(hDlg), szTemp, szCaption, MB_OK|MB_ICONEXCLAMATION);
  796. // and cancel the call
  797. SetWindowLong(hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  798. return TRUE;
  799. }
  800. // otherwise scale is in correct range
  801. bRelativeToOrig =
  802. SendDlgItemMessage(hDlg, IDC_VP_RELATIVE, BM_GETCHECK, 0, 0) != 0;
  803. if (nCurrentScale != lpVP->nCurrentScale ||
  804. bRelativeToOrig != lpVP->bRelativeToOrig)
  805. {
  806. lpVP->nCurrentScale = nCurrentScale;
  807. lpVP->bRelativeToOrig = bRelativeToOrig;
  808. }
  809. }
  810. // handle aspect changes
  811. if (SendDlgItemMessage(hDlg, IDC_VP_ASICON, BM_GETCHECK, 0, 0L))
  812. dvAspect = DVASPECT_ICON;
  813. else
  814. dvAspect = DVASPECT_CONTENT;
  815. if (dvAspect == lpVP->dvAspect)
  816. dvAspect = (DWORD)-1;
  817. else
  818. {
  819. lpVP->dvAspect = dvAspect;
  820. bRelativeToOrig = 1;
  821. }
  822. lpObjInfo->SetViewInfo(lpOP->dwObject, hMetaPict, dvAspect,
  823. nCurrentScale, bRelativeToOrig);
  824. }
  825. SetWindowLong(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  826. PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  827. return TRUE;
  828. }
  829. break;
  830. case WM_DESTROY:
  831. SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0);
  832. StandardCleanup((PVOID)lpVP, hDlg);
  833. return TRUE;
  834. }
  835. return FALSE;
  836. }
  837. /////////////////////////////////////////////////////////////////////////////
  838. // LinkPropsDialogProc and helpers
  839. static BOOL IsNullTime(const FILETIME* lpFileTime)
  840. {
  841. FILETIME fileTimeNull = { 0, 0 };
  842. return CompareFileTime(&fileTimeNull, lpFileTime) == 0;
  843. }
  844. static BOOL SetDlgItemDate(HWND hDlg, int nID, const FILETIME* lpFileTime)
  845. {
  846. if (IsNullTime(lpFileTime))
  847. return FALSE;
  848. // convert UTC file time to system time
  849. FILETIME localTime;
  850. FileTimeToLocalFileTime(lpFileTime, &localTime);
  851. SYSTEMTIME systemTime;
  852. FileTimeToSystemTime(&localTime, &systemTime);
  853. TCHAR szDate[80];
  854. GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemTime,
  855. NULL, szDate, sizeof(szDate) / sizeof(TCHAR));
  856. SetDlgItemText(hDlg, nID, szDate);
  857. return TRUE;
  858. }
  859. static BOOL SetDlgItemTime(HWND hDlg, int nID, const FILETIME* lpFileTime)
  860. {
  861. if (IsNullTime(lpFileTime))
  862. return FALSE;
  863. // convert UTC file time to system time
  864. FILETIME localTime;
  865. FileTimeToLocalFileTime(lpFileTime, &localTime);
  866. SYSTEMTIME systemTime;
  867. FileTimeToSystemTime(&localTime, &systemTime);
  868. if (systemTime.wHour || systemTime.wMinute || systemTime.wSecond)
  869. {
  870. TCHAR szTime[80];
  871. GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systemTime,
  872. NULL, szTime, sizeof(szTime)/sizeof(TCHAR));
  873. SetDlgItemText(hDlg, nID, szTime);
  874. }
  875. return TRUE;
  876. }
  877. BOOL FLinkPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
  878. {
  879. // Copy the structure at lParam into our instance memory.
  880. HFONT hFont;
  881. LPLINKPROPS lpLP = (LPLINKPROPS)LpvStandardInit(hDlg, sizeof(LINKPROPS), &hFont);
  882. // LpvStandardInit send a termination to us already.
  883. if (NULL == lpLP)
  884. return FALSE;
  885. LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
  886. LPOLEUILINKPROPS lpOLP = (LPOLEUILINKPROPS)lpPP->lParam;
  887. lpLP->lpOLP = lpOLP;
  888. lpLP->nIDD = IDD_LINKPROPS;
  889. // If we got a font, send it to the necessary controls.
  890. if (NULL != hFont)
  891. {
  892. // Do this for as many controls as you need it for.
  893. SendDlgItemMessage(hDlg, IDC_LP_LINKSOURCE, WM_SETFONT, (WPARAM)hFont, 0);
  894. SendDlgItemMessage(hDlg, IDC_LP_DATE, WM_SETFONT, (WPARAM)hFont, 0);
  895. SendDlgItemMessage(hDlg, IDC_LP_TIME, WM_SETFONT, (WPARAM)hFont, 0);
  896. }
  897. // general "Unknown" string for unknown items
  898. TCHAR szUnknown[64];
  899. LoadString(_g_hOleStdResInst, IDS_OLE2UIUNKNOWN, szUnknown, 64);
  900. // get object information and fill in default fields
  901. LPOLEUIOBJECTPROPS lpOP = lpOLP->lpOP;
  902. LPOLEUILINKINFO lpLinkInfo = lpOP->lpLinkInfo;
  903. FILETIME lastUpdate; memset(&lastUpdate, 0, sizeof(lastUpdate));
  904. lpLinkInfo->GetLastUpdate(lpOP->dwLink, &lastUpdate);
  905. // initialize time and date static text
  906. if (IsNullTime(&lastUpdate))
  907. {
  908. // time and date are unknown
  909. SetDlgItemText(hDlg, IDC_LP_DATE, szUnknown);
  910. SetDlgItemText(hDlg, IDC_LP_TIME, szUnknown);
  911. }
  912. else
  913. {
  914. // time and date are known
  915. SetDlgItemDate(hDlg, IDC_LP_DATE, &lastUpdate);
  916. SetDlgItemTime(hDlg, IDC_LP_TIME, &lastUpdate);
  917. }
  918. // initialize source display name
  919. LPTSTR lpszDisplayName;
  920. lpLinkInfo->GetLinkSource(lpOP->dwLink, &lpszDisplayName,
  921. &lpLP->nFileLength, NULL, NULL, NULL, NULL);
  922. SetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpszDisplayName);
  923. OleStdFree(lpszDisplayName);
  924. // initialize automatic/manual update field
  925. DWORD dwUpdate;
  926. lpLinkInfo->GetLinkUpdateOptions(lpOP->dwLink, &dwUpdate);
  927. CheckRadioButton(hDlg, IDC_LP_AUTOMATIC, IDC_LP_MANUAL,
  928. dwUpdate == OLEUPDATE_ALWAYS ? IDC_LP_AUTOMATIC : IDC_LP_MANUAL);
  929. lpLP->dwUpdate = dwUpdate;
  930. if (!(lpOP->dwFlags & OPF_SHOWHELP))
  931. StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
  932. // Call the hook with lCustData in lParam
  933. UStandardHook((PVOID)lpLP, hDlg, WM_INITDIALOG, wParam, lpOLP->lCustData);
  934. return TRUE;
  935. }
  936. INT_PTR CALLBACK LinkPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  937. {
  938. // Declare Win16/Win32 compatible WM_COMMAND parameters.
  939. COMMANDPARAMS(wID, wCode, hWndMsg);
  940. // This will fail under WM_INITDIALOG, where we allocate it.
  941. UINT uHook = 0;
  942. LPLINKPROPS lpLP = (LPLINKPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
  943. // If the hook processed the message, we're done.
  944. if (0 != uHook)
  945. return (INT_PTR)uHook;
  946. // Get pointers to important info
  947. LPOLEUILINKPROPS lpOLP = NULL;
  948. LPOLEUIOBJECTPROPS lpOP = NULL;
  949. LPOLEUILINKINFO lpLinkInfo;
  950. if (lpLP != NULL)
  951. {
  952. lpOLP = lpLP->lpOLP;
  953. if (lpOLP != NULL)
  954. {
  955. lpLinkInfo = lpOLP->lpOP->lpLinkInfo;
  956. lpOP = lpOLP->lpOP;
  957. }
  958. }
  959. switch (iMsg)
  960. {
  961. case WM_INITDIALOG:
  962. FLinkPropsInit(hDlg, wParam, lParam);
  963. return TRUE;
  964. case WM_COMMAND:
  965. switch (wID)
  966. {
  967. case IDC_LP_OPENSOURCE:
  968. // force update
  969. SendMessage(GetParent(hDlg), PSM_APPLY, 0, 0);
  970. // launch the object
  971. lpLinkInfo->OpenLinkSource(lpOP->dwLink);
  972. // close the dialog
  973. SendMessage(GetParent(hDlg), WM_COMMAND, IDOK, 0);
  974. break;
  975. case IDC_LP_UPDATENOW:
  976. {
  977. // force update
  978. SendMessage(GetParent(hDlg), PSM_APPLY, 0, 0);
  979. // update the link via container provided callback
  980. if (lpLinkInfo->UpdateLink(lpOP->dwLink, TRUE, FALSE) != NOERROR)
  981. break;
  982. // since link was updated, update the time/date display
  983. SYSTEMTIME systemTime; GetSystemTime(&systemTime);
  984. FILETIME localTime; SystemTimeToFileTime(&systemTime, &localTime);
  985. FILETIME lastUpdate; LocalFileTimeToFileTime(&localTime, &lastUpdate);
  986. lpLinkInfo->GetLastUpdate(lpOP->dwLink, &lastUpdate);
  987. SetDlgItemDate(hDlg, IDC_LP_DATE, &lastUpdate);
  988. SetDlgItemTime(hDlg, IDC_LP_TIME, &lastUpdate);
  989. // modification that cannot be undone
  990. SendMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  991. }
  992. break;
  993. case IDC_LP_BREAKLINK:
  994. {
  995. UINT uRet = PopupMessage(GetParent(hDlg), IDS_LINKPROPS,
  996. IDS_CONFIRMBREAKLINK, MB_YESNO|MB_ICONQUESTION);
  997. if (uRet == IDYES)
  998. {
  999. // cancel the link turning it into a picture
  1000. lpLinkInfo->CancelLink(lpOP->dwLink);
  1001. // allow other pages to refresh
  1002. lpOP->dwFlags &= ~OPF_OBJECTISLINK;
  1003. SendMessage(GetParent(hDlg), PSM_QUERYSIBLINGS,
  1004. OLEUI_QUERY_LINKBROKEN, 0);
  1005. // remove the links page (since this is no longer a link)
  1006. SendMessage(GetParent(hDlg), PSM_REMOVEPAGE, 2, 0);
  1007. }
  1008. }
  1009. break;
  1010. case IDC_LP_CHANGESOURCE:
  1011. {
  1012. // get current source in OLE memory
  1013. UINT nLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_LP_LINKSOURCE));
  1014. LPTSTR lpszDisplayName = (LPTSTR)OleStdMalloc((nLen+1) * sizeof(TCHAR));
  1015. GetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpszDisplayName, nLen+1);
  1016. if (lpszDisplayName == NULL)
  1017. break;
  1018. // fill in the OLEUICHANGESOURCE struct
  1019. OLEUICHANGESOURCE cs; memset(&cs, 0, sizeof(cs));
  1020. cs.cbStruct = sizeof(cs);
  1021. cs.hWndOwner = GetParent(GetParent(hDlg));
  1022. cs.dwFlags = CSF_ONLYGETSOURCE;
  1023. if (lpOP->dwFlags & OPF_SHOWHELP)
  1024. cs.dwFlags |= CSF_SHOWHELP;
  1025. cs.lpOleUILinkContainer = lpLinkInfo;
  1026. cs.dwLink = lpOP->dwLink;
  1027. cs.lpszDisplayName = lpszDisplayName;
  1028. cs.nFileLength = lpLP->nFileLength;
  1029. // allow the Change Souce dialog to be hooked
  1030. UINT uRet = UStandardHook(lpLP, hDlg, uMsgChangeSource, 0,
  1031. (LPARAM)&cs);
  1032. if (!uRet)
  1033. {
  1034. uRet = (OLEUI_OK == OleUIChangeSource(&cs));
  1035. SetFocus(hDlg);
  1036. }
  1037. if (uRet)
  1038. {
  1039. OleStdFree(lpLP->lpszDisplayName);
  1040. lpLP->lpszDisplayName = cs.lpszDisplayName;
  1041. lpLP->nFileLength = cs.nFileLength;
  1042. SetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpLP->lpszDisplayName);
  1043. OleStdFree(cs.lpszTo);
  1044. OleStdFree(cs.lpszFrom);
  1045. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  1046. }
  1047. }
  1048. break;
  1049. case IDC_LP_MANUAL:
  1050. case IDC_LP_AUTOMATIC:
  1051. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  1052. break;
  1053. case IDC_OLEUIHELP:
  1054. PostMessage(GetParent(GetParent(hDlg)),
  1055. uMsgHelp,
  1056. (WPARAM)hDlg,
  1057. MAKELPARAM(IDD_LINKPROPS, 0));
  1058. return TRUE;
  1059. }
  1060. break;
  1061. case WM_NOTIFY:
  1062. switch (((NMHDR*)lParam)->code)
  1063. {
  1064. case PSN_HELP:
  1065. PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
  1066. (WPARAM)hDlg, MAKELPARAM(IDD_LINKPROPS, 0));
  1067. break;
  1068. case PSN_APPLY:
  1069. {
  1070. // update link update options first
  1071. DWORD dwUpdate;
  1072. if (SendDlgItemMessage(hDlg, IDC_LP_AUTOMATIC, BM_GETCHECK, 0, 0))
  1073. dwUpdate = OLEUPDATE_ALWAYS;
  1074. else
  1075. dwUpdate = OLEUPDATE_ONCALL;
  1076. if (dwUpdate != lpLP->dwUpdate)
  1077. lpLinkInfo->SetLinkUpdateOptions(lpOP->dwLink, dwUpdate);
  1078. // set the link source
  1079. if (lpLP->lpszDisplayName != NULL)
  1080. {
  1081. // try setting with validation first
  1082. ULONG chEaten;
  1083. if (NOERROR != lpLinkInfo->SetLinkSource(lpOP->dwLink,
  1084. lpLP->lpszDisplayName, lpLP->nFileLength, &chEaten,
  1085. TRUE))
  1086. {
  1087. UINT uRet = PopupMessage(GetParent(hDlg), IDS_LINKPROPS,
  1088. IDS_INVALIDSOURCE, MB_ICONQUESTION|MB_YESNO);
  1089. if (uRet == IDYES)
  1090. {
  1091. // user wants to correct the link source
  1092. SetWindowLong(hDlg, DWLP_MSGRESULT, 1);
  1093. return TRUE;
  1094. }
  1095. // user doesn't care if link source is bogus
  1096. lpLinkInfo->SetLinkSource(lpOP->dwLink,
  1097. lpLP->lpszDisplayName, lpLP->nFileLength, &chEaten,
  1098. FALSE);
  1099. }
  1100. OleStdFree(lpLP->lpszDisplayName);
  1101. lpLP->lpszDisplayName = NULL;
  1102. }
  1103. }
  1104. SetWindowLong(hDlg, DWLP_MSGRESULT, 0);
  1105. PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
  1106. return TRUE;
  1107. }
  1108. break;
  1109. case WM_DESTROY:
  1110. if (lpLP != NULL)
  1111. {
  1112. OleStdFree(lpLP->lpszDisplayName);
  1113. lpLP->lpszDisplayName = NULL;
  1114. }
  1115. StandardCleanup((PVOID)lpLP, hDlg);
  1116. return TRUE;
  1117. default:
  1118. if (lpOP != NULL && lpOP->lpPS->hwndParent && iMsg == uMsgBrowseOFN)
  1119. {
  1120. SendMessage(lpOP->lpPS->hwndParent, uMsgBrowseOFN, wParam, lParam);
  1121. }
  1122. break;
  1123. }
  1124. return FALSE;
  1125. }
  1126. /////////////////////////////////////////////////////////////////////////////
  1127. // Property Page initialization code
  1128. struct PROPPAGEDATA
  1129. {
  1130. UINT nTemplateID;
  1131. UINT nTemplateID4;
  1132. DLGPROC pfnDlgProc;
  1133. size_t nPtrOffset;
  1134. };
  1135. #define PTR_OFFSET(x) offsetof(OLEUIOBJECTPROPS, x)
  1136. static PROPPAGEDATA pageData[3] =
  1137. {
  1138. { IDD_GNRLPROPS,IDD_GNRLPROPS4, GnrlPropsDialogProc, PTR_OFFSET(lpGP), },
  1139. { IDD_VIEWPROPS,IDD_VIEWPROPS, ViewPropsDialogProc, PTR_OFFSET(lpVP), },
  1140. { IDD_LINKPROPS,IDD_LINKPROPS4, LinkPropsDialogProc, PTR_OFFSET(lpLP), },
  1141. };
  1142. #undef PTR_OFFSET
  1143. static UINT WINAPI PrepareObjectProperties(LPOLEUIOBJECTPROPS lpOP)
  1144. {
  1145. // setup back pointers from page structs to sheet structs
  1146. lpOP->lpGP->lpOP = lpOP;
  1147. lpOP->lpVP->lpOP = lpOP;
  1148. if ((lpOP->dwFlags & OPF_OBJECTISLINK) && lpOP->lpLP != NULL)
  1149. lpOP->lpLP->lpOP = lpOP;
  1150. // pre-init GNRLPROPS struct
  1151. LPOLEUIGNRLPROPS lpGP = lpOP->lpGP;
  1152. // get ready to initialize PROPSHEET structs
  1153. LPPROPSHEETHEADER lpPS = lpOP->lpPS;
  1154. LPPROPSHEETPAGE lpPPs = (LPPROPSHEETPAGE)lpPS->ppsp;
  1155. UINT nMaxPage = (lpOP->dwFlags & OPF_OBJECTISLINK ? 3 : 2);
  1156. // setting OPF_NOFILLDEFAULT allows you to control almost everything
  1157. if (!(lpOP->dwFlags & OPF_NOFILLDEFAULT))
  1158. {
  1159. // get array of 3 PROPSHEETPAGE structs if not provided
  1160. if (lpPS->ppsp == NULL)
  1161. {
  1162. lpPS->nPages = nMaxPage;
  1163. lpPPs = (LPPROPSHEETPAGE)
  1164. OleStdMalloc(nMaxPage * sizeof(PROPSHEETPAGE));
  1165. if (lpPPs == NULL)
  1166. return OLEUI_ERR_OLEMEMALLOC;
  1167. memset(lpPPs, 0, nMaxPage * sizeof(PROPSHEETPAGE));
  1168. lpPS->ppsp = lpPPs;
  1169. }
  1170. // fill in defaults for lpPS
  1171. lpPS->dwFlags |= PSH_PROPSHEETPAGE;
  1172. if (lpPS->hInstance == NULL)
  1173. lpPS->hInstance = _g_hOleStdResInst;
  1174. // fill Defaults for Standard Property Pages
  1175. LPPROPSHEETPAGE lpPP = lpPPs;
  1176. for (UINT nPage = 0; nPage < nMaxPage; nPage++)
  1177. {
  1178. PROPPAGEDATA* pPageData = &pageData[nPage];
  1179. if (lpPP->dwSize == 0)
  1180. lpPP->dwSize = sizeof(PROPSHEETPAGE);
  1181. if (lpPP->hInstance == NULL)
  1182. lpPP->hInstance = _g_hOleStdResInst;
  1183. UINT nIDD = bWin4 ?
  1184. pPageData->nTemplateID4 : pPageData->nTemplateID;
  1185. if (lpPP->pszTemplate == NULL)
  1186. lpPP->pszTemplate = MAKEINTRESOURCE(nIDD);
  1187. lpPP = (LPPROPSHEETPAGE)((LPBYTE)lpPP+lpPP->dwSize);
  1188. }
  1189. }
  1190. // fill Property Page info which cannot be overridden
  1191. LPPROPSHEETPAGE lpPP = lpPPs;
  1192. for (UINT nPage = 0; nPage < nMaxPage; nPage++)
  1193. {
  1194. PROPPAGEDATA* pPageData = &pageData[nPage];
  1195. lpPP->pfnDlgProc = pPageData->pfnDlgProc;
  1196. lpPP->lParam = (LPARAM)
  1197. *(OLEUIGNRLPROPS**)((LPBYTE)lpOP + pPageData->nPtrOffset);
  1198. lpPP = (LPPROPSHEETPAGE)((LPBYTE)lpPP+lpPP->dwSize);
  1199. }
  1200. return OLEUI_SUCCESS;
  1201. }
  1202. /////////////////////////////////////////////////////////////////////////////