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.

764 lines
26 KiB

  1. /*
  2. * COMMON.CPP
  3. *
  4. * Standardized (and centralized) pieces of each OLEDLG dialog function:
  5. *
  6. * UStandardValidation Validates standard fields in each dialog structure
  7. * UStandardInvocation Invokes a dialog through DialogBoxIndirectParam
  8. * LpvStandardInit Common WM_INITDIALOG processing
  9. * LpvStandardEntry Common code to execute on dialog proc entry.
  10. * UStandardHook Centralized hook calling function.
  11. * StandardCleanup Common exit/cleanup code.
  12. * StandardShowDlgItem Show-Enable/Hide-Disable dialog item
  13. * StandardEnableDlgItem Enable/Disable dialog item
  14. * StandardResizeDlgY Resize dialog to fit controls
  15. *
  16. * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  17. */
  18. #include "precomp.h"
  19. #include "common.h"
  20. #include "utility.h"
  21. OLEDBGDATA
  22. /*
  23. * UStandardValidation
  24. *
  25. * Purpose:
  26. * Performs validation on the standard pieces of any dialog structure,
  27. * that is, the fields defined in the OLEUISTANDARD structure.
  28. *
  29. * Parameters:
  30. * lpUI const LPOLEUISTANDARD pointing to the shared data of
  31. * all structs.
  32. * cbExpect const UINT structure size desired by the caller.
  33. * phDlgMem const HGLOBAL FAR * in which to store a loaded customized
  34. * template, if one exists.
  35. * (This may be NULL in which case the template pointer isn't
  36. * needed by the calling function and should be released.)
  37. *
  38. * Return Value:
  39. * UINT OLEUI_SUCCESS if all validation succeeded. Otherwise
  40. * it will be one of the standard error codes.
  41. */
  42. UINT WINAPI UStandardValidation(LPOLEUISTANDARD lpUI, const UINT cbExpect,
  43. HGLOBAL* phMemDlg)
  44. {
  45. /*
  46. * 1. Validate non-NULL pointer parameter. Note: We don't validate
  47. * phDlg since it's not passed from an external source.
  48. */
  49. if (NULL == lpUI)
  50. return OLEUI_ERR_STRUCTURENULL;
  51. // 2. Validate that the structure is readable and writable.
  52. if (IsBadWritePtr(lpUI, cbExpect))
  53. return OLEUI_ERR_STRUCTUREINVALID;
  54. // 3. Validate the structure size
  55. if (cbExpect != lpUI->cbStruct)
  56. return OLEUI_ERR_CBSTRUCTINCORRECT;
  57. // 4. Validate owner-window handle. NULL is considered valid.
  58. if (NULL != lpUI->hWndOwner && !IsWindow(lpUI->hWndOwner))
  59. return OLEUI_ERR_HWNDOWNERINVALID;
  60. // 5. Validate the dialog caption. NULL is considered valid.
  61. if (NULL != lpUI->lpszCaption && IsBadReadPtr(lpUI->lpszCaption, 1))
  62. return OLEUI_ERR_LPSZCAPTIONINVALID;
  63. // 6. Validate the hook pointer. NULL is considered valid.
  64. if (NULL != lpUI->lpfnHook && IsBadCodePtr((FARPROC)lpUI->lpfnHook))
  65. return OLEUI_ERR_LPFNHOOKINVALID;
  66. /*
  67. * 7. If hInstance is non-NULL, we have to also check lpszTemplate.
  68. * Otherwise, lpszTemplate is not used and requires no validation.
  69. * lpszTemplate cannot be NULL if used.
  70. */
  71. HGLOBAL hMem = NULL;
  72. if (NULL != lpUI->hInstance)
  73. {
  74. //Best we can try is one character
  75. if (NULL == lpUI->lpszTemplate || (HIWORD(PtrToUlong(lpUI->lpszTemplate)) != 0 &&
  76. IsBadReadPtr(lpUI->lpszTemplate, 1)))
  77. return OLEUI_ERR_LPSZTEMPLATEINVALID;
  78. HRSRC hRes = FindResource(lpUI->hInstance, lpUI->lpszTemplate, RT_DIALOG);
  79. if (NULL == hRes)
  80. return OLEUI_ERR_FINDTEMPLATEFAILURE;
  81. hMem = LoadResource(lpUI->hInstance, hRes);
  82. if (NULL == hMem)
  83. return OLEUI_ERR_LOADTEMPLATEFAILURE;
  84. }
  85. // 8. If hResource is non-NULL, be sure we can lock it.
  86. if (NULL != lpUI->hResource)
  87. {
  88. if ((LPSTR)NULL == LockResource(lpUI->hResource))
  89. return OLEUI_ERR_HRESOURCEINVALID;
  90. }
  91. /*
  92. * Here we have hMem==NULL if we should use the standard template
  93. * or the one in lpUI->hResource. If hMem is non-NULL, then we
  94. * loaded one from the calling application's resources which the
  95. * caller of this function has to free if it sees any other error.
  96. */
  97. if (NULL != phMemDlg)
  98. {
  99. *phMemDlg = hMem;
  100. }
  101. return OLEUI_SUCCESS;
  102. }
  103. /*
  104. * UStandardInvocation
  105. *
  106. * Purpose:
  107. * Provides standard template loading and calling on DialogBoxIndirectParam
  108. * for all the OLE UI dialogs.
  109. *
  110. * Parameters:
  111. * lpDlgProc DLGPROC of the dialog function.
  112. * lpUI LPOLEUISTANDARD containing the dialog structure.
  113. * hMemDlg HGLOBAL containing the dialog template. If this
  114. * is NULL and lpUI->hResource is NULL, then we load
  115. * the standard template given the name in lpszStdTemplate
  116. * lpszStdTemplate LPCSTR standard template to load if hMemDlg is NULL
  117. * and lpUI->hResource is NULL.
  118. *
  119. * Return Value:
  120. * UINT OLEUI_SUCCESS if all is well, otherwise and error
  121. * code.
  122. */
  123. UINT WINAPI UStandardInvocation(
  124. DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPTSTR lpszStdTemplate)
  125. {
  126. // Make sure we have a template, then lock it down
  127. HGLOBAL hTemplate = hMemDlg;
  128. if (NULL == hTemplate)
  129. hTemplate = lpUI->hResource;
  130. if (NULL == hTemplate)
  131. {
  132. HRSRC hRes = FindResource(_g_hOleStdResInst, (LPCTSTR) lpszStdTemplate, RT_DIALOG);
  133. if (NULL == hRes)
  134. return OLEUI_ERR_FINDTEMPLATEFAILURE;
  135. hTemplate = LoadResource(_g_hOleStdResInst, hRes);
  136. if (NULL == hTemplate)
  137. return OLEUI_ERR_LOADTEMPLATEFAILURE;
  138. }
  139. /*
  140. * hTemplate has the template to use, so now we can invoke the dialog.
  141. * Since we have exported all of our dialog procedures using the
  142. * _keyword, we do not need to call MakeProcInstance,
  143. * we can ue the dialog procedure address directly.
  144. */
  145. INT_PTR iRet = DialogBoxIndirectParam(_g_hOleStdResInst, (LPCDLGTEMPLATE)hTemplate,
  146. lpUI->hWndOwner, lpDlgProc, (LPARAM)lpUI);
  147. if (-1 == iRet)
  148. return OLEUI_ERR_DIALOGFAILURE;
  149. // Return the code from EndDialog, generally OLEUI_OK or OLEUI_CANCEL
  150. return (UINT)iRet;
  151. }
  152. /*
  153. * LpvStandardInit
  154. *
  155. * Purpose:
  156. * Default actions for WM_INITDIALOG handling in the dialog, allocating
  157. * a dialog-specific structure, setting that memory as a dialog property,
  158. * and creating a small font if necessary setting that font as a property.
  159. *
  160. * Parameters:
  161. * hDlg HWND of the dialog
  162. * cbStruct UINT size of dialog-specific structure to allocate.
  163. * fCreateFont BOOL indicating if we need to create a small Helv
  164. * font for this dialog.
  165. * phFont HFONT FAR * in which to place a created font. Can be
  166. * NULL if fCreateFont is FALSE.
  167. *
  168. * Return Value:
  169. * LPVOID Pointer to global memory allocated for the dialog.
  170. * The memory will have been set as a dialog property
  171. * using the STRUCTUREPROP label.
  172. */
  173. LPVOID WINAPI LpvStandardInit(HWND hDlg, UINT cbStruct, HFONT* phFont)
  174. {
  175. // Must have at least sizeof(void*) bytes in cbStruct
  176. if (sizeof(void*) > cbStruct)
  177. {
  178. PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
  179. return NULL;
  180. }
  181. HGLOBAL gh = GlobalAlloc(GHND, cbStruct);
  182. if (NULL == gh)
  183. {
  184. PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
  185. return NULL;
  186. }
  187. LPVOID lpv = GlobalLock(gh);
  188. SetProp(hDlg, STRUCTUREPROP, gh);
  189. if (phFont != NULL)
  190. *phFont = NULL;
  191. if (!bWin4 && phFont != NULL)
  192. {
  193. // Create the non-bold font for result and file texts. We call
  194. HFONT hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
  195. LOGFONT lf;
  196. GetObject(hFont, sizeof(LOGFONT), &lf);
  197. lf.lfWeight = FW_NORMAL;
  198. // Attempt to create the font. If this fails, then we return no font.
  199. *phFont = CreateFontIndirect(&lf);
  200. // If we couldn't create the font, we'll do with the default.
  201. if (NULL != *phFont)
  202. SetProp(hDlg, FONTPROP, (HANDLE)*phFont);
  203. }
  204. // Setup the context help mode (WS_EX_CONTEXTHELP)
  205. if (bWin4)
  206. {
  207. DWORD dwExStyle = GetWindowLong(hDlg, GWL_EXSTYLE);
  208. dwExStyle |= WS_EX_CONTEXTHELP;
  209. SetWindowLong(hDlg, GWL_EXSTYLE, dwExStyle);
  210. }
  211. return lpv;
  212. }
  213. typedef struct COMMON
  214. {
  215. OLEUISTANDARD* pStandard;
  216. UINT nIDD;
  217. } COMMON, *PCOMMON, FAR* LPCOMMON;
  218. /*
  219. * LpvStandardEntry
  220. *
  221. * Purpose:
  222. * Retrieves the dialog's structure property and calls the hook
  223. * as necessary. This should be called on entry into all dialog
  224. * procedures.
  225. *
  226. * Parameters:
  227. * hDlg HWND of the dialog
  228. * iMsg UINT message to the dialog
  229. * wParam, lParam WPARAM, LPARAM message parameters
  230. * puHookResult UINT FAR * in which this function stores the return value
  231. * from the hook if it is called. If no hook is available,
  232. * this will be FALSE.
  233. *
  234. * Return Value:
  235. * LPVOID Pointer to the dialog's extra structure held in the
  236. * STRUCTUREPROP property.
  237. */
  238. // char szDebug[100];
  239. LPVOID WINAPI LpvStandardEntry(HWND hDlg, UINT iMsg,
  240. WPARAM wParam, LPARAM lParam, UINT FAR * puHookResult)
  241. {
  242. // This will fail under WM_INITDIALOG, where we allocate using StandardInit
  243. LPVOID lpv = NULL;
  244. HGLOBAL gh = GetProp(hDlg, STRUCTUREPROP);
  245. if (NULL != puHookResult && NULL != gh)
  246. {
  247. *puHookResult = 0;
  248. // gh was locked previously, lock and unlock to get lpv
  249. lpv = GlobalLock(gh);
  250. GlobalUnlock(gh);
  251. // Call the hook for all messages except WM_INITDIALOG
  252. if (NULL != lpv && WM_INITDIALOG != iMsg)
  253. *puHookResult = UStandardHook(lpv, hDlg, iMsg, wParam, lParam);
  254. // Default processing for various messages
  255. LPCOMMON lpCommon = (LPCOMMON)lpv;
  256. if (*puHookResult == 0 && NULL != lpv)
  257. {
  258. switch (iMsg)
  259. {
  260. // handle standard Win4 help messages
  261. case WM_HELP:
  262. {
  263. HWND hWndChild = (HWND)((LPHELPINFO)lParam)->hItemHandle;
  264. //skip read-only controls (requested by Help folks)
  265. //basically the help strings for items like ObjectName on GnrlProps
  266. //give useless information.
  267. //If we do not make this check now the other option is to turn ON
  268. //the #if 0 inside the switch. That is ugly.
  269. if (hWndChild!=hDlg )
  270. {
  271. int iCtrlId = ((LPHELPINFO)lParam)->iCtrlId;
  272. // wsprintfA(szDebug,"\n @@@ hWnd= %lx, hChld = %lx, ctrlId = %d ", hDlg, hWndChild, iCtrlId);
  273. // OutputDebugStringA(szDebug);
  274. switch (iCtrlId)
  275. {
  276. // list of control IDs that should not have help
  277. case -1: //IDC_STATIC
  278. case 0xffff: //IDC_STATIC
  279. case IDC_CI_GROUP:
  280. case IDC_GP_OBJECTICON:
  281. break;
  282. default:
  283. StandardHelp(hWndChild, lpCommon->nIDD);
  284. }
  285. }
  286. *puHookResult = TRUE; //We handled the message.
  287. break;
  288. } //case WM_HELP
  289. case WM_CONTEXTMENU:
  290. {
  291. POINT pt;
  292. int iCtrlId;
  293. HWND hwndChild = NULL;
  294. if( hDlg == (HWND) wParam )
  295. {
  296. GetCursorPos(&pt);
  297. ScreenToClient(hDlg, &pt);
  298. hwndChild = ChildWindowFromPointEx(hDlg, pt,
  299. CWP_SKIPINVISIBLE);
  300. //hWndChild will now be either hDlg or hWnd of the ctrl
  301. }
  302. if ( hwndChild != hDlg )
  303. {
  304. if (hwndChild)
  305. {
  306. iCtrlId = GetDlgCtrlID(hwndChild);
  307. }
  308. else
  309. {
  310. iCtrlId = GetDlgCtrlID((HWND)wParam);
  311. }
  312. // wsprintfA(szDebug, "\n ### hWnd= %lx, hChld = %lx, ctrlId = %d ", hDlg, hwndChild, iCtrlId);
  313. // OutputDebugStringA(szDebug);
  314. switch (iCtrlId)
  315. {
  316. // list of control IDs that should not have help
  317. case -1: // IDC_STATIC
  318. case 0xffff: // IDC_STATIC
  319. case IDC_CI_GROUP:
  320. case IDC_GP_OBJECTICON:
  321. break;
  322. default:
  323. StandardContextMenu(wParam, lParam, lpCommon->nIDD);
  324. }
  325. }
  326. *puHookResult = TRUE; //We handled the message.
  327. break;
  328. } // case WM_CONTEXTMENU
  329. case WM_CTLCOLOREDIT:
  330. {
  331. // make readonly edits have gray background
  332. if (bWin4 && (GetWindowLong((HWND)lParam, GWL_STYLE)
  333. & ES_READONLY))
  334. {
  335. *puHookResult = (UINT)SendMessage(hDlg, WM_CTLCOLORSTATIC, wParam, lParam);
  336. }
  337. break;
  338. }
  339. } //switch (iMsg)
  340. } //*puHookResult == 0
  341. } //NULL != puHookResult
  342. return lpv;
  343. }
  344. /*
  345. * UStandardHook
  346. *
  347. * Purpose:
  348. * Provides a generic hook calling function assuming that all private
  349. * dialog structures have a far pointer to their assocated public
  350. * structure as the first field, and that the first part of the public
  351. * structure matches an OLEUISTANDARD.
  352. *
  353. * Parameters:
  354. * pv PVOID to the dialog structure.
  355. * hDlg HWND to send with the call to the hook.
  356. * iMsg UINT message to send to the hook.
  357. * wParam, lParam WPARAM, LPARAM message parameters
  358. *
  359. * Return Value:
  360. * UINT Return value from the hook, zero to indicate that
  361. * default action should occur, nonzero to specify
  362. * that the hook did process the message. In some
  363. * circumstances it will be important for the hook to
  364. * return a non-trivial non-zero value here, such as
  365. * a brush from WM_CTLCOLOR, in which case the caller
  366. * should return that value from the dialog procedure.
  367. */
  368. UINT WINAPI UStandardHook(LPVOID lpv, HWND hDlg, UINT iMsg,
  369. WPARAM wParam, LPARAM lParam)
  370. {
  371. UINT uRet = 0;
  372. LPOLEUISTANDARD lpUI = *((LPOLEUISTANDARD FAR *)lpv);
  373. if (NULL != lpUI && NULL != lpUI->lpfnHook)
  374. {
  375. /*
  376. * In order for the hook to have the proper DS, they should be
  377. * compiling with -GA -GEs so and usin __to get everything
  378. * set up properly.
  379. */
  380. uRet = (*lpUI->lpfnHook)(hDlg, iMsg, wParam, lParam);
  381. }
  382. return uRet;
  383. }
  384. /*
  385. * StandardCleanup
  386. *
  387. * Purpose:
  388. * Removes properties and reverses any other standard initiazation
  389. * done through StandardSetup.
  390. *
  391. * Parameters:
  392. * lpv LPVOID containing the private dialog structure.
  393. * hDlg HWND of the dialog closing.
  394. *
  395. * Return Value:
  396. * None
  397. */
  398. void WINAPI StandardCleanup(LPVOID lpv, HWND hDlg)
  399. {
  400. HFONT hFont=(HFONT)RemoveProp(hDlg, FONTPROP);
  401. if (NULL != hFont)
  402. {
  403. DeleteObject(hFont);
  404. }
  405. HGLOBAL gh = RemoveProp(hDlg, STRUCTUREPROP);
  406. if (gh != NULL)
  407. {
  408. GlobalUnlock(gh);
  409. GlobalFree(gh);
  410. }
  411. }
  412. /* StandardShowDlgItem
  413. * -------------------
  414. * Show & Enable or Hide & Disable a dialog item as appropriate.
  415. * it is NOT sufficient to simply hide the item; it must be disabled
  416. * too or the keyboard accelerator still functions.
  417. */
  418. void WINAPI StandardShowDlgItem(HWND hDlg, int idControl, int nCmdShow)
  419. {
  420. HWND hItem = GetDlgItem(hDlg, idControl);
  421. if (hItem != NULL)
  422. {
  423. ShowWindow(hItem, nCmdShow);
  424. EnableWindow(hItem, nCmdShow != SW_HIDE);
  425. }
  426. }
  427. /* StandardEnableDlgItem
  428. * -------------------
  429. * Enable/Disable a dialog item. If the item does not exist
  430. * this call is a noop.
  431. */
  432. void WINAPI StandardEnableDlgItem(HWND hDlg, int idControl, BOOL bEnable)
  433. {
  434. HWND hItem = GetDlgItem(hDlg, idControl);
  435. if (hItem != NULL)
  436. EnableWindow(hItem, bEnable);
  437. }
  438. /* StandardResizeDlgY
  439. * ------------------
  440. * Resize a dialog to fit around the visible controls. This is used
  441. * for dialogs which remove controls from the bottom of the dialogs.
  442. * A good example of this is the convert dialog, which when CF_HIDERESULTS
  443. * is selected, removes the "results box" at the bottom of the dialog.
  444. * This implementation currently
  445. */
  446. BOOL WINAPI StandardResizeDlgY(HWND hDlg)
  447. {
  448. RECT rect;
  449. // determine maxY by looking at all child windows on the dialog
  450. int maxY = 0;
  451. HWND hChild = GetWindow(hDlg, GW_CHILD);
  452. while (hChild != NULL)
  453. {
  454. if (GetWindowLong(hChild, GWL_STYLE) & WS_VISIBLE)
  455. {
  456. GetWindowRect(hChild, &rect);
  457. if (rect.bottom > maxY)
  458. maxY = rect.bottom;
  459. }
  460. hChild = GetWindow(hChild, GW_HWNDNEXT);
  461. }
  462. if (maxY > 0)
  463. {
  464. // get current font that the dialog is using
  465. HFONT hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0);
  466. if (hFont == NULL)
  467. hFont = (HFONT)GetStockObject(SYSTEM_FONT);
  468. OleDbgAssert(hFont != NULL);
  469. // calculate height of the font in pixels
  470. HDC hDC = GetDC(NULL);
  471. hFont = (HFONT)SelectObject(hDC, hFont);
  472. TEXTMETRIC tm;
  473. GetTextMetrics(hDC, &tm);
  474. SelectObject(hDC, hFont);
  475. ReleaseDC(NULL, hDC);
  476. // determine if window is too large and resize if necessary
  477. GetWindowRect(hDlg, &rect);
  478. if (rect.bottom > maxY + tm.tmHeight)
  479. {
  480. // window is too large -- resize it
  481. rect.bottom = maxY + tm.tmHeight;
  482. SetWindowPos(hDlg, NULL,
  483. 0, 0, rect.right-rect.left, rect.bottom-rect.top,
  484. SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
  485. return TRUE;
  486. }
  487. }
  488. return FALSE;
  489. }
  490. /////////////////////////////////////////////////////////////////////////////
  491. // Support for Windows 95 help
  492. #define HELPFILE TEXT("mfcuix.hlp")
  493. LPDWORD LoadHelpInfo(UINT nIDD)
  494. {
  495. HRSRC hrsrc = FindResource(_g_hOleStdResInst, MAKEINTRESOURCE(nIDD),
  496. MAKEINTRESOURCE(RT_HELPINFO));
  497. if (hrsrc == NULL)
  498. return NULL;
  499. HGLOBAL hHelpInfo = LoadResource(_g_hOleStdResInst, hrsrc);
  500. if (hHelpInfo == NULL)
  501. return NULL;
  502. LPDWORD lpdwHelpInfo = (LPDWORD)LockResource(hHelpInfo);
  503. return lpdwHelpInfo;
  504. }
  505. void WINAPI StandardHelp(HWND hWnd, UINT nIDD)
  506. {
  507. LPDWORD lpdwHelpInfo = LoadHelpInfo(nIDD);
  508. if (lpdwHelpInfo == NULL)
  509. {
  510. OleDbgOut1(TEXT("Warning: unable to load help information (RT_HELPINFO)\n"));
  511. return;
  512. }
  513. /*
  514. int id=GetDlgCtrlID( hWnd);
  515. wsprintfA(szDebug,"\n HH @@@### hWnd= %lx, ctrlId = %d %lx", hWnd,id,id);
  516. OutputDebugStringA(szDebug);
  517. */
  518. WinHelp(hWnd, HELPFILE, HELP_WM_HELP, (ULONG_PTR)lpdwHelpInfo);
  519. }
  520. void WINAPI StandardContextMenu(WPARAM wParam, LPARAM, UINT nIDD)
  521. {
  522. LPDWORD lpdwHelpInfo = LoadHelpInfo(nIDD);
  523. if (lpdwHelpInfo == NULL)
  524. {
  525. OleDbgOut1(TEXT("Warning: unable to load help information (RT_HELPINFO)\n"));
  526. return;
  527. }
  528. /*
  529. int id=GetDlgCtrlID((HWND)wParam);
  530. wsprintfA(szDebug,"\n CC $$$*** hWnd= %lx, ctrlId = %d %lx ",(HWND)wParam,id,id);
  531. OutputDebugStringA(szDebug);
  532. */
  533. WinHelp((HWND)wParam, HELPFILE, HELP_CONTEXTMENU, (ULONG_PTR)lpdwHelpInfo);
  534. }
  535. /////////////////////////////////////////////////////////////////////////////
  536. // StandardPropertySheet (stub for Windows 95 API PropertySheet)
  537. typedef void (WINAPI* LPFNINITCOMMONCONTROLS)(VOID);
  538. int WINAPI StandardInitCommonControls()
  539. {
  540. TASKDATA* pTaskData = GetTaskData();
  541. OleDbgAssert(pTaskData != NULL);
  542. if (pTaskData->hInstCommCtrl == NULL)
  543. {
  544. pTaskData->hInstCommCtrl = LoadLibrary(TEXT("comctl32.dll"));
  545. if (pTaskData->hInstCommCtrl == NULL)
  546. goto Error;
  547. LPFNINITCOMMONCONTROLS lpfnInitCommonControls = (LPFNINITCOMMONCONTROLS)
  548. GetProcAddress(pTaskData->hInstCommCtrl, "InitCommonControls");
  549. if (lpfnInitCommonControls == NULL)
  550. goto ErrorFreeLibrary;
  551. (*lpfnInitCommonControls)();
  552. }
  553. return 0;
  554. ErrorFreeLibrary:
  555. if (pTaskData->hInstCommCtrl != NULL)
  556. {
  557. FreeLibrary(pTaskData->hInstCommCtrl);
  558. pTaskData->hInstCommCtrl = NULL;
  559. }
  560. Error:
  561. return -1;
  562. }
  563. typedef int (WINAPI* LPFNPROPERTYSHEET)(LPCPROPSHEETHEADER);
  564. int WINAPI StandardPropertySheet(LPPROPSHEETHEADER lpPS, BOOL fWide)
  565. {
  566. int nResult = StandardInitCommonControls();
  567. if (nResult < 0)
  568. return nResult;
  569. TASKDATA* pTaskData = GetTaskData();
  570. OleDbgAssert(pTaskData != NULL);
  571. LPFNPROPERTYSHEET lpfnPropertySheet;
  572. if (fWide)
  573. {
  574. lpfnPropertySheet = (LPFNPROPERTYSHEET)GetProcAddress(pTaskData->hInstCommCtrl, "PropertySheetW");
  575. }
  576. else
  577. {
  578. lpfnPropertySheet = (LPFNPROPERTYSHEET)GetProcAddress(pTaskData->hInstCommCtrl, "PropertySheetA");
  579. }
  580. if (lpfnPropertySheet == NULL)
  581. return -1;
  582. nResult = (*lpfnPropertySheet)(lpPS);
  583. return nResult;
  584. }
  585. typedef HICON (WINAPI* LPFNEXTRACTICON)(HINSTANCE, LPCTSTR, UINT);
  586. HICON StandardExtractIcon(HINSTANCE hInst, LPCTSTR lpszExeFileName, UINT nIconIndex)
  587. {
  588. TASKDATA* pTaskData = GetTaskData();
  589. OleDbgAssert(pTaskData != NULL);
  590. LPFNEXTRACTICON lpfnExtractIcon;
  591. if (pTaskData->hInstShell == NULL)
  592. {
  593. pTaskData->hInstShell = LoadLibrary(TEXT("shell32.dll"));
  594. if (pTaskData->hInstShell == NULL)
  595. goto Error;
  596. }
  597. lpfnExtractIcon = (LPFNEXTRACTICON)
  598. #ifdef UNICODE
  599. GetProcAddress(pTaskData->hInstShell, "ExtractIconW");
  600. #else
  601. GetProcAddress(pTaskData->hInstShell, "ExtractIconA");
  602. #endif
  603. if (lpfnExtractIcon == NULL)
  604. goto ErrorFreeLibrary;
  605. return (*lpfnExtractIcon)(hInst, lpszExeFileName, nIconIndex);
  606. ErrorFreeLibrary:
  607. if (pTaskData->hInstShell != NULL)
  608. {
  609. FreeLibrary(pTaskData->hInstShell);
  610. pTaskData->hInstShell = NULL;
  611. }
  612. Error:
  613. return NULL;
  614. }
  615. typedef BOOL (WINAPI* LPFNGETOPENFILENAME)(LPOPENFILENAME);
  616. BOOL StandardGetOpenFileName(LPOPENFILENAME lpofn)
  617. {
  618. TASKDATA* pTaskData = GetTaskData();
  619. OleDbgAssert(pTaskData != NULL);
  620. LPFNGETOPENFILENAME lpfnGetOpenFileName;
  621. if (pTaskData->hInstComDlg == NULL)
  622. {
  623. pTaskData->hInstComDlg = LoadLibrary(TEXT("comdlg32.dll"));
  624. if (pTaskData->hInstComDlg == NULL)
  625. goto Error;
  626. }
  627. lpfnGetOpenFileName = (LPFNGETOPENFILENAME)
  628. #ifdef UNICODE
  629. GetProcAddress(pTaskData->hInstComDlg, "GetOpenFileNameW");
  630. #else
  631. GetProcAddress(pTaskData->hInstComDlg, "GetOpenFileNameA");
  632. #endif
  633. if (lpfnGetOpenFileName == NULL)
  634. goto ErrorFreeLibrary;
  635. return (*lpfnGetOpenFileName)(lpofn);
  636. ErrorFreeLibrary:
  637. if (pTaskData->hInstComDlg != NULL)
  638. {
  639. FreeLibrary(pTaskData->hInstComDlg);
  640. pTaskData->hInstComDlg = NULL;
  641. }
  642. Error:
  643. return FALSE;
  644. }
  645. typedef short (WINAPI* LPFNGETFILETITLE)(LPCTSTR, LPTSTR, WORD);
  646. short StandardGetFileTitle(LPCTSTR lpszFile, LPTSTR lpszTitle, WORD cbBuf)
  647. {
  648. TASKDATA* pTaskData = GetTaskData();
  649. OleDbgAssert(pTaskData != NULL);
  650. LPFNGETFILETITLE lpfnGetFileTitle;
  651. if (pTaskData->hInstComDlg == NULL)
  652. {
  653. pTaskData->hInstComDlg = LoadLibrary(TEXT("comdlg32.dll"));
  654. if (pTaskData->hInstComDlg == NULL)
  655. goto Error;
  656. }
  657. lpfnGetFileTitle = (LPFNGETFILETITLE)
  658. #ifdef UNICODE
  659. GetProcAddress(pTaskData->hInstComDlg, "GetFileTitleW");
  660. #else
  661. GetProcAddress(pTaskData->hInstComDlg, "GetFileTitleA");
  662. #endif
  663. if (lpfnGetFileTitle == NULL)
  664. goto ErrorFreeLibrary;
  665. return (*lpfnGetFileTitle)(lpszFile, lpszTitle, cbBuf);
  666. ErrorFreeLibrary:
  667. if (pTaskData->hInstComDlg != NULL)
  668. {
  669. FreeLibrary(pTaskData->hInstComDlg);
  670. pTaskData->hInstComDlg = NULL;
  671. }
  672. Error:
  673. return -1;
  674. }