summaryrefslogtreecommitdiffstats
path: root/private/ole2ui32/common.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'private/ole2ui32/common.cpp')
-rw-r--r--private/ole2ui32/common.cpp685
1 files changed, 685 insertions, 0 deletions
diff --git a/private/ole2ui32/common.cpp b/private/ole2ui32/common.cpp
new file mode 100644
index 000000000..fb31a80e2
--- /dev/null
+++ b/private/ole2ui32/common.cpp
@@ -0,0 +1,685 @@
+/*
+ * 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(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 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.
+ */
+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 hWnd = (HWND)((LPHELPINFO)lParam)->hItemHandle;
+ StandardHelp(hWnd, lpCommon->nIDD);
+ break;
+ }
+ case WM_CONTEXTMENU:
+ StandardContextMenu(wParam, lParam, lpCommon->nIDD);
+ break;
+
+ // make readonly edits have gray background
+ case WM_CTLCOLOREDIT:
+ if (bWin4 && (GetWindowLong((HWND)lParam, GWL_STYLE)
+ & ES_READONLY))
+ {
+ *puHookResult = SendMessage(hDlg, WM_CTLCOLORSTATIC,
+ wParam, lParam);
+ }
+ break;
+ }
+ }
+ }
+ 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)GetProp(hDlg, FONTPROP);
+ if (NULL != hFont)
+ {
+ DeleteObject(hFont);
+ RemoveProp(hDlg, FONTPROP);
+ }
+
+ 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
+// BUGBUG - probably need to rename
+#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;
+ }
+ WinHelp(hWnd, HELPFILE, HELP_WM_HELP, (DWORD)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;
+ }
+ WinHelp((HWND)wParam, HELPFILE, HELP_CONTEXTMENU, (DWORD)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;
+}
+