/* * COMMON.C * * Standardized (and centralized) pieces of each OLE2UI dialog function: * UStandardValidation Validates standard fields in each dialog structure * UStandardInvocation Invokes a dialog through DialogBoxIndirectParam * LpvStandardInit Common WM_INITDIALOG processing * LpvStandardEntry Common code to execute on dialog proc entry. * FStandardHook Centralized hook calling function. * StandardCleanup Common exit/cleanup code. * OleUIShowDlgItem Show-Enable/Hide-Disable dialog item * * Copyright (c)1992 Microsoft Corporation, All Right Reserved */ #define STRICT 1 #include "ole2ui.h" #include "common.h" #include "utility.h" #include /* * UStandardValidation * * Purpose: * Performs validation on the standard pieces of any dialog structure, * that is, the fields defined in the OLEUISTANDARD structure. * * Parameters: * lpUI const LPOLEUISTANDARD pointing to the shared data of * all structs. * cbExpect const UINT structure size desired by the caller. * phDlgMem const HGLOBAL FAR * in which to store a loaded customized * template, if one exists. * * Return Value: * UINT OLEUI_SUCCESS if all validation succeeded. Otherwise * it will be one of the standard error codes. */ UINT WINAPI UStandardValidation(const LPOLEUISTANDARD lpUI, const UINT cbExpect , const HGLOBAL FAR *phMemDlg) { HRSRC hRes=NULL; HGLOBAL hMem=NULL; /* * 1. Validate non-NULL pointer parameter. Note: We don't validate * phDlg since it's not passed from an external source. */ if (NULL==lpUI) return OLEUI_ERR_STRUCTURENULL; //2. Validate that the structure is readable and writable. if (IsBadReadPtr(lpUI, cbExpect) || IsBadWritePtr(lpUI, cbExpect)) return OLEUI_ERR_STRUCTUREINVALID; //3. Validate the structure size if (cbExpect!=lpUI->cbStruct) return OLEUI_ERR_CBSTRUCTINCORRECT; //4. Validate owner-window handle. NULL is considered valid. if (NULL!=lpUI->hWndOwner && !IsWindow(lpUI->hWndOwner)) return OLEUI_ERR_HWNDOWNERINVALID; //5. Validate the dialog caption. NULL is considered valid. if (NULL!=lpUI->lpszCaption && IsBadReadPtr(lpUI->lpszCaption, 1)) return OLEUI_ERR_LPSZCAPTIONINVALID; //6. Validate the hook pointer. NULL is considered valid. if ((LPFNOLEUIHOOK)NULL!=lpUI->lpfnHook && IsBadCodePtr((FARPROC)lpUI->lpfnHook)) return OLEUI_ERR_LPFNHOOKINVALID; /* * 7. If hInstance is non-NULL, we have to also check lpszTemplate. * Otherwise, lpszTemplate is not used and requires no validation. * lpszTemplate cannot be NULL if used. */ if (NULL!=lpUI->hInstance) { //Best we can try is one character if (NULL==lpUI->lpszTemplate || IsBadReadPtr(lpUI->lpszTemplate, 1)) return OLEUI_ERR_LPSZTEMPLATEINVALID; hRes=FindResource(lpUI->hInstance, lpUI->lpszTemplate, RT_DIALOG); //This is the only thing that catches invalid non-NULL hInstance if (NULL==hRes) return OLEUI_ERR_FINDTEMPLATEFAILURE; hMem=LoadResource(lpUI->hInstance, hRes); if (NULL==hMem) return OLEUI_ERR_LOADTEMPLATEFAILURE; } //8. If hResource is non-NULL, be sure we can lock it. if (NULL!=lpUI->hResource) { if ((LPSTR)NULL==GlobalLock(lpUI->hResource)) return OLEUI_ERR_HRESOURCEINVALID; GlobalUnlock(lpUI->hResource); } /* * Here we have hMem==NULL if we should use the standard template * or the one in lpUI->hResource. If hMem is non-NULL, then we * loaded one from the calling application's resources which the * caller of this function has to free if it sees any other error. */ *(HGLOBAL FAR *)phMemDlg=hMem; return OLEUI_SUCCESS; } /* * UStandardInvocation * * Purpose: * Provides standard template loading and calling on DialogBoxIndirectParam * for all the OLE UI dialogs. * * Parameters: * lpDlgProc DLGPROC of the dialog function. * lpUI LPOLEUISTANDARD containing the dialog structure. * hMemDlg HGLOBAL containing the dialog template. If this * is NULL and lpUI->hResource is NULL, then we load * the standard template given the name in lpszStdTemplate * lpszStdTemplate LPCSTR standard template to load if hMemDlg is NULL * and lpUI->hResource is NULL. * * Return Value: * UINT OLEUI_SUCCESS if all is well, otherwise and error * code. */ UINT WINAPI UStandardInvocation #ifdef WIN32 (DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPTSTR lpszStdTemplate) #else (DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPCTSTR lpszStdTemplate) #endif { HGLOBAL hTemplate=hMemDlg; HRSRC hRes; int iRet; //Make sure we have a template, then lock it down if (NULL==hTemplate) hTemplate=lpUI->hResource; if (NULL==hTemplate) { hRes=FindResource(ghInst, (LPCTSTR) lpszStdTemplate, RT_DIALOG); if (NULL==hRes) { return OLEUI_ERR_FINDTEMPLATEFAILURE; } hTemplate=LoadResource(ghInst, hRes); if (NULL==hTemplate) { return OLEUI_ERR_LOADTEMPLATEFAILURE; } } /* * hTemplate has the template to use, so now we can invoke the dialog. * Since we have exported all of our dialog procedures using the * _export keyword, we do not need to call MakeProcInstance, * we can ue the dialog procedure address directly. */ iRet=DialogBoxIndirectParam(ghInst, hTemplate, lpUI->hWndOwner , lpDlgProc, (LPARAM)lpUI); /* * Cleanup the template if we explicitly loaded it. Caller is * responsible for already loaded template resources. */ if (hTemplate!=lpUI->hResource) FreeResource(hTemplate); if (-1==iRet) return OLEUI_ERR_DIALOGFAILURE; //Return the code from EndDialog, generally OLEUI_OK or OLEUI_CANCEL return (UINT)iRet; } /* * LpvStandardInit * * Purpose: * Default actions for WM_INITDIALOG handling in the dialog, allocating * a dialog-specific structure, setting that memory as a dialog property, * and creating a small font if necessary setting that font as a property. * * Parameters: * hDlg HWND of the dialog * cbStruct UINT size of dialog-specific structure to allocate. * fCreateFont BOOL indicating if we need to create a small Helv * font for this dialog. * phFont HFONT FAR * in which to place a created font. Can be * NULL if fCreateFont is FALSE. * * Return Value: * LPVOID Pointer to global memory allocated for the dialog. * The memory will have been set as a dialog property * using the STRUCTUREPROP label. */ LPVOID WINAPI LpvStandardInit(HWND hDlg, UINT cbStruct, BOOL fCreateFont, HFONT FAR * phFont) { LPVOID lpv; HFONT hFont; LOGFONT lf; HGLOBAL gh; //Must have at least sizeof(OLEUISTANDARD) bytes in cbStruct if (sizeof(OLEUISTANDARD) > cbStruct || (fCreateFont && NULL==phFont)) { PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L); return NULL; } gh=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, cbStruct); if (NULL==gh) { PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L); return NULL; } lpv = GlobalLock(gh); SetProp(hDlg, STRUCTUREPROP, gh); if (fCreateFont) { //Create the non-bold font for result and file texts. We call hFont=(HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L); GetObject(hFont, sizeof(LOGFONT), &lf); lf.lfWeight=FW_NORMAL; //Attempt to create the font. If this fails, then we return no font. *phFont=CreateFontIndirect(&lf); //If we couldn't create the font, we'll do with the default. if (NULL!=*phFont) SetProp(hDlg, FONTPROP, (HANDLE)*phFont); } return lpv; } /* * LpvStandardEntry * * Purpose: * Retrieves the dialog's structure property and calls the hook * as necessary. This should be called on entry into all dialog * procedures. * * Parameters: * hDlg HWND of the dialog * iMsg UINT message to the dialog * wParam, lParam WPARAM, LPARAM message parameters * puHookResult UINT FAR * in which this function stores the return value * from the hook if it is called. If no hook is available, * this will be FALSE. * * Return Value: * LPVOID Pointer to the dialog's extra structure held in the * STRUCTUREPROP property. */ LPVOID WINAPI LpvStandardEntry(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam , UINT FAR * puHookResult) { LPVOID lpv = NULL; HGLOBAL gh; // This will fail under WM_INITDIALOG, where we allocate using StandardInit gh = GetProp(hDlg, STRUCTUREPROP); if (NULL!=puHookResult && NULL!=gh) { *puHookResult=0; // gh was locked previously, lock and unlock to get lpv lpv = GlobalLock(gh); GlobalUnlock(gh); //Call the hook for all messages except WM_INITDIALOG if (NULL!=lpv && WM_INITDIALOG!=iMsg) *puHookResult=UStandardHook(lpv, hDlg, iMsg, wParam, lParam); } return lpv; } /* * UStandardHook * * Purpose: * Provides a generic hook calling function assuming that all private * dialog structures have a far pointer to their assocated public * structure as the first field, and that the first part of the public * structure matches an OLEUISTANDARD. * * Parameters: * pv PVOID to the dialog structure. * hDlg HWND to send with the call to the hook. * iMsg UINT message to send to the hook. * wParam, lParam WPARAM, LPARAM message parameters * * Return Value: * UINT Return value from the hook, zero to indicate that * default action should occur, nonzero to specify * that the hook did process the message. In some * circumstances it will be important for the hook to * return a non-trivial non-zero value here, such as * a brush from WM_CTLCOLOR, in which case the caller * should return that value from the dialog procedure. */ UINT WINAPI UStandardHook(LPVOID lpv, HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) { LPOLEUISTANDARD lpUI; UINT uRet=0; lpUI=*((LPOLEUISTANDARD FAR *)lpv); if (NULL!=lpUI && NULL!=lpUI->lpfnHook) { /* * In order for the hook to have the proper DS, they should be * compiling with -GA -GEs so and usin __export to get everything * set up properly. */ uRet=(*lpUI->lpfnHook)(hDlg, iMsg, wParam, lParam); } return uRet; } /* * StandardCleanup * * Purpose: * Removes properties and reverses any other standard initiazation * done through StandardSetup. * * Parameters: * lpv LPVOID containing the private dialog structure. * hDlg HWND of the dialog closing. * * Return Value: * None */ void WINAPI StandardCleanup(LPVOID lpv, HWND hDlg) { HFONT hFont; HGLOBAL gh; hFont=(HFONT)GetProp(hDlg, FONTPROP); if (NULL!=hFont) DeleteObject(hFont); RemoveProp(hDlg, FONTPROP); gh = RemoveProp(hDlg, STRUCTUREPROP); if (gh) { GlobalUnlock(gh); GlobalFree(gh); } return; } /* StandardShowDlgItem ** ------------------- ** Show & Enable or Hide & Disable a dialog item as appropriate. ** it is NOT sufficient to simply hide the item; it must be disabled ** too or the keyboard accelerator still functions. */ void WINAPI StandardShowDlgItem(HWND hDlg, int idControl, int nCmdShow) { if (SW_HIDE == nCmdShow) { ShowWindow(GetDlgItem(hDlg, idControl), SW_HIDE); EnableWindow(GetDlgItem(hDlg, idControl), FALSE); } else { ShowWindow(GetDlgItem(hDlg, idControl), SW_SHOWNORMAL); EnableWindow(GetDlgItem(hDlg, idControl), TRUE); } }