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.

423 lines
12 KiB

  1. /*
  2. * COMMON.C
  3. *
  4. * Standardized (and centralized) pieces of each OLE2UI dialog function:
  5. * UStandardValidation Validates standard fields in each dialog structure
  6. * UStandardInvocation Invokes a dialog through DialogBoxIndirectParam
  7. * LpvStandardInit Common WM_INITDIALOG processing
  8. * LpvStandardEntry Common code to execute on dialog proc entry.
  9. * FStandardHook Centralized hook calling function.
  10. * StandardCleanup Common exit/cleanup code.
  11. * OleUIShowDlgItem Show-Enable/Hide-Disable dialog item
  12. *
  13. * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  14. */
  15. #define STRICT 1
  16. #include "ole2ui.h"
  17. #include "common.h"
  18. #include "utility.h"
  19. #include <malloc.h>
  20. /*
  21. * UStandardValidation
  22. *
  23. * Purpose:
  24. * Performs validation on the standard pieces of any dialog structure,
  25. * that is, the fields defined in the OLEUISTANDARD structure.
  26. *
  27. * Parameters:
  28. * lpUI const LPOLEUISTANDARD pointing to the shared data of
  29. * all structs.
  30. * cbExpect const UINT structure size desired by the caller.
  31. * phDlgMem const HGLOBAL FAR * in which to store a loaded customized
  32. * template, if one exists.
  33. *
  34. * Return Value:
  35. * UINT OLEUI_SUCCESS if all validation succeeded. Otherwise
  36. * it will be one of the standard error codes.
  37. */
  38. UINT WINAPI UStandardValidation(const LPOLEUISTANDARD lpUI, const UINT cbExpect
  39. , const HGLOBAL FAR *phMemDlg)
  40. {
  41. HRSRC hRes=NULL;
  42. HGLOBAL hMem=NULL;
  43. /*
  44. * 1. Validate non-NULL pointer parameter. Note: We don't validate
  45. * phDlg since it's not passed from an external source.
  46. */
  47. if (NULL==lpUI)
  48. return OLEUI_ERR_STRUCTURENULL;
  49. //2. Validate that the structure is readable and writable.
  50. if (IsBadReadPtr(lpUI, cbExpect) || IsBadWritePtr(lpUI, cbExpect))
  51. return OLEUI_ERR_STRUCTUREINVALID;
  52. //3. Validate the structure size
  53. if (cbExpect!=lpUI->cbStruct)
  54. return OLEUI_ERR_CBSTRUCTINCORRECT;
  55. //4. Validate owner-window handle. NULL is considered valid.
  56. if (NULL!=lpUI->hWndOwner && !IsWindow(lpUI->hWndOwner))
  57. return OLEUI_ERR_HWNDOWNERINVALID;
  58. //5. Validate the dialog caption. NULL is considered valid.
  59. if (NULL!=lpUI->lpszCaption && IsBadReadPtr(lpUI->lpszCaption, 1))
  60. return OLEUI_ERR_LPSZCAPTIONINVALID;
  61. //6. Validate the hook pointer. NULL is considered valid.
  62. if ((LPFNOLEUIHOOK)NULL!=lpUI->lpfnHook
  63. && IsBadCodePtr((FARPROC)lpUI->lpfnHook))
  64. return OLEUI_ERR_LPFNHOOKINVALID;
  65. /*
  66. * 7. If hInstance is non-NULL, we have to also check lpszTemplate.
  67. * Otherwise, lpszTemplate is not used and requires no validation.
  68. * lpszTemplate cannot be NULL if used.
  69. */
  70. if (NULL!=lpUI->hInstance)
  71. {
  72. //Best we can try is one character
  73. if (NULL==lpUI->lpszTemplate || IsBadReadPtr(lpUI->lpszTemplate, 1))
  74. return OLEUI_ERR_LPSZTEMPLATEINVALID;
  75. hRes=FindResource(lpUI->hInstance, lpUI->lpszTemplate, RT_DIALOG);
  76. //This is the only thing that catches invalid non-NULL hInstance
  77. if (NULL==hRes)
  78. return OLEUI_ERR_FINDTEMPLATEFAILURE;
  79. hMem=LoadResource(lpUI->hInstance, hRes);
  80. if (NULL==hMem)
  81. return OLEUI_ERR_LOADTEMPLATEFAILURE;
  82. }
  83. //8. If hResource is non-NULL, be sure we can lock it.
  84. if (NULL!=lpUI->hResource)
  85. {
  86. if ((LPSTR)NULL==GlobalLock(lpUI->hResource))
  87. return OLEUI_ERR_HRESOURCEINVALID;
  88. GlobalUnlock(lpUI->hResource);
  89. }
  90. /*
  91. * Here we have hMem==NULL if we should use the standard template
  92. * or the one in lpUI->hResource. If hMem is non-NULL, then we
  93. * loaded one from the calling application's resources which the
  94. * caller of this function has to free if it sees any other error.
  95. */
  96. *(HGLOBAL FAR *)phMemDlg=hMem;
  97. return OLEUI_SUCCESS;
  98. }
  99. /*
  100. * UStandardInvocation
  101. *
  102. * Purpose:
  103. * Provides standard template loading and calling on DialogBoxIndirectParam
  104. * for all the OLE UI dialogs.
  105. *
  106. * Parameters:
  107. * lpDlgProc DLGPROC of the dialog function.
  108. * lpUI LPOLEUISTANDARD containing the dialog structure.
  109. * hMemDlg HGLOBAL containing the dialog template. If this
  110. * is NULL and lpUI->hResource is NULL, then we load
  111. * the standard template given the name in lpszStdTemplate
  112. * lpszStdTemplate LPCSTR standard template to load if hMemDlg is NULL
  113. * and lpUI->hResource is NULL.
  114. *
  115. * Return Value:
  116. * UINT OLEUI_SUCCESS if all is well, otherwise and error
  117. * code.
  118. */
  119. UINT WINAPI UStandardInvocation
  120. #ifdef WIN32
  121. (DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPTSTR lpszStdTemplate)
  122. #else
  123. (DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPCTSTR lpszStdTemplate)
  124. #endif
  125. {
  126. HGLOBAL hTemplate=hMemDlg;
  127. HRSRC hRes;
  128. int iRet;
  129. //Make sure we have a template, then lock it down
  130. if (NULL==hTemplate)
  131. hTemplate=lpUI->hResource;
  132. if (NULL==hTemplate)
  133. {
  134. hRes=FindResource(ghInst, (LPCTSTR) lpszStdTemplate, RT_DIALOG);
  135. if (NULL==hRes)
  136. {
  137. return OLEUI_ERR_FINDTEMPLATEFAILURE;
  138. }
  139. hTemplate=LoadResource(ghInst, hRes);
  140. if (NULL==hTemplate)
  141. {
  142. return OLEUI_ERR_LOADTEMPLATEFAILURE;
  143. }
  144. }
  145. /*
  146. * hTemplate has the template to use, so now we can invoke the dialog.
  147. * Since we have exported all of our dialog procedures using the
  148. * _export keyword, we do not need to call MakeProcInstance,
  149. * we can ue the dialog procedure address directly.
  150. */
  151. iRet=DialogBoxIndirectParam(ghInst, hTemplate, lpUI->hWndOwner
  152. , lpDlgProc, (LPARAM)lpUI);
  153. /*
  154. * Cleanup the template if we explicitly loaded it. Caller is
  155. * responsible for already loaded template resources.
  156. */
  157. if (hTemplate!=lpUI->hResource)
  158. FreeResource(hTemplate);
  159. if (-1==iRet)
  160. return OLEUI_ERR_DIALOGFAILURE;
  161. //Return the code from EndDialog, generally OLEUI_OK or OLEUI_CANCEL
  162. return (UINT)iRet;
  163. }
  164. /*
  165. * LpvStandardInit
  166. *
  167. * Purpose:
  168. * Default actions for WM_INITDIALOG handling in the dialog, allocating
  169. * a dialog-specific structure, setting that memory as a dialog property,
  170. * and creating a small font if necessary setting that font as a property.
  171. *
  172. * Parameters:
  173. * hDlg HWND of the dialog
  174. * cbStruct UINT size of dialog-specific structure to allocate.
  175. * fCreateFont BOOL indicating if we need to create a small Helv
  176. * font for this dialog.
  177. * phFont HFONT FAR * in which to place a created font. Can be
  178. * NULL if fCreateFont is FALSE.
  179. *
  180. * Return Value:
  181. * LPVOID Pointer to global memory allocated for the dialog.
  182. * The memory will have been set as a dialog property
  183. * using the STRUCTUREPROP label.
  184. */
  185. LPVOID WINAPI LpvStandardInit(HWND hDlg, UINT cbStruct, BOOL fCreateFont, HFONT FAR * phFont)
  186. {
  187. LPVOID lpv;
  188. HFONT hFont;
  189. LOGFONT lf;
  190. HGLOBAL gh;
  191. //Must have at least sizeof(OLEUISTANDARD) bytes in cbStruct
  192. if (sizeof(OLEUISTANDARD) > cbStruct || (fCreateFont && NULL==phFont))
  193. {
  194. PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
  195. return NULL;
  196. }
  197. gh=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, cbStruct);
  198. if (NULL==gh)
  199. {
  200. PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
  201. return NULL;
  202. }
  203. lpv = GlobalLock(gh);
  204. SetProp(hDlg, STRUCTUREPROP, gh);
  205. if (fCreateFont) {
  206. //Create the non-bold font for result and file texts. We call
  207. hFont=(HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
  208. GetObject(hFont, sizeof(LOGFONT), &lf);
  209. lf.lfWeight=FW_NORMAL;
  210. //Attempt to create the font. If this fails, then we return no font.
  211. *phFont=CreateFontIndirect(&lf);
  212. //If we couldn't create the font, we'll do with the default.
  213. if (NULL!=*phFont)
  214. SetProp(hDlg, FONTPROP, (HANDLE)*phFont);
  215. }
  216. return lpv;
  217. }
  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. LPVOID WINAPI LpvStandardEntry(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam
  239. , UINT FAR * puHookResult)
  240. {
  241. LPVOID lpv = NULL;
  242. HGLOBAL gh;
  243. // This will fail under WM_INITDIALOG, where we allocate using StandardInit
  244. 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. }
  255. return lpv;
  256. }
  257. /*
  258. * UStandardHook
  259. *
  260. * Purpose:
  261. * Provides a generic hook calling function assuming that all private
  262. * dialog structures have a far pointer to their assocated public
  263. * structure as the first field, and that the first part of the public
  264. * structure matches an OLEUISTANDARD.
  265. *
  266. * Parameters:
  267. * pv PVOID to the dialog structure.
  268. * hDlg HWND to send with the call to the hook.
  269. * iMsg UINT message to send to the hook.
  270. * wParam, lParam WPARAM, LPARAM message parameters
  271. *
  272. * Return Value:
  273. * UINT Return value from the hook, zero to indicate that
  274. * default action should occur, nonzero to specify
  275. * that the hook did process the message. In some
  276. * circumstances it will be important for the hook to
  277. * return a non-trivial non-zero value here, such as
  278. * a brush from WM_CTLCOLOR, in which case the caller
  279. * should return that value from the dialog procedure.
  280. */
  281. UINT WINAPI UStandardHook(LPVOID lpv, HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  282. {
  283. LPOLEUISTANDARD lpUI;
  284. UINT uRet=0;
  285. lpUI=*((LPOLEUISTANDARD FAR *)lpv);
  286. if (NULL!=lpUI && NULL!=lpUI->lpfnHook)
  287. {
  288. /*
  289. * In order for the hook to have the proper DS, they should be
  290. * compiling with -GA -GEs so and usin __export to get everything
  291. * set up properly.
  292. */
  293. uRet=(*lpUI->lpfnHook)(hDlg, iMsg, wParam, lParam);
  294. }
  295. return uRet;
  296. }
  297. /*
  298. * StandardCleanup
  299. *
  300. * Purpose:
  301. * Removes properties and reverses any other standard initiazation
  302. * done through StandardSetup.
  303. *
  304. * Parameters:
  305. * lpv LPVOID containing the private dialog structure.
  306. * hDlg HWND of the dialog closing.
  307. *
  308. * Return Value:
  309. * None
  310. */
  311. void WINAPI StandardCleanup(LPVOID lpv, HWND hDlg)
  312. {
  313. HFONT hFont;
  314. HGLOBAL gh;
  315. hFont=(HFONT)GetProp(hDlg, FONTPROP);
  316. if (NULL!=hFont)
  317. DeleteObject(hFont);
  318. RemoveProp(hDlg, FONTPROP);
  319. gh = RemoveProp(hDlg, STRUCTUREPROP);
  320. if (gh)
  321. {
  322. GlobalUnlock(gh);
  323. GlobalFree(gh);
  324. }
  325. return;
  326. }
  327. /* StandardShowDlgItem
  328. ** -------------------
  329. ** Show & Enable or Hide & Disable a dialog item as appropriate.
  330. ** it is NOT sufficient to simply hide the item; it must be disabled
  331. ** too or the keyboard accelerator still functions.
  332. */
  333. void WINAPI StandardShowDlgItem(HWND hDlg, int idControl, int nCmdShow)
  334. {
  335. if (SW_HIDE == nCmdShow) {
  336. ShowWindow(GetDlgItem(hDlg, idControl), SW_HIDE);
  337. EnableWindow(GetDlgItem(hDlg, idControl), FALSE);
  338. } else {
  339. ShowWindow(GetDlgItem(hDlg, idControl), SW_SHOWNORMAL);
  340. EnableWindow(GetDlgItem(hDlg, idControl), TRUE);
  341. }
  342. }
  343.