mirror of https://github.com/tongzx/nt5src
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
764 lines
26 KiB
/*
|
|
* COMMON.CPP
|
|
*
|
|
* Standardized (and centralized) pieces of each OLEDLG 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.
|
|
* UStandardHook Centralized hook calling function.
|
|
* StandardCleanup Common exit/cleanup code.
|
|
* StandardShowDlgItem Show-Enable/Hide-Disable dialog item
|
|
* StandardEnableDlgItem Enable/Disable dialog item
|
|
* StandardResizeDlgY Resize dialog to fit controls
|
|
*
|
|
* Copyright (c)1992 Microsoft Corporation, All Right Reserved
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
#include "common.h"
|
|
#include "utility.h"
|
|
|
|
OLEDBGDATA
|
|
|
|
/*
|
|
* 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.
|
|
* (This may be NULL in which case the template pointer isn't
|
|
* needed by the calling function and should be released.)
|
|
*
|
|
* Return Value:
|
|
* UINT OLEUI_SUCCESS if all validation succeeded. Otherwise
|
|
* it will be one of the standard error codes.
|
|
*/
|
|
UINT WINAPI UStandardValidation(LPOLEUISTANDARD lpUI, const UINT cbExpect,
|
|
HGLOBAL* phMemDlg)
|
|
{
|
|
/*
|
|
* 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 (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 (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.
|
|
*/
|
|
HGLOBAL hMem = NULL;
|
|
if (NULL != lpUI->hInstance)
|
|
{
|
|
//Best we can try is one character
|
|
if (NULL == lpUI->lpszTemplate || (HIWORD(PtrToUlong(lpUI->lpszTemplate)) != 0 &&
|
|
IsBadReadPtr(lpUI->lpszTemplate, 1)))
|
|
return OLEUI_ERR_LPSZTEMPLATEINVALID;
|
|
HRSRC hRes = FindResource(lpUI->hInstance, lpUI->lpszTemplate, RT_DIALOG);
|
|
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 == LockResource(lpUI->hResource))
|
|
return OLEUI_ERR_HRESOURCEINVALID;
|
|
}
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
if (NULL != phMemDlg)
|
|
{
|
|
*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(
|
|
DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPTSTR lpszStdTemplate)
|
|
{
|
|
// Make sure we have a template, then lock it down
|
|
HGLOBAL hTemplate = hMemDlg;
|
|
if (NULL == hTemplate)
|
|
hTemplate = lpUI->hResource;
|
|
|
|
if (NULL == hTemplate)
|
|
{
|
|
HRSRC hRes = FindResource(_g_hOleStdResInst, (LPCTSTR) lpszStdTemplate, RT_DIALOG);
|
|
if (NULL == hRes)
|
|
return OLEUI_ERR_FINDTEMPLATEFAILURE;
|
|
|
|
hTemplate = LoadResource(_g_hOleStdResInst, 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
|
|
* _keyword, we do not need to call MakeProcInstance,
|
|
* we can ue the dialog procedure address directly.
|
|
*/
|
|
|
|
INT_PTR iRet = DialogBoxIndirectParam(_g_hOleStdResInst, (LPCDLGTEMPLATE)hTemplate,
|
|
lpUI->hWndOwner, lpDlgProc, (LPARAM)lpUI);
|
|
|
|
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, HFONT* phFont)
|
|
{
|
|
// Must have at least sizeof(void*) bytes in cbStruct
|
|
if (sizeof(void*) > cbStruct)
|
|
{
|
|
PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
|
|
return NULL;
|
|
}
|
|
|
|
HGLOBAL gh = GlobalAlloc(GHND, cbStruct);
|
|
if (NULL == gh)
|
|
{
|
|
PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
|
|
return NULL;
|
|
}
|
|
LPVOID lpv = GlobalLock(gh);
|
|
SetProp(hDlg, STRUCTUREPROP, gh);
|
|
|
|
if (phFont != NULL)
|
|
*phFont = NULL;
|
|
if (!bWin4 && phFont != NULL)
|
|
{
|
|
// Create the non-bold font for result and file texts. We call
|
|
HFONT hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
|
|
LOGFONT lf;
|
|
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);
|
|
}
|
|
|
|
// Setup the context help mode (WS_EX_CONTEXTHELP)
|
|
if (bWin4)
|
|
{
|
|
DWORD dwExStyle = GetWindowLong(hDlg, GWL_EXSTYLE);
|
|
dwExStyle |= WS_EX_CONTEXTHELP;
|
|
SetWindowLong(hDlg, GWL_EXSTYLE, dwExStyle);
|
|
}
|
|
|
|
return lpv;
|
|
}
|
|
|
|
typedef struct COMMON
|
|
{
|
|
OLEUISTANDARD* pStandard;
|
|
UINT nIDD;
|
|
|
|
} COMMON, *PCOMMON, FAR* LPCOMMON;
|
|
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
// char szDebug[100];
|
|
|
|
LPVOID WINAPI LpvStandardEntry(HWND hDlg, UINT iMsg,
|
|
WPARAM wParam, LPARAM lParam, UINT FAR * puHookResult)
|
|
{
|
|
// This will fail under WM_INITDIALOG, where we allocate using StandardInit
|
|
LPVOID lpv = NULL;
|
|
HGLOBAL 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);
|
|
|
|
// Default processing for various messages
|
|
LPCOMMON lpCommon = (LPCOMMON)lpv;
|
|
if (*puHookResult == 0 && NULL != lpv)
|
|
{
|
|
switch (iMsg)
|
|
{
|
|
// handle standard Win4 help messages
|
|
case WM_HELP:
|
|
{
|
|
HWND hWndChild = (HWND)((LPHELPINFO)lParam)->hItemHandle;
|
|
//skip read-only controls (requested by Help folks)
|
|
//basically the help strings for items like ObjectName on GnrlProps
|
|
//give useless information.
|
|
//If we do not make this check now the other option is to turn ON
|
|
//the #if 0 inside the switch. That is ugly.
|
|
|
|
if (hWndChild!=hDlg )
|
|
{
|
|
int iCtrlId = ((LPHELPINFO)lParam)->iCtrlId;
|
|
// wsprintfA(szDebug,"\n @@@ hWnd= %lx, hChld = %lx, ctrlId = %d ", hDlg, hWndChild, iCtrlId);
|
|
// OutputDebugStringA(szDebug);
|
|
switch (iCtrlId)
|
|
{
|
|
// list of control IDs that should not have help
|
|
case -1: //IDC_STATIC
|
|
case 0xffff: //IDC_STATIC
|
|
case IDC_CI_GROUP:
|
|
case IDC_GP_OBJECTICON:
|
|
break;
|
|
default:
|
|
StandardHelp(hWndChild, lpCommon->nIDD);
|
|
|
|
}
|
|
}
|
|
*puHookResult = TRUE; //We handled the message.
|
|
break;
|
|
} //case WM_HELP
|
|
|
|
case WM_CONTEXTMENU:
|
|
{
|
|
POINT pt;
|
|
int iCtrlId;
|
|
HWND hwndChild = NULL;
|
|
if( hDlg == (HWND) wParam )
|
|
{
|
|
GetCursorPos(&pt);
|
|
ScreenToClient(hDlg, &pt);
|
|
hwndChild = ChildWindowFromPointEx(hDlg, pt,
|
|
CWP_SKIPINVISIBLE);
|
|
//hWndChild will now be either hDlg or hWnd of the ctrl
|
|
}
|
|
|
|
if ( hwndChild != hDlg )
|
|
{
|
|
if (hwndChild)
|
|
{
|
|
iCtrlId = GetDlgCtrlID(hwndChild);
|
|
}
|
|
else
|
|
{
|
|
iCtrlId = GetDlgCtrlID((HWND)wParam);
|
|
}
|
|
// wsprintfA(szDebug, "\n ### hWnd= %lx, hChld = %lx, ctrlId = %d ", hDlg, hwndChild, iCtrlId);
|
|
// OutputDebugStringA(szDebug);
|
|
switch (iCtrlId)
|
|
{
|
|
// list of control IDs that should not have help
|
|
case -1: // IDC_STATIC
|
|
case 0xffff: // IDC_STATIC
|
|
case IDC_CI_GROUP:
|
|
case IDC_GP_OBJECTICON:
|
|
break;
|
|
default:
|
|
StandardContextMenu(wParam, lParam, lpCommon->nIDD);
|
|
}
|
|
}
|
|
|
|
*puHookResult = TRUE; //We handled the message.
|
|
break;
|
|
} // case WM_CONTEXTMENU
|
|
|
|
case WM_CTLCOLOREDIT:
|
|
{
|
|
// make readonly edits have gray background
|
|
if (bWin4 && (GetWindowLong((HWND)lParam, GWL_STYLE)
|
|
& ES_READONLY))
|
|
{
|
|
*puHookResult = (UINT)SendMessage(hDlg, WM_CTLCOLORSTATIC, wParam, lParam);
|
|
}
|
|
break;
|
|
}
|
|
} //switch (iMsg)
|
|
} //*puHookResult == 0
|
|
} //NULL != puHookResult
|
|
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)
|
|
{
|
|
UINT uRet = 0;
|
|
LPOLEUISTANDARD 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 __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=(HFONT)RemoveProp(hDlg, FONTPROP);
|
|
if (NULL != hFont)
|
|
{
|
|
DeleteObject(hFont);
|
|
}
|
|
|
|
HGLOBAL gh = RemoveProp(hDlg, STRUCTUREPROP);
|
|
if (gh != NULL)
|
|
{
|
|
GlobalUnlock(gh);
|
|
GlobalFree(gh);
|
|
}
|
|
}
|
|
|
|
/* 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)
|
|
{
|
|
HWND hItem = GetDlgItem(hDlg, idControl);
|
|
if (hItem != NULL)
|
|
{
|
|
ShowWindow(hItem, nCmdShow);
|
|
EnableWindow(hItem, nCmdShow != SW_HIDE);
|
|
}
|
|
}
|
|
|
|
/* StandardEnableDlgItem
|
|
* -------------------
|
|
* Enable/Disable a dialog item. If the item does not exist
|
|
* this call is a noop.
|
|
*/
|
|
void WINAPI StandardEnableDlgItem(HWND hDlg, int idControl, BOOL bEnable)
|
|
{
|
|
HWND hItem = GetDlgItem(hDlg, idControl);
|
|
if (hItem != NULL)
|
|
EnableWindow(hItem, bEnable);
|
|
}
|
|
|
|
/* StandardResizeDlgY
|
|
* ------------------
|
|
* Resize a dialog to fit around the visible controls. This is used
|
|
* for dialogs which remove controls from the bottom of the dialogs.
|
|
* A good example of this is the convert dialog, which when CF_HIDERESULTS
|
|
* is selected, removes the "results box" at the bottom of the dialog.
|
|
* This implementation currently
|
|
*/
|
|
BOOL WINAPI StandardResizeDlgY(HWND hDlg)
|
|
{
|
|
RECT rect;
|
|
|
|
// determine maxY by looking at all child windows on the dialog
|
|
int maxY = 0;
|
|
HWND hChild = GetWindow(hDlg, GW_CHILD);
|
|
while (hChild != NULL)
|
|
{
|
|
if (GetWindowLong(hChild, GWL_STYLE) & WS_VISIBLE)
|
|
{
|
|
GetWindowRect(hChild, &rect);
|
|
if (rect.bottom > maxY)
|
|
maxY = rect.bottom;
|
|
}
|
|
hChild = GetWindow(hChild, GW_HWNDNEXT);
|
|
}
|
|
|
|
if (maxY > 0)
|
|
{
|
|
// get current font that the dialog is using
|
|
HFONT hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0);
|
|
if (hFont == NULL)
|
|
hFont = (HFONT)GetStockObject(SYSTEM_FONT);
|
|
OleDbgAssert(hFont != NULL);
|
|
|
|
// calculate height of the font in pixels
|
|
HDC hDC = GetDC(NULL);
|
|
hFont = (HFONT)SelectObject(hDC, hFont);
|
|
TEXTMETRIC tm;
|
|
GetTextMetrics(hDC, &tm);
|
|
SelectObject(hDC, hFont);
|
|
ReleaseDC(NULL, hDC);
|
|
|
|
// determine if window is too large and resize if necessary
|
|
GetWindowRect(hDlg, &rect);
|
|
if (rect.bottom > maxY + tm.tmHeight)
|
|
{
|
|
// window is too large -- resize it
|
|
rect.bottom = maxY + tm.tmHeight;
|
|
SetWindowPos(hDlg, NULL,
|
|
0, 0, rect.right-rect.left, rect.bottom-rect.top,
|
|
SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Support for Windows 95 help
|
|
#define HELPFILE TEXT("mfcuix.hlp")
|
|
|
|
LPDWORD LoadHelpInfo(UINT nIDD)
|
|
{
|
|
HRSRC hrsrc = FindResource(_g_hOleStdResInst, MAKEINTRESOURCE(nIDD),
|
|
MAKEINTRESOURCE(RT_HELPINFO));
|
|
if (hrsrc == NULL)
|
|
return NULL;
|
|
|
|
HGLOBAL hHelpInfo = LoadResource(_g_hOleStdResInst, hrsrc);
|
|
if (hHelpInfo == NULL)
|
|
return NULL;
|
|
|
|
LPDWORD lpdwHelpInfo = (LPDWORD)LockResource(hHelpInfo);
|
|
return lpdwHelpInfo;
|
|
}
|
|
|
|
void WINAPI StandardHelp(HWND hWnd, UINT nIDD)
|
|
{
|
|
LPDWORD lpdwHelpInfo = LoadHelpInfo(nIDD);
|
|
if (lpdwHelpInfo == NULL)
|
|
{
|
|
OleDbgOut1(TEXT("Warning: unable to load help information (RT_HELPINFO)\n"));
|
|
return;
|
|
}
|
|
/*
|
|
int id=GetDlgCtrlID( hWnd);
|
|
wsprintfA(szDebug,"\n HH @@@### hWnd= %lx, ctrlId = %d %lx", hWnd,id,id);
|
|
OutputDebugStringA(szDebug);
|
|
*/
|
|
|
|
WinHelp(hWnd, HELPFILE, HELP_WM_HELP, (ULONG_PTR)lpdwHelpInfo);
|
|
}
|
|
|
|
void WINAPI StandardContextMenu(WPARAM wParam, LPARAM, UINT nIDD)
|
|
{
|
|
LPDWORD lpdwHelpInfo = LoadHelpInfo(nIDD);
|
|
if (lpdwHelpInfo == NULL)
|
|
{
|
|
OleDbgOut1(TEXT("Warning: unable to load help information (RT_HELPINFO)\n"));
|
|
return;
|
|
}
|
|
/*
|
|
int id=GetDlgCtrlID((HWND)wParam);
|
|
wsprintfA(szDebug,"\n CC $$$*** hWnd= %lx, ctrlId = %d %lx ",(HWND)wParam,id,id);
|
|
OutputDebugStringA(szDebug);
|
|
*/
|
|
|
|
WinHelp((HWND)wParam, HELPFILE, HELP_CONTEXTMENU, (ULONG_PTR)lpdwHelpInfo);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// StandardPropertySheet (stub for Windows 95 API PropertySheet)
|
|
|
|
typedef void (WINAPI* LPFNINITCOMMONCONTROLS)(VOID);
|
|
|
|
int WINAPI StandardInitCommonControls()
|
|
{
|
|
TASKDATA* pTaskData = GetTaskData();
|
|
OleDbgAssert(pTaskData != NULL);
|
|
|
|
if (pTaskData->hInstCommCtrl == NULL)
|
|
{
|
|
pTaskData->hInstCommCtrl = LoadLibrary(TEXT("comctl32.dll"));
|
|
if (pTaskData->hInstCommCtrl == NULL)
|
|
goto Error;
|
|
|
|
LPFNINITCOMMONCONTROLS lpfnInitCommonControls = (LPFNINITCOMMONCONTROLS)
|
|
GetProcAddress(pTaskData->hInstCommCtrl, "InitCommonControls");
|
|
if (lpfnInitCommonControls == NULL)
|
|
goto ErrorFreeLibrary;
|
|
(*lpfnInitCommonControls)();
|
|
}
|
|
return 0;
|
|
|
|
ErrorFreeLibrary:
|
|
if (pTaskData->hInstCommCtrl != NULL)
|
|
{
|
|
FreeLibrary(pTaskData->hInstCommCtrl);
|
|
pTaskData->hInstCommCtrl = NULL;
|
|
}
|
|
|
|
Error:
|
|
return -1;
|
|
}
|
|
|
|
typedef int (WINAPI* LPFNPROPERTYSHEET)(LPCPROPSHEETHEADER);
|
|
|
|
int WINAPI StandardPropertySheet(LPPROPSHEETHEADER lpPS, BOOL fWide)
|
|
{
|
|
int nResult = StandardInitCommonControls();
|
|
if (nResult < 0)
|
|
return nResult;
|
|
|
|
TASKDATA* pTaskData = GetTaskData();
|
|
OleDbgAssert(pTaskData != NULL);
|
|
|
|
LPFNPROPERTYSHEET lpfnPropertySheet;
|
|
if (fWide)
|
|
{
|
|
lpfnPropertySheet = (LPFNPROPERTYSHEET)GetProcAddress(pTaskData->hInstCommCtrl, "PropertySheetW");
|
|
}
|
|
else
|
|
{
|
|
lpfnPropertySheet = (LPFNPROPERTYSHEET)GetProcAddress(pTaskData->hInstCommCtrl, "PropertySheetA");
|
|
}
|
|
if (lpfnPropertySheet == NULL)
|
|
return -1;
|
|
|
|
nResult = (*lpfnPropertySheet)(lpPS);
|
|
return nResult;
|
|
}
|
|
|
|
typedef HICON (WINAPI* LPFNEXTRACTICON)(HINSTANCE, LPCTSTR, UINT);
|
|
|
|
HICON StandardExtractIcon(HINSTANCE hInst, LPCTSTR lpszExeFileName, UINT nIconIndex)
|
|
{
|
|
TASKDATA* pTaskData = GetTaskData();
|
|
OleDbgAssert(pTaskData != NULL);
|
|
LPFNEXTRACTICON lpfnExtractIcon;
|
|
|
|
if (pTaskData->hInstShell == NULL)
|
|
{
|
|
pTaskData->hInstShell = LoadLibrary(TEXT("shell32.dll"));
|
|
if (pTaskData->hInstShell == NULL)
|
|
goto Error;
|
|
}
|
|
lpfnExtractIcon = (LPFNEXTRACTICON)
|
|
#ifdef UNICODE
|
|
GetProcAddress(pTaskData->hInstShell, "ExtractIconW");
|
|
#else
|
|
GetProcAddress(pTaskData->hInstShell, "ExtractIconA");
|
|
#endif
|
|
if (lpfnExtractIcon == NULL)
|
|
goto ErrorFreeLibrary;
|
|
return (*lpfnExtractIcon)(hInst, lpszExeFileName, nIconIndex);
|
|
|
|
ErrorFreeLibrary:
|
|
if (pTaskData->hInstShell != NULL)
|
|
{
|
|
FreeLibrary(pTaskData->hInstShell);
|
|
pTaskData->hInstShell = NULL;
|
|
}
|
|
|
|
Error:
|
|
return NULL;
|
|
}
|
|
|
|
|
|
typedef BOOL (WINAPI* LPFNGETOPENFILENAME)(LPOPENFILENAME);
|
|
|
|
BOOL StandardGetOpenFileName(LPOPENFILENAME lpofn)
|
|
{
|
|
TASKDATA* pTaskData = GetTaskData();
|
|
OleDbgAssert(pTaskData != NULL);
|
|
LPFNGETOPENFILENAME lpfnGetOpenFileName;
|
|
|
|
if (pTaskData->hInstComDlg == NULL)
|
|
{
|
|
pTaskData->hInstComDlg = LoadLibrary(TEXT("comdlg32.dll"));
|
|
if (pTaskData->hInstComDlg == NULL)
|
|
goto Error;
|
|
}
|
|
lpfnGetOpenFileName = (LPFNGETOPENFILENAME)
|
|
#ifdef UNICODE
|
|
GetProcAddress(pTaskData->hInstComDlg, "GetOpenFileNameW");
|
|
#else
|
|
GetProcAddress(pTaskData->hInstComDlg, "GetOpenFileNameA");
|
|
#endif
|
|
if (lpfnGetOpenFileName == NULL)
|
|
goto ErrorFreeLibrary;
|
|
return (*lpfnGetOpenFileName)(lpofn);
|
|
|
|
ErrorFreeLibrary:
|
|
if (pTaskData->hInstComDlg != NULL)
|
|
{
|
|
FreeLibrary(pTaskData->hInstComDlg);
|
|
pTaskData->hInstComDlg = NULL;
|
|
}
|
|
|
|
Error:
|
|
return FALSE;
|
|
}
|
|
|
|
typedef short (WINAPI* LPFNGETFILETITLE)(LPCTSTR, LPTSTR, WORD);
|
|
|
|
short StandardGetFileTitle(LPCTSTR lpszFile, LPTSTR lpszTitle, WORD cbBuf)
|
|
{
|
|
TASKDATA* pTaskData = GetTaskData();
|
|
OleDbgAssert(pTaskData != NULL);
|
|
LPFNGETFILETITLE lpfnGetFileTitle;
|
|
|
|
if (pTaskData->hInstComDlg == NULL)
|
|
{
|
|
pTaskData->hInstComDlg = LoadLibrary(TEXT("comdlg32.dll"));
|
|
if (pTaskData->hInstComDlg == NULL)
|
|
goto Error;
|
|
}
|
|
lpfnGetFileTitle = (LPFNGETFILETITLE)
|
|
#ifdef UNICODE
|
|
GetProcAddress(pTaskData->hInstComDlg, "GetFileTitleW");
|
|
#else
|
|
GetProcAddress(pTaskData->hInstComDlg, "GetFileTitleA");
|
|
#endif
|
|
if (lpfnGetFileTitle == NULL)
|
|
goto ErrorFreeLibrary;
|
|
return (*lpfnGetFileTitle)(lpszFile, lpszTitle, cbBuf);
|
|
|
|
ErrorFreeLibrary:
|
|
if (pTaskData->hInstComDlg != NULL)
|
|
{
|
|
FreeLibrary(pTaskData->hInstComDlg);
|
|
pTaskData->hInstComDlg = NULL;
|
|
}
|
|
|
|
Error:
|
|
return -1;
|
|
}
|
|
|