424 lines
12 KiB
C
424 lines
12 KiB
C
|
/*
|
|||
|
* 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 <malloc.h>
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* 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);
|
|||
|
}
|
|||
|
}
|
|||
|
|