summaryrefslogtreecommitdiffstats
path: root/private/ole2ui32
diff options
context:
space:
mode:
Diffstat (limited to 'private/ole2ui32')
-rw-r--r--private/ole2ui32/busy.cpp421
-rw-r--r--private/ole2ui32/chngsrc.cpp432
-rw-r--r--private/ole2ui32/common.cpp685
-rw-r--r--private/ole2ui32/common.h154
-rw-r--r--private/ole2ui32/convert.cpp1424
-rw-r--r--private/ole2ui32/daytona/makefile6
-rw-r--r--private/ole2ui32/daytona/sources74
-rw-r--r--private/ole2ui32/dbgutil.cpp372
-rw-r--r--private/ole2ui32/dirs40
-rw-r--r--private/ole2ui32/dllfuncs.cpp65
-rw-r--r--private/ole2ui32/drawicon.cpp674
-rw-r--r--private/ole2ui32/geticon.cpp166
-rw-r--r--private/ole2ui32/icon.cpp1316
-rw-r--r--private/ole2ui32/iconbox.cpp215
-rw-r--r--private/ole2ui32/iconbox.h29
-rw-r--r--private/ole2ui32/insobj.cpp1850
-rw-r--r--private/ole2ui32/links.cpp1537
-rw-r--r--private/ole2ui32/mfcui/dirs37
-rw-r--r--private/ole2ui32/mfcui/mfcui.cpp223
-rw-r--r--private/ole2ui32/mfcui/mfcuia32/makefile6
-rw-r--r--private/ole2ui32/mfcui/mfcuia32/mfcui.rc80
-rw-r--r--private/ole2ui32/mfcui/mfcuia32/mfcuia32.def19
-rw-r--r--private/ole2ui32/mfcui/mfcuia32/sources52
-rw-r--r--private/ole2ui32/mfcui/mfcuiw32/makefile6
-rw-r--r--private/ole2ui32/mfcui/mfcuiw32/mfcui.rc80
-rw-r--r--private/ole2ui32/mfcui/mfcuiw32/mfcuiw32.def19
-rw-r--r--private/ole2ui32/mfcui/mfcuiw32/sources50
-rw-r--r--private/ole2ui32/mfcui/resource.h15
-rw-r--r--private/ole2ui32/objprop.cpp1335
-rw-r--r--private/ole2ui32/ole2ui.cpp1036
-rw-r--r--private/ole2ui32/ole2ui.rc254
-rw-r--r--private/ole2ui32/oledlg.def46
-rw-r--r--private/ole2ui32/oledlgs.h170
-rw-r--r--private/ole2ui32/olestd.cpp816
-rw-r--r--private/ole2ui32/olestd.h328
-rw-r--r--private/ole2ui32/oleutl.cpp132
-rw-r--r--private/ole2ui32/pastespl.cpp1881
-rw-r--r--private/ole2ui32/precomp.h29
-rw-r--r--private/ole2ui32/res/egares.bmpbin0 -> 2954 bytes
-rw-r--r--private/ole2ui32/res/hivgares.bmpbin0 -> 7226 bytes
-rw-r--r--private/ole2ui32/res/ole2ui.rc2145
-rw-r--r--private/ole2ui32/res/vgares.bmpbin0 -> 3916 bytes
-rw-r--r--private/ole2ui32/resimage.cpp355
-rw-r--r--private/ole2ui32/resimage.h56
-rw-r--r--private/ole2ui32/resource.h102
-rw-r--r--private/ole2ui32/targtdev.cpp32
-rw-r--r--private/ole2ui32/template.cpp229
-rw-r--r--private/ole2ui32/template.h119
-rw-r--r--private/ole2ui32/test/ansi/makefile6
-rw-r--r--private/ole2ui32/test/ansi/sources53
-rw-r--r--private/ole2ui32/test/unicode/makefile6
-rw-r--r--private/ole2ui32/test/unicode/sources53
-rw-r--r--private/ole2ui32/uiclass.h7
-rw-r--r--private/ole2ui32/utility.cpp830
-rw-r--r--private/ole2ui32/utility.h66
-rw-r--r--private/ole2ui32/win32s/makefile6
-rw-r--r--private/ole2ui32/win32s/oledlg.def46
-rw-r--r--private/ole2ui32/win32s/sources78
-rw-r--r--private/ole2ui32/winres.h300
-rw-r--r--private/ole2ui32/wrapstub.cpp1777
60 files changed, 20340 insertions, 0 deletions
diff --git a/private/ole2ui32/busy.cpp b/private/ole2ui32/busy.cpp
new file mode 100644
index 000000000..eb18144f0
--- /dev/null
+++ b/private/ole2ui32/busy.cpp
@@ -0,0 +1,421 @@
+/*
+ * BUSY.CPP
+ *
+ * Implements the OleUIBusy function which invokes the "Server Busy"
+ * dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+
+OLEDBGDATA
+
+// Internally used structure
+typedef struct tagBUSY
+{
+ // Keep these items first as the Standard* functions depend on it here.
+ LPOLEUIBUSY lpOBZ; // Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ /*
+ * What we store extra in this structure besides the original caller's
+ * pointer are those fields that we need to modify during the life of
+ * the dialog or that we don't want to change in the original structure
+ * until the user presses OK.
+ */
+ DWORD dwFlags; // Flags passed in
+ HWND hWndBlocked; // HWND of app which is blocking
+
+} BUSY, *PBUSY, FAR *LPBUSY;
+
+// Internal function prototypes
+// BUSY.CPP
+
+BOOL CALLBACK BusyDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam);
+BOOL GetTaskInfo(HWND hWnd, HTASK htask, LPTSTR* lplpszWindowName, HWND* lphWnd);
+void BuildBusyDialogString(HWND, DWORD, int, LPTSTR);
+BOOL FBusyInit(HWND hDlg, WPARAM wParam, LPARAM lParam);
+void MakeWindowActive(HWND hWndSwitchTo);
+
+/*
+ * OleUIBusy
+ *
+ * Purpose:
+ * Invokes the standard OLE "Server Busy" dialog box which
+ * notifies the user that the server application is not receiving
+ * messages. The dialog then asks the user to either cancel
+ * the operation, switch to the task which is blocked, or continue
+ * waiting.
+ *
+ * Parameters:
+ * lpBZ LPOLEUIBUSY pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * OLEUI_BZERR_HTASKINVALID : Error
+ * OLEUI_BZ_SWITCHTOSELECTED : Success, user selected "switch to"
+ * OLEUI_BZ_RETRYSELECTED : Success, user selected "retry"
+ * OLEUI_CANCEL : Success, user selected "cancel"
+ */
+STDAPI_(UINT) OleUIBusy(LPOLEUIBUSY lpOBZ)
+{
+ HGLOBAL hMemDlg = NULL;
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpOBZ, sizeof(OLEUIBUSY),
+ &hMemDlg);
+
+ // Error out if the standard validation failed
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+ // Error out if our secondary validation failed
+ if (OLEUI_ERR_STANDARDMIN <= uRet)
+ {
+ return uRet;
+ }
+
+ // Invoke the dialog.
+ uRet = UStandardInvocation(BusyDialogProc, (LPOLEUISTANDARD)lpOBZ,
+ hMemDlg, MAKEINTRESOURCE(IDD_BUSY));
+ return uRet;
+}
+
+/*
+ * BusyDialogProc
+ *
+ * Purpose:
+ * Implements the OLE Busy dialog as invoked through the OleUIBusy function.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ *
+ */
+BOOL CALLBACK BusyDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uRet = 0;
+ LPBUSY lpBZ = (LPBUSY)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
+
+ // If the hook processed the message, we're done.
+ if (0 != uRet)
+ return (BOOL)uRet;
+
+ // Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ // Process our special "close" message. If we get this message,
+ // this means that the call got unblocked, so we need to
+ // return OLEUI_BZ_CALLUNBLOCKED to our calling app.
+ if (iMsg == uMsgCloseBusyDlg)
+ {
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_BZ_CALLUNBLOCKED, 0L);
+ return TRUE;
+ }
+
+ switch (iMsg)
+ {
+ case WM_DESTROY:
+ if (lpBZ)
+ {
+ StandardCleanup(lpBZ, hDlg);
+ }
+ break;
+ case WM_INITDIALOG:
+ FBusyInit(hDlg, wParam, lParam);
+ return TRUE;
+
+ case WM_ACTIVATEAPP:
+ {
+ /* try to bring down our Busy/NotResponding dialog as if
+ ** the user entered RETRY.
+ */
+ BOOL fActive = (BOOL)wParam;
+ if (fActive)
+ {
+ // If this is the app BUSY case, then bring down our
+ // dialog when switching BACK to our app
+ if (lpBZ && !(lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG))
+ SendMessage(hDlg,uMsgEndDialog,OLEUI_BZ_RETRYSELECTED,0L);
+ }
+ else
+ {
+ // If this is the app NOT RESPONDING case, then bring down
+ // our dialog when switching AWAY to another app
+ if (lpBZ && (lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG))
+ SendMessage(hDlg,uMsgEndDialog,OLEUI_BZ_RETRYSELECTED,0L);
+ }
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_BZ_SWITCHTO:
+ {
+ BOOL fNotRespondingDlg =
+ (BOOL)(lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG);
+ HWND hwndTaskList = hDlg;
+
+ // If this is the app not responding case, then we want
+ // to bring down the dialog when "SwitchTo" is selected.
+ // If the app is busy (RetryRejectedCall situation) then
+ // we do NOT want to bring down the dialog. this is
+ // the OLE2.0 user model design.
+ if (fNotRespondingDlg)
+ {
+ hwndTaskList = GetParent(hDlg);
+ if (hwndTaskList == NULL)
+ hwndTaskList = GetDesktopWindow();
+ PostMessage(hDlg, uMsgEndDialog,
+ OLEUI_BZ_SWITCHTOSELECTED, 0L);
+ }
+
+ // If user selects "Switch To...", switch activation
+ // directly to the window which is causing the problem.
+ if (IsWindow(lpBZ->hWndBlocked))
+ MakeWindowActive(lpBZ->hWndBlocked);
+ else
+ PostMessage(hwndTaskList, WM_SYSCOMMAND, SC_TASKLIST, 0);
+ }
+ break;
+
+ case IDC_BZ_RETRY:
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_BZ_RETRYSELECTED, 0L);
+ break;
+
+ case IDCANCEL:
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * FBusyInit
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the Busy dialog box.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+BOOL FBusyInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ HFONT hFont;
+ LPBUSY lpBZ = (LPBUSY)LpvStandardInit(hDlg, sizeof(BUSY), &hFont);
+
+ // PvStandardInit sent a termination to us already.
+ if (NULL == lpBZ)
+ return FALSE;
+
+ // Our original structure is in lParam
+ LPOLEUIBUSY lpOBZ = (LPOLEUIBUSY)lParam;
+
+ // Copy it to our instance of the structure (in lpBZ)
+ lpBZ->lpOBZ = lpOBZ;
+ lpBZ->nIDD = IDD_BUSY;
+
+ //Copy other information from lpOBZ that we might modify.
+ lpBZ->dwFlags = lpOBZ->dwFlags;
+
+ // Set default information
+ lpBZ->hWndBlocked = NULL;
+
+ // Insert HWND of our dialog into the address pointed to by
+ // lphWndDialog. This can be used by the app who called
+ // OleUIBusy to bring down the dialog with uMsgCloseBusyDialog
+ if (lpOBZ->lphWndDialog &&
+ !IsBadWritePtr(lpOBZ->lphWndDialog, sizeof(HWND)))
+ {
+ *lpOBZ->lphWndDialog = hDlg;
+ }
+
+ // Update text in text box --
+ // GetTaskInfo will return two pointers, one to the task name
+ // (file name) and one to the window name. We need to call
+ // OleStdFree on these when we're done with them. We also
+ // get the HWND which is blocked in this call
+ //
+ // In the case where this call fails, a default message should already
+ // be present in the dialog template, so no action is needed
+
+ LPTSTR lpWindowName;
+ if (GetTaskInfo(hDlg, lpOBZ->hTask, &lpWindowName, &lpBZ->hWndBlocked))
+ {
+ // Build string to present to user, place in IDC_BZ_MESSAGE1 control
+ BuildBusyDialogString(hDlg, lpBZ->dwFlags, IDC_BZ_MESSAGE1, lpWindowName);
+ OleStdFree(lpWindowName);
+ }
+
+ // Update icon with the system "exclamation" icon
+ HICON hIcon = LoadIcon(NULL, IDI_EXCLAMATION);
+ SendDlgItemMessage(hDlg, IDC_BZ_ICON, STM_SETICON, (WPARAM)hIcon, 0L);
+
+ // Disable/Enable controls
+ if ((lpBZ->dwFlags & BZ_DISABLECANCELBUTTON) ||
+ (lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG))
+ {
+ // Disable cancel for "not responding" dialog
+ StandardEnableDlgItem(hDlg, IDCANCEL, FALSE);
+ }
+
+ if (lpBZ->dwFlags & BZ_DISABLESWITCHTOBUTTON)
+ StandardEnableDlgItem(hDlg, IDC_BZ_SWITCHTO, FALSE);
+
+ if (lpBZ->dwFlags & BZ_DISABLERETRYBUTTON)
+ StandardEnableDlgItem(hDlg, IDC_BZ_RETRY, FALSE);
+
+ // Call the hook with lCustData in lParam
+ UStandardHook((LPVOID)lpBZ, hDlg, WM_INITDIALOG, wParam, lpOBZ->lCustData);
+
+ // Update caption if lpszCaption was specified
+ if (lpBZ->lpOBZ->lpszCaption && !IsBadReadPtr(lpBZ->lpOBZ->lpszCaption, 1))
+ {
+ SetWindowText(hDlg, lpBZ->lpOBZ->lpszCaption);
+ }
+ return TRUE;
+}
+
+/*
+ * BuildBusyDialogString
+ *
+ * Purpose:
+ * Builds the string that will be displayed in the dialog from the
+ * task name and window name parameters.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * dwFlags DWORD containing flags passed into dialog
+ * iControl Control ID to place the text string
+ * lpTaskName LPSTR pointing to name of task (e.g. C:\TEST\TEST.EXE)
+ * lpWindowName LPSTR for name of window
+ *
+ * Caveats:
+ * The caller of this function MUST de-allocate the lpTaskName and
+ * lpWindowName pointers itself with OleStdFree
+ *
+ * Return Value:
+ * void
+ */
+void BuildBusyDialogString(
+ HWND hDlg, DWORD dwFlags, int iControl, LPTSTR lpWindowName)
+{
+ // Load the format string out of stringtable, choose a different
+ // string depending on what flags are passed in to the dialog
+ UINT uiStringNum;
+ if (dwFlags & BZ_NOTRESPONDINGDIALOG)
+ uiStringNum = IDS_BZRESULTTEXTNOTRESPONDING;
+ else
+ uiStringNum = IDS_BZRESULTTEXTBUSY;
+
+ TCHAR szFormat[256];
+ if (LoadString(_g_hOleStdResInst, uiStringNum, szFormat, 256) == 0)
+ return;
+
+ // Build the string. The format string looks like this:
+ // "This action cannot be completed because the "%1" application
+ // is [busy | not responding]. Choose \"Switch To\" to correct the
+ // problem."
+
+ TCHAR szMessage[512];
+ FormatString1(szMessage, szFormat, lpWindowName);
+ SetDlgItemText(hDlg, iControl, szMessage);
+}
+
+/*
+ * GetTaskInfo()
+ *
+ * Purpose: Gets information about the specified task and places the
+ * module name, window name and top-level HWND for the task in the specified
+ * pointers
+ *
+ * NOTE: The two string pointers allocated in this routine are
+ * the responsibility of the CALLER to de-allocate.
+ *
+ * Parameters:
+ * hWnd HWND who called this function
+ * htask HTASK which we want to find out more info about
+ * lplpszTaskName Location that the module name is returned
+ * lplpszWindowName Location where the window name is returned
+ *
+ */
+BOOL GetTaskInfo(
+ HWND hWnd, HTASK htask, LPTSTR* lplpszWindowName, HWND* lphWnd)
+{
+ if (htask == NULL)
+ return FALSE;
+
+ // initialize 'out' parameters
+ *lplpszWindowName = NULL;
+
+ // Now, enumerate top-level windows in system
+ HWND hwndNext = GetWindow(hWnd, GW_HWNDFIRST);
+ while (hwndNext)
+ {
+ // See if we can find a non-owned top level window whose
+ // hInstance matches the one we just got passed. If we find one,
+ // we can be fairly certain that this is the top-level window for
+ // the task which is blocked.
+ DWORD dwProcessID;
+ DWORD dwThreadID = GetWindowThreadProcessId(hwndNext, &dwProcessID);
+ if ((hwndNext != hWnd) &&
+ (dwThreadID == (DWORD)htask) &&
+ (IsWindowVisible(hwndNext)) && !GetWindow(hwndNext, GW_OWNER))
+ {
+ // We found our window! Alloc space for new strings
+ LPTSTR lpszWN;
+ if ((lpszWN = (LPTSTR)OleStdMalloc(MAX_PATH_SIZE)) == NULL)
+ break;
+
+ // We found the window we were looking for, copy info to
+ // local vars
+ GetWindowText(hwndNext, lpszWN, MAX_PATH);
+
+ // Note: the task name cannot be retrieved with the Win32 API.
+
+ // everything was successful. Set string pointers to point to our data.
+ *lplpszWindowName = lpszWN;
+ *lphWnd = hwndNext;
+ return TRUE;
+ }
+ hwndNext = GetWindow(hwndNext, GW_HWNDNEXT);
+ }
+
+ return FALSE;
+}
+
+/*
+ * MakeWindowActive()
+ *
+ * Purpose: Makes specified window the active window.
+ *
+ */
+void MakeWindowActive(HWND hWndSwitchTo)
+{
+ // If it's iconic, we need to restore it.
+ if (IsIconic(hWndSwitchTo))
+ ShowWindow(hWndSwitchTo, SW_RESTORE);
+
+ // Move the new window to the top of the Z-order
+ SetForegroundWindow(GetLastActivePopup(hWndSwitchTo));
+}
diff --git a/private/ole2ui32/chngsrc.cpp b/private/ole2ui32/chngsrc.cpp
new file mode 100644
index 000000000..bca1c115b
--- /dev/null
+++ b/private/ole2ui32/chngsrc.cpp
@@ -0,0 +1,432 @@
+/*
+ * CHNGSRC.CPP
+ *
+ * Implements the OleUIChangeSource function which invokes the complete
+ * Change Source dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+
+OLEDBGDATA
+
+// Internally used structure
+typedef struct tagCHANGESOURCE
+{
+ // Keep this item first as the Standard* functions depend on it here.
+ LPOLEUICHANGESOURCE lpOCS; //Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ /*
+ * What we store extra in this structure besides the original caller's
+ * pointer are those fields that we need to modify during the life of
+ * the dialog but that we don't want to change in the original structure
+ * until the user presses OK.
+ */
+
+} CHANGESOURCE, *PCHANGESOURCE, FAR* LPCHANGESOURCE;
+
+// Internal function prototypes
+// CHNGSRC.CPP
+
+UINT CALLBACK ChangeSourceHookProc(HWND, UINT, WPARAM, LPARAM);
+BOOL FChangeSourceInit(HWND hDlg, WPARAM, LPARAM);
+STDAPI_(BOOL) IsValidInterface(void FAR* ppv);
+
+/*
+ * OleUIChangeSource
+ *
+ * Purpose:
+ * Invokes the standard OLE Change Source dialog box allowing the user
+ * to change the source of a link. The link source is not actually
+ * changed by this dialog. It is up to the caller to actually change
+ * the link source itself.
+ *
+ * Parameters:
+ * lpCS LPOLEUIChangeSource pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * UINT One of the following codes, indicating success or error:
+ * OLEUI_SUCCESS Success
+ * OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
+ */
+STDAPI_(UINT) OleUIChangeSource(LPOLEUICHANGESOURCE lpCS)
+{
+ HGLOBAL hMemDlg = NULL;
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpCS,
+ sizeof(OLEUICHANGESOURCE), &hMemDlg);
+
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+
+ HCURSOR hCurSave = NULL;
+
+ // validate contents of lpCS
+ if (lpCS->lpOleUILinkContainer == NULL)
+ {
+ uRet = OLEUI_CSERR_LINKCNTRNULL;
+ goto Error;
+ }
+ if (!IsValidInterface(lpCS->lpOleUILinkContainer))
+ {
+ uRet = OLEUI_CSERR_LINKCNTRINVALID;
+ goto Error;
+ }
+
+ // lpszFrom and lpszTo must be NULL (they are out only)
+ if (lpCS->lpszFrom != NULL)
+ {
+ uRet = OLEUI_CSERR_FROMNOTNULL;
+ goto Error;
+ }
+ if (lpCS->lpszTo != NULL)
+ {
+ uRet = OLEUI_CSERR_TONOTNULL;
+ goto Error;
+ }
+
+ // lpszDisplayName must be valid or NULL
+ if (lpCS->lpszDisplayName != NULL &&
+ IsBadStringPtr(lpCS->lpszDisplayName, (UINT)-1))
+ {
+ uRet = OLEUI_CSERR_SOURCEINVALID;
+ goto Error;
+ }
+
+ hCurSave = HourGlassOn();
+
+ // attempt to retrieve link source if not provided
+ if (lpCS->lpszDisplayName == NULL)
+ {
+ if (NOERROR != lpCS->lpOleUILinkContainer->GetLinkSource(
+ lpCS->dwLink, &lpCS->lpszDisplayName, &lpCS->nFileLength,
+ NULL, NULL, NULL, NULL))
+ {
+ uRet = OLEUI_CSERR_SOURCEINVALID;
+ goto Error;
+ }
+ }
+
+ // verify that nFileLength is valid
+ if ((UINT)lstrlen(lpCS->lpszDisplayName) < lpCS->nFileLength)
+ {
+ uRet = OLEUI_CSERR_SOURCEINVALID;
+ goto Error;
+ }
+
+ // allocate file buffer and split directory and file name
+ UINT nFileLength; nFileLength = lpCS->nFileLength;
+ UINT nFileBuf; nFileBuf = max(nFileLength+1, MAX_PATH);
+ LPTSTR lpszFileBuf;
+ LPTSTR lpszDirBuf; lpszDirBuf = (LPTSTR)OleStdMalloc(nFileBuf * sizeof(TCHAR));
+ if (lpszDirBuf == NULL)
+ {
+ uRet = OLEUI_ERR_OLEMEMALLOC;
+ goto Error;
+ }
+ lstrcpyn(lpszDirBuf, lpCS->lpszDisplayName, nFileLength+1);
+
+ UINT nFileLen; nFileLen = GetFileName(lpszDirBuf, NULL, 0);
+
+ lpszFileBuf = (LPTSTR)OleStdMalloc(nFileBuf * sizeof(TCHAR));
+ if (lpszFileBuf == NULL)
+ {
+ uRet = OLEUI_ERR_OLEMEMALLOC;
+ goto ErrorFreeDirBuf;
+ }
+ memmove(lpszFileBuf, lpszDirBuf+nFileLength-nFileLen+1,
+ (nFileLen+1)*sizeof(TCHAR));
+ lpszDirBuf[nFileLength-(nFileLen - 1)] = 0;
+
+ // start filling the OPENFILENAME struct
+ OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn));
+ ofn.lpstrFile = lpszFileBuf;
+ ofn.nMaxFile = nFileBuf;
+ ofn.lpstrInitialDir = lpszDirBuf;
+
+ // load filter strings
+ TCHAR szFilters[MAX_PATH];
+ if (!LoadString(_g_hOleStdResInst, IDS_FILTERS, szFilters, MAX_PATH))
+ szFilters[0] = 0;
+ else
+ ReplaceCharWithNull(szFilters, szFilters[lstrlen(szFilters)-1]);
+ ofn.lpstrFilter = szFilters;
+ ofn.nFilterIndex = 1;
+
+ TCHAR szTitle[MAX_PATH];
+
+ // set the caption
+ if (NULL!=lpCS->lpszCaption)
+ ofn.lpstrTitle = lpCS->lpszCaption;
+ else
+ {
+ LoadString(_g_hOleStdResInst, IDS_CHANGESOURCE, szTitle, MAX_PATH);
+ ofn.lpstrTitle = szTitle;
+ }
+
+ // fill in rest of OPENFILENAME struct
+ ofn.hwndOwner = lpCS->hWndOwner;
+ ofn.lStructSize = sizeof(ofn);
+ ofn.Flags = OFN_HIDEREADONLY | OFN_ENABLEHOOK;
+ if (bWin4 && ((NULL == lpCS->hInstance && NULL == lpCS->hResource)
+ || 0 != (lpCS->dwFlags & CSF_EXPLORER)))
+ ofn.Flags |= OFN_EXPLORER;
+ if (lpCS->dwFlags & CSF_SHOWHELP)
+ ofn.Flags |= OFN_SHOWHELP;
+ ofn.lCustData = (LPARAM)lpCS;
+ ofn.lpfnHook = ChangeSourceHookProc;
+ ofn.lCustData = (LPARAM)lpCS;
+ lpCS->lpOFN = &ofn; // needed sometimes in hook proc
+
+ // allow hooking of the dialog resource
+ if (lpCS->hResource != NULL)
+ {
+ ofn.hInstance = (HINSTANCE)lpCS->hResource;
+ ofn.lpTemplateName = (LPCTSTR)lpCS->hResource;
+ ofn.Flags |= OFN_ENABLETEMPLATEHANDLE;
+ }
+ else
+ {
+ if (lpCS->hInstance == NULL)
+ {
+ ofn.hInstance = _g_hOleStdResInst;
+ ofn.lpTemplateName = bWin4 ?
+ MAKEINTRESOURCE(IDD_CHANGESOURCE4) : MAKEINTRESOURCE(IDD_CHANGESOURCE);
+ ofn.Flags |= OFN_ENABLETEMPLATE;
+ }
+ else
+ {
+ ofn.hInstance = lpCS->hInstance;
+ ofn.lpTemplateName = lpCS->lpszTemplate;
+ ofn.Flags |= OFN_ENABLETEMPLATE;
+ }
+ }
+
+ if (lpCS->hWndOwner != NULL)
+ {
+ // allow hooking of the OFN struct
+ SendMessage(lpCS->hWndOwner, uMsgBrowseOFN, ID_BROWSE_CHANGESOURCE, (LPARAM)&ofn);
+ }
+
+ // call up the dialog
+ BOOL bResult;
+
+ bResult = StandardGetOpenFileName(&ofn);
+
+ // cleanup
+ OleStdFree(lpszDirBuf);
+ OleStdFree(lpszFileBuf);
+
+ HourGlassOff(hCurSave);
+
+ // map return value to OLEUI_ standard returns
+ return bResult ? OLEUI_OK : OLEUI_CANCEL;
+
+// handle most error returns here
+ErrorFreeDirBuf:
+ OleStdFree(lpszDirBuf);
+
+Error:
+ if (hCurSave != NULL)
+ HourGlassOff(hCurSave);
+ return uRet;
+}
+
+/*
+ * ChangeSourceHookProc
+ *
+ * Purpose:
+ * Implements the OLE Change Source dialog as invoked through the
+ * OleUIChangeSource function. This is a standard COMMDLG hook function
+ * as opposed to a dialog proc.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ */
+UINT CALLBACK ChangeSourceHookProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uHook = 0;
+ LPCHANGESOURCE lpCS = (LPCHANGESOURCE)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
+
+ LPOLEUICHANGESOURCE lpOCS = NULL;
+ if (lpCS != NULL)
+ lpOCS = lpCS->lpOCS;
+
+ // If the hook processed the message, we're done.
+ if (0 != uHook)
+ return uHook;
+
+ // Process help message
+ if ((iMsg == uMsgHelp) && NULL != lpOCS)
+ {
+ PostMessage(lpOCS->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_CHANGESOURCE, 0));
+ }
+
+ // Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ // Free any specific allocations before calling StandardCleanup
+ StandardCleanup((PVOID)lpCS, hDlg);
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ // handle validation of the file name (when user hits OK)
+ if (iMsg == uMsgFileOKString)
+ {
+ // always use fully qualified name
+ LPOPENFILENAME lpOFN = lpOCS->lpOFN;
+ LPCTSTR lpsz = lpOFN->lpstrFile;
+ LPTSTR lpszFile;
+ TCHAR szPath[MAX_PATH];
+ if (!GetFullPathName(lpsz, MAX_PATH, szPath, &lpszFile))
+ lstrcpyn(szPath, lpsz, MAX_PATH);
+ UINT nLenFile = lstrlen(szPath);
+ TCHAR szItemName[MAX_PATH];
+ GetDlgItemText(hDlg, edt2, szItemName, MAX_PATH);
+
+ // combine them into szDisplayName (which is now large enough)
+ TCHAR szDisplayName[MAX_PATH+MAX_PATH];
+ lstrcpy(szDisplayName, szPath);
+ if (szItemName[0] != '\0')
+ {
+ lstrcat(szDisplayName, TEXT("\\"));
+ lstrcat(szDisplayName, szItemName);
+ }
+
+ if (!(lpOCS->dwFlags & CSF_ONLYGETSOURCE))
+ {
+ // verify the source by calling into the link container
+ LPOLEUILINKCONTAINER lpOleUILinkCntr = lpOCS->lpOleUILinkContainer;
+ ULONG chEaten;
+ if (lpOleUILinkCntr->SetLinkSource(lpOCS->dwLink, szDisplayName, nLenFile,
+ &chEaten, TRUE) != NOERROR)
+ {
+ // link not verified ok
+ lpOCS->dwFlags &= ~CSF_VALIDSOURCE;
+ UINT uRet = PopupMessage(hDlg, IDS_CHANGESOURCE, IDS_INVALIDSOURCE,
+ MB_ICONQUESTION | MB_YESNO);
+ if (uRet == IDYES)
+ {
+ SetWindowLong(hDlg, DWL_MSGRESULT, 1);
+ return 1; // do not close dialog
+ }
+
+ // user doesn't care if the link is valid or not
+ lpOleUILinkCntr->SetLinkSource(lpOCS->dwLink, szDisplayName, nLenFile,
+ &chEaten, FALSE);
+ }
+ else
+ {
+ // link was verified ok
+ lpOCS->dwFlags |= CSF_VALIDSOURCE;
+ }
+ }
+
+ // calculate lpszFrom and lpszTo for batch changes to links
+ DiffPrefix(lpOCS->lpszDisplayName, szDisplayName, &lpOCS->lpszFrom, &lpOCS->lpszTo);
+
+ // only keep them if the file name portion is the only part that changed
+ if (lstrcmpi(lpOCS->lpszTo, lpOCS->lpszFrom) == 0 ||
+ (UINT)lstrlen(lpOCS->lpszFrom) > lpOCS->nFileLength)
+ {
+ OleStdFree(lpOCS->lpszFrom);
+ lpOCS->lpszFrom = NULL;
+
+ OleStdFree(lpOCS->lpszTo);
+ lpOCS->lpszTo = NULL;
+ }
+
+ // store new source in lpOCS->lpszDisplayName
+ OleStdFree(lpOCS->lpszDisplayName);
+ lpOCS->lpszDisplayName = OleStdCopyString(szDisplayName);
+ lpOCS->nFileLength = nLenFile;
+
+ return 0;
+ }
+
+ switch (iMsg)
+ {
+ case WM_NOTIFY:
+ if (((NMHDR*)lParam)->code == CDN_HELP)
+ {
+ goto POSTHELP;
+ }
+ break;
+ case WM_COMMAND:
+ if (wID == pshHelp)
+ {
+POSTHELP:
+ PostMessage(lpCS->lpOCS->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_CHANGESOURCE, 0));
+ }
+ break;
+ case WM_INITDIALOG:
+ return FChangeSourceInit(hDlg, wParam, lParam);
+ }
+
+ return 0;
+}
+
+/*
+ * FChangeSourceInit
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the Change Source dialog box.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+BOOL FChangeSourceInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ LPCHANGESOURCE lpCS = (LPCHANGESOURCE)LpvStandardInit(hDlg, sizeof(CHANGESOURCE), NULL);
+
+ // PvStandardInit send a termination to us already.
+ if (NULL == lpCS)
+ return FALSE;
+
+ LPOLEUICHANGESOURCE lpOCS=
+ (LPOLEUICHANGESOURCE)((LPOPENFILENAME)lParam)->lCustData;
+ lpCS->lpOCS = lpOCS;
+ lpCS->nIDD = IDD_CHANGESOURCE;
+
+ // Setup Item text box with item part of lpszDisplayName
+ LPTSTR lpszItemName = lpOCS->lpszDisplayName + lpOCS->nFileLength;
+ if (*lpszItemName != '\0')
+ SetDlgItemText(hDlg, edt2, lpszItemName+1);
+ SendDlgItemMessage(hDlg, edt2, EM_LIMITTEXT, MAX_PATH, 0L);
+
+ // Change the caption
+ if (NULL!=lpOCS->lpszCaption)
+ SetWindowText(hDlg, lpOCS->lpszCaption);
+
+ // Call the hook with lCustData in lParam
+ UStandardHook((PVOID)lpCS, hDlg, WM_INITDIALOG, wParam, lpOCS->lCustData);
+#ifdef CHICO
+ TCHAR szTemp[MAX_PATH];
+ LoadString(_g_hOleStdResInst, IDS_CHNGSRCOKBUTTON , szTemp, MAX_PATH);
+ CommDlg_OpenSave_SetControlText(GetParent(hDlg), IDOK, szTemp);
+#endif
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
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;
+}
+
diff --git a/private/ole2ui32/common.h b/private/ole2ui32/common.h
new file mode 100644
index 000000000..fbbd585bf
--- /dev/null
+++ b/private/ole2ui32/common.h
@@ -0,0 +1,154 @@
+/*
+ * COMMON.H
+ *
+ * Structures and definitions applicable to all OLE 2.0 UI dialogs.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+// Macros to handle control message packing between Win16 and Win32
+#ifndef COMMANDPARAMS
+#define COMMANDPARAMS(wID, wCode, hWndMsg) \
+ WORD wID = LOWORD(wParam); \
+ WORD wCode = HIWORD(wParam); \
+ HWND hWndMsg = (HWND)(UINT)lParam;
+#endif
+
+#ifndef SendCommand
+#define SendCommand(hWnd, wID, wCode, hControl) \
+ SendMessage(hWnd, WM_COMMAND, MAKELONG(wID, wCode) \
+ , (LPARAM)hControl)
+#endif
+
+// Property labels used to store dialog structures and fonts
+#define STRUCTUREPROP TEXT("Structure")
+#define FONTPROP TEXT("Font")
+
+#ifndef WM_HELP
+
+// WM_HELP is new Windows 95 help message
+#define WM_HELP 0x0053
+// WM_CONTEXTMENU is new Windows 95 right button menus
+#define WM_CONTEXTMENU 0x007B
+
+typedef struct tagHELPINFO /* Structure pointed to by lParam of WM_HELP */
+{
+ UINT cbSize; /* Size in bytes of this struct */
+ int iContextType; /* Either HELPINFO_WINDOW or HELPINFO_MENUITEM */
+ int iCtrlId; /* Control Id or a Menu item Id. */
+ HANDLE hItemHandle; /* hWnd of control or hMenu. */
+ DWORD dwContextId; /* Context Id associated with this item */
+ POINT MousePos; /* Mouse Position in screen co-ordinates */
+} HELPINFO, FAR *LPHELPINFO;
+
+#define HELP_CONTEXTMENU 0x000a
+#define HELP_WM_HELP 0x000c
+
+#endif //!WM_HELP
+
+
+#ifndef WS_EX_CONTEXTHELP
+#define WS_EX_CONTEXTHELP 0x0400L
+#endif
+
+#ifndef OFN_EXPLORER
+#define OFN_EXPLORER 0x00080000
+#endif
+
+#ifndef WS_EX_CLIENTEDGE
+#define WS_EX_CLIENTEDGE 0x200
+#endif
+
+
+/*
+ * Standard structure for all dialogs. This commonality lets us make
+ * a single piece of code that will validate this entire structure and
+ * perform any necessary initialization.
+ */
+
+typedef struct tagOLEUISTANDARD
+{
+ // These IN fields are standard across all OLEUI dialog functions.
+ DWORD cbStruct; // Structure Size
+ DWORD dwFlags; // IN-OUT: Flags
+ HWND hWndOwner; // Owning window
+ LPCTSTR lpszCaption; // Dialog caption bar contents
+ LPFNOLEUIHOOK lpfnHook; // Hook callback
+ LPARAM lCustData; // Custom data to pass to hook
+ HINSTANCE hInstance; // Instance for customized template name
+ LPCTSTR lpszTemplate; // Customized template name
+ HRSRC hResource; // Customized template handle
+
+} OLEUISTANDARD, *POLEUISTANDARD, FAR *LPOLEUISTANDARD;
+
+// Function prototypes
+// COMMON.CPP
+
+UINT WINAPI UStandardValidation(LPOLEUISTANDARD, const UINT, HGLOBAL*);
+UINT WINAPI UStandardInvocation(DLGPROC, LPOLEUISTANDARD, HGLOBAL, LPTSTR);
+LPVOID WINAPI LpvStandardInit(HWND, UINT, HFONT* = NULL);
+LPVOID WINAPI LpvStandardEntry(HWND, UINT, WPARAM, LPARAM, UINT FAR *);
+UINT WINAPI UStandardHook(LPVOID, HWND, UINT, WPARAM, LPARAM);
+void WINAPI StandardCleanup(LPVOID, HWND);
+void WINAPI StandardShowDlgItem(HWND hDlg, int idControl, int nCmdShow);
+void WINAPI StandardEnableDlgItem(HWND hDlg, int idControl, BOOL bEnable);
+BOOL WINAPI StandardResizeDlgY(HWND hDlg);
+void WINAPI StandardHelp(HWND, UINT);
+void WINAPI StandardContextMenu(WPARAM, LPARAM, UINT nIDD);
+UINT InternalObjectProperties(LPOLEUIOBJECTPROPS lpOP, BOOL fWide);
+int WINAPI StandardPropertySheet(LPPROPSHEETHEADER lpPS, BOOL fWide);
+int WINAPI StandardInitCommonControls();
+HICON StandardExtractIcon(HINSTANCE hInst, LPCTSTR lpszExeFileName, UINT nIconIndex);
+BOOL StandardGetOpenFileName(LPOPENFILENAME lpofn);
+short StandardGetFileTitle(LPCTSTR lpszFile, LPTSTR lpszTitle, WORD cbBuf);
+
+// shared globals: registered messages
+extern UINT uMsgHelp;
+extern UINT uMsgEndDialog;
+extern UINT uMsgBrowse;
+extern UINT uMsgChangeIcon;
+extern UINT uMsgFileOKString;
+extern UINT uMsgCloseBusyDlg;
+extern UINT uMsgConvert;
+extern UINT uMsgChangeSource;
+extern UINT uMsgAddControl;
+extern UINT uMsgBrowseOFN;
+
+typedef struct tagTASKDATA
+{
+ HINSTANCE hInstCommCtrl;
+ HINSTANCE hInstShell;
+ HINSTANCE hInstComDlg;
+} TASKDATA;
+
+STDAPI_(TASKDATA*) GetTaskData(); // returns TASKDATA for current process
+
+extern BOOL bWin4; // TRUE if running Win4 or greater
+extern BOOL bSharedData; // TRUE if runing Win32s
+
+/////////////////////////////////////////////////////////////////////////////
+// Maximum buffer sizes
+
+// Maximum key size we read from the RegDB.
+#define OLEUI_CCHKEYMAX 256 // same in geticon.c too
+#define OLEUI_CCHKEYMAX_SIZE OLEUI_CCHKEYMAX*sizeof(TCHAR)
+
+// Maximum length of Object menu
+#define OLEUI_OBJECTMENUMAX 256
+
+// Maximim length of a path in BYTEs
+#define MAX_PATH_SIZE (MAX_PATH*sizeof(TCHAR))
+
+// Icon label length
+#define OLEUI_CCHLABELMAX 40 // same in geticon.c too
+#define OLEUI_CCHLABELMAX_SIZE OLEUI_CCHLABELMAX*sizeof(TCHAR)
+
+// Length of the CLSID string
+#define OLEUI_CCHCLSIDSTRING 39
+#define OLEUI_CCHCLSIDSTRING_SIZE OLEUI_CCHCLSIDSTRING*sizeof(TCHAR)
+
+#endif //_COMMON_H_
diff --git a/private/ole2ui32/convert.cpp b/private/ole2ui32/convert.cpp
new file mode 100644
index 000000000..928ef4438
--- /dev/null
+++ b/private/ole2ui32/convert.cpp
@@ -0,0 +1,1424 @@
+/*
+ * CONVERT.CPP
+ *
+ * Implements the OleUIConvert function which invokes the complete
+ * Convert dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include <stdlib.h>
+#include "utility.h"
+#include "iconbox.h"
+
+OLEDBGDATA
+
+// Internally used structure
+typedef struct tagCONVERT
+{
+ // Keep this item first as the Standard* functions depend on it here.
+ LPOLEUICONVERT lpOCV; // Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ /*
+ * What we store extra in this structure besides the original caller's
+ * pointer are those fields that we need to modify during the life of
+ * the dialog but that we don't want to change in the original structure
+ * until the user presses OK.
+ */
+
+ DWORD dwFlags; // Flags passed in
+ HWND hListVisible; // listbox that is currently visible
+ HWND hListInvisible; // listbox that is currently hidden
+ CLSID clsid; // Class ID sent in to dialog: IN only
+ DWORD dvAspect;
+ BOOL fCustomIcon;
+ UINT IconIndex; // index (in exe) of current icon
+ LPTSTR lpszIconSource; // path to current icon source
+ LPTSTR lpszCurrentObject;
+ LPTSTR lpszConvertDefault;
+ LPTSTR lpszActivateDefault;
+
+} CONVERT, *PCONVERT, FAR *LPCONVERT;
+
+// Internal function prototypes
+// CONVERT.CPP
+
+BOOL CALLBACK ConvertDialogProc(HWND, UINT, WPARAM, LPARAM);
+BOOL FConvertInit(HWND hDlg, WPARAM, LPARAM);
+void SetConvertResults(HWND, LPCONVERT);
+UINT FillClassList(CLSID clsid, HWND hList, HWND hListInvisible,
+ LPTSTR FAR *lplpszCurrentClass, BOOL fIsLinkedObject, WORD wFormat,
+ UINT cClsidExclude, LPCLSID lpClsidExclude, BOOL bAddSameClass);
+BOOL FormatIncluded(LPTSTR szStringToSearch, WORD wFormat);
+void SwapWindows(HWND, HWND, HWND);
+void ConvertCleanup(HWND hDlg, LPCONVERT lpCV);
+static void UpdateClassIcon(HWND hDlg, LPCONVERT lpCV, HWND hList);
+
+/*
+ * OleUIConvert
+ *
+ * Purpose:
+ * Invokes the standard OLE Change Type dialog box allowing the user
+ * to change the type of the single specified object, or change the
+ * type of all OLE objects of a specified type.
+ *
+ * Parameters:
+ * lpCV LPOLEUICONVERT pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * UINT One of the following codes, indicating success or error:
+ * OLEUI_SUCCESS Success
+ * OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
+ */
+STDAPI_(UINT) OleUIConvert(LPOLEUICONVERT lpCV)
+{
+ HGLOBAL hMemDlg = NULL;
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpCV, sizeof(OLEUICONVERT),
+ &hMemDlg);
+
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+ if (lpCV->hMetaPict != NULL && !IsValidMetaPict(lpCV->hMetaPict))
+ {
+ return(OLEUI_CTERR_HMETAPICTINVALID);
+ }
+
+ if ((lpCV->dwFlags & CF_SETCONVERTDEFAULT)
+ && (!IsValidClassID(lpCV->clsidConvertDefault)))
+ uRet = OLEUI_CTERR_CLASSIDINVALID;
+
+ if ((lpCV->dwFlags & CF_SETACTIVATEDEFAULT)
+ && (!IsValidClassID(lpCV->clsidActivateDefault)))
+ uRet = OLEUI_CTERR_CLASSIDINVALID;
+
+ if ((lpCV->dvAspect != DVASPECT_ICON) && (lpCV->dvAspect != DVASPECT_CONTENT))
+ uRet = OLEUI_CTERR_DVASPECTINVALID;
+
+ if ((lpCV->wFormat >= CF_CLIPBOARDMIN) && (lpCV->wFormat <= CF_CLIPBOARDMAX))
+ {
+ TCHAR szTemp[8];
+ if (0 == GetClipboardFormatName(lpCV->wFormat, szTemp, 8))
+ uRet = OLEUI_CTERR_CBFORMATINVALID;
+ }
+
+ if ((NULL != lpCV->lpszUserType)
+ && (IsBadReadPtr(lpCV->lpszUserType, 1)))
+ uRet = OLEUI_CTERR_STRINGINVALID;
+
+ if ( (NULL != lpCV->lpszDefLabel)
+ && (IsBadReadPtr(lpCV->lpszDefLabel, 1)) )
+ uRet = OLEUI_CTERR_STRINGINVALID;
+
+ if (0 != lpCV->cClsidExclude &&
+ IsBadReadPtr(lpCV->lpClsidExclude, lpCV->cClsidExclude * sizeof(CLSID)))
+ {
+ uRet = OLEUI_IOERR_LPCLSIDEXCLUDEINVALID;
+ }
+
+ if (OLEUI_ERR_STANDARDMIN <= uRet)
+ {
+ return uRet;
+ }
+
+ UINT nIDD;
+ if (!bWin4)
+ nIDD = lpCV->dwFlags & CF_CONVERTONLY ? IDD_CONVERTONLY : IDD_CONVERT;
+ else
+ nIDD = lpCV->dwFlags & CF_CONVERTONLY ? IDD_CONVERTONLY4 : IDD_CONVERT4;
+
+ // Now that we've validated everything, we can invoke the dialog.
+ uRet = UStandardInvocation(ConvertDialogProc, (LPOLEUISTANDARD)lpCV,
+ hMemDlg, MAKEINTRESOURCE(nIDD));
+ return uRet;
+}
+
+/*
+ * ConvertDialogProc
+ *
+ * Purpose:
+ * Implements the OLE Convert dialog as invoked through the
+ * OleUIConvert function.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ *
+ */
+BOOL CALLBACK ConvertDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uRet = 0;
+ LPCONVERT lpCV = (LPCONVERT)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
+
+ //If the hook processed the message, we're done.
+ if (0 != uRet)
+ return (BOOL)uRet;
+
+ //Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ // Process help message from Change Icon
+ if (iMsg == uMsgHelp)
+ {
+ PostMessage(lpCV->lpOCV->hWndOwner, uMsgHelp, wParam, lParam);
+ return FALSE;
+ }
+
+ switch (iMsg)
+ {
+ case WM_DESTROY:
+ if (lpCV)
+ {
+ ConvertCleanup(hDlg, lpCV);
+ StandardCleanup(lpCV, hDlg);
+ }
+ break;
+ case WM_INITDIALOG:
+ FConvertInit(hDlg, wParam, lParam);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_CV_ACTIVATELIST:
+ case IDC_CV_CONVERTLIST:
+ switch (wCode)
+ {
+ case LBN_SELCHANGE:
+ // Change "Results" window to reflect current selection
+ SetConvertResults(hDlg, lpCV);
+
+ // Update the icon we display, if in display as icon mode
+ if ((lpCV->dwFlags & CF_SELECTCONVERTTO) &&
+ lpCV->dvAspect == DVASPECT_ICON && !lpCV->fCustomIcon)
+ {
+ UpdateClassIcon(hDlg, lpCV, hWndMsg);
+ }
+ break;
+
+ case LBN_DBLCLK:
+ SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
+ break;
+ }
+ break;
+
+ case IDC_CV_CONVERTTO:
+ case IDC_CV_ACTIVATEAS:
+ {
+ HWND hList = lpCV->hListVisible;
+ HWND hListInvisible = lpCV->hListInvisible;
+
+ if (IDC_CV_CONVERTTO == wParam)
+ {
+ // User just click on the button again - it was
+ // already selected.
+ if (lpCV->dwFlags & CF_SELECTCONVERTTO)
+ break;
+
+ // If we're working with a linked object, don't
+ // add the activate list - just the object's
+ // class should appear in the listbox.
+ SwapWindows(hDlg, hList, hListInvisible);
+
+ lpCV->hListVisible = hListInvisible;
+ lpCV->hListInvisible = hList;
+
+ EnableWindow(lpCV->hListInvisible, FALSE);
+ EnableWindow(lpCV->hListVisible, TRUE);
+
+ // Update our flags.
+ lpCV->dwFlags &= ~CF_SELECTACTIVATEAS;
+ lpCV->dwFlags |= CF_SELECTCONVERTTO;
+ }
+ else
+ {
+ if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
+ break;
+
+ SwapWindows(hDlg, hList, hListInvisible);
+
+ lpCV->hListVisible = hListInvisible;
+ lpCV->hListInvisible = hList;
+
+ EnableWindow(lpCV->hListInvisible, FALSE);
+ EnableWindow(lpCV->hListVisible, TRUE);
+
+ // Update our flags.
+ lpCV->dwFlags |= CF_SELECTACTIVATEAS;
+ lpCV->dwFlags &= ~CF_SELECTCONVERTTO;
+ }
+
+ LRESULT lRetVal;
+ if (lpCV->dwFlags & CF_SELECTCONVERTTO)
+ lRetVal = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszConvertDefault);
+ else
+ lRetVal = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszActivateDefault);
+
+ if (LB_ERR == lRetVal)
+ {
+ TCHAR szCurrentObject[40];
+ GetDlgItemText(hDlg, IDC_CV_OBJECTTYPE, szCurrentObject, 40);
+ SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)szCurrentObject);
+ }
+
+ // Turn updates back on.
+ SendMessage(hDlg, WM_SETREDRAW, TRUE, 0L);
+
+ InvalidateRect(lpCV->hListVisible, NULL, TRUE);
+ UpdateWindow(lpCV->hListVisible);
+
+ if ((lpCV->dvAspect & DVASPECT_ICON) && (lpCV->dwFlags & CF_SELECTCONVERTTO))
+ UpdateClassIcon(hDlg, lpCV, lpCV->hListVisible);
+
+ // Hide the icon stuff when Activate is selected...show
+ // it again when Convert is selected.
+ BOOL fState = ((lpCV->dwFlags & CF_SELECTACTIVATEAS) ||
+ (lpCV->dwFlags & CF_DISABLEDISPLAYASICON)) ?
+ SW_HIDE : SW_SHOW;
+
+ StandardShowDlgItem(hDlg, IDC_CV_DISPLAYASICON, fState);
+
+ // Only display the icon if convert is selected AND
+ // display as icon is checked.
+ if ((SW_SHOW==fState) && (DVASPECT_ICON!=lpCV->dvAspect))
+ fState = SW_HIDE;
+
+ StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, fState);
+ StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, fState);
+
+ SetConvertResults(hDlg, lpCV);
+ }
+ break;
+
+ case IDOK:
+ {
+ // Set output flags to current ones
+ lpCV->lpOCV->dwFlags = lpCV->dwFlags;
+
+ // Update the dvAspect and fObjectsIconChanged members
+ // as appropriate.
+ if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
+ {
+ // DON'T update aspect if activate as was selected.
+ lpCV->lpOCV->fObjectsIconChanged = FALSE;
+ }
+ else
+ lpCV->lpOCV->dvAspect = lpCV->dvAspect;
+
+ // Get the new clsid
+ TCHAR szBuffer[256];
+ LRESULT iCurSel = SendMessage(lpCV->hListVisible, LB_GETCURSEL, 0, 0);
+ SendMessage(lpCV->hListVisible, LB_GETTEXT, iCurSel, (LPARAM)szBuffer);
+
+ LPTSTR lpszCLSID = PointerToNthField(szBuffer, 2, '\t');
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszCLSID[OLEUI_CCHKEYMAX];
+ ATOW(wszCLSID, lpszCLSID, OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszCLSID, (&(lpCV->lpOCV->clsidNew)));
+#else
+ CLSIDFromString(lpszCLSID, (&(lpCV->lpOCV->clsidNew)));
+#endif
+
+ // Free the hMetaPict we got in.
+ OleUIMetafilePictIconFree(lpCV->lpOCV->hMetaPict);
+
+ // Get the hMetaPict (if display as icon is checked)
+ if (DVASPECT_ICON == lpCV->dvAspect)
+ lpCV->lpOCV->hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
+ IDC_CV_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ else
+ lpCV->lpOCV->hMetaPict = (HGLOBAL)NULL;
+
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ }
+ break;
+
+ case IDCANCEL:
+ {
+ HGLOBAL hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
+ IDC_CV_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ OleUIMetafilePictIconFree(hMetaPict);
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
+ }
+ break;
+
+ case IDC_OLEUIHELP:
+ PostMessage(lpCV->lpOCV->hWndOwner,
+ uMsgHelp, (WPARAM)hDlg, MAKELPARAM(IDD_CONVERT, 0));
+ break;
+
+ case IDC_CV_DISPLAYASICON:
+ {
+ BOOL fCheck = IsDlgButtonChecked(hDlg, wID);
+ if (fCheck)
+ lpCV->dvAspect = DVASPECT_ICON;
+ else
+ lpCV->dvAspect = DVASPECT_CONTENT;
+
+ if (fCheck && !lpCV->fCustomIcon)
+ UpdateClassIcon(hDlg, lpCV, lpCV->hListVisible);
+
+ // Show or hide the icon depending on the check state.
+ int i = (fCheck) ? SW_SHOWNORMAL : SW_HIDE;
+ StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, i);
+ StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, i);
+ SetConvertResults(hDlg, lpCV);
+ }
+ break;
+
+ case IDC_CV_CHANGEICON:
+ {
+ // Initialize the structure for the hook.
+ OLEUICHANGEICON ci; memset(&ci, 0, sizeof(ci));
+
+ ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
+ IDC_CV_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ ci.cbStruct = sizeof(ci);
+ ci.hWndOwner= hDlg;
+ ci.dwFlags = CIF_SELECTCURRENT;
+
+ // Only show help if we're showing it for this dialog.
+ if (lpCV->dwFlags & CF_SHOWHELPBUTTON)
+ ci.dwFlags |= CIF_SHOWHELP;
+
+ int iSel = (INT)SendMessage(lpCV->hListVisible, LB_GETCURSEL, 0, 0);
+
+ // Get whole string
+ LPTSTR pszString = (LPTSTR)OleStdMalloc(
+ OLEUI_CCHLABELMAX_SIZE + OLEUI_CCHCLSIDSTRING_SIZE);
+
+ SendMessage(lpCV->hListVisible, LB_GETTEXT, iSel, (LPARAM)pszString);
+
+ // Set pointer to CLSID (string)
+ LPTSTR pszCLSID = PointerToNthField(pszString, 2, '\t');
+
+ // Get the clsid to pass to change icon.
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszCLSID[OLEUI_CCHKEYMAX];
+ ATOW(wszCLSID, pszCLSID, OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszCLSID, &(ci.clsid));
+#else
+ CLSIDFromString(pszCLSID, &(ci.clsid));
+#endif
+ OleStdFree(pszString);
+
+ // Let the hook in to customize Change Icon if desired.
+ uRet = UStandardHook(lpCV, hDlg, uMsgChangeIcon, 0, (LPARAM)&ci);
+
+ if (0 == uRet)
+ uRet= (OLEUI_OK == OleUIChangeIcon(&ci));
+
+ // Update the display if necessary.
+ if (0 != uRet)
+ {
+ SendDlgItemMessage(hDlg, IDC_CV_ICONDISPLAY, IBXM_IMAGESET, 0,
+ (LPARAM)ci.hMetaPict);
+
+ // Update our custom/default flag
+ if (ci.dwFlags & CIF_SELECTDEFAULT)
+ lpCV->fCustomIcon = FALSE; // we're in default mode (icon changes on each LB selchange)
+ else if (ci.dwFlags & CIF_SELECTFROMFILE)
+ lpCV->fCustomIcon = TRUE; // we're in custom mode (icon doesn't change)
+
+ // no change in fCustomIcon if user selected current
+ lpCV->lpOCV->fObjectsIconChanged = TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * FConvertInit
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the Convert dialog box.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+BOOL FConvertInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ HFONT hFont; // non-bold version of dialog's font
+ LPCONVERT lpCV = (LPCONVERT)LpvStandardInit(hDlg, sizeof(CONVERT), &hFont);
+
+ // PvStandardInit send a termination to us already.
+ if (NULL == lpCV)
+ return FALSE;
+
+ LPOLEUICONVERT lpOCV = (LPOLEUICONVERT)lParam;
+ lpCV->lpOCV = lpOCV;
+ lpCV->nIDD = IDD_CONVERT;
+ lpCV->fCustomIcon = FALSE;
+
+ // Copy other information from lpOCV that we might modify.
+ lpCV->dwFlags = lpOCV->dwFlags;
+ lpCV->clsid = lpOCV->clsid;
+ lpCV->dvAspect = lpOCV->dvAspect;
+ lpCV->hListVisible = GetDlgItem(hDlg, IDC_CV_ACTIVATELIST);
+ lpCV->hListInvisible = GetDlgItem(hDlg, IDC_CV_CONVERTLIST);
+ OleDbgAssert(lpCV->hListInvisible != NULL);
+ lpCV->lpszCurrentObject = lpOCV->lpszUserType;
+ lpOCV->clsidNew = CLSID_NULL;
+ lpOCV->fObjectsIconChanged = FALSE;
+
+ lpCV->lpszConvertDefault = (LPTSTR)OleStdMalloc(OLEUI_CCHLABELMAX_SIZE);
+ lpCV->lpszActivateDefault = (LPTSTR)OleStdMalloc(OLEUI_CCHLABELMAX_SIZE);
+ lpCV->lpszIconSource = (LPTSTR)OleStdMalloc(MAX_PATH_SIZE);
+
+ // If we got a font, send it to the necessary controls.
+ if (NULL != hFont)
+ {
+ SendDlgItemMessage(hDlg, IDC_CV_OBJECTTYPE, WM_SETFONT, (WPARAM)hFont, 0L);
+ SendDlgItemMessage(hDlg, IDC_CV_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L);
+ }
+
+ // Hide the help button if necessary
+ if (!(lpCV->dwFlags & CF_SHOWHELPBUTTON))
+ StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
+
+ // Show or hide the Change icon button
+ if (lpCV->dwFlags & CF_HIDECHANGEICON)
+ DestroyWindow(GetDlgItem(hDlg, IDC_CV_CHANGEICON));
+
+ // Fill the Object Type listbox with entries from the reg DB.
+ UINT nRet = FillClassList(lpOCV->clsid, lpCV->hListVisible,
+ lpCV->hListInvisible, &(lpCV->lpszCurrentObject),
+ lpOCV->fIsLinkedObject, lpOCV->wFormat,
+ lpOCV->cClsidExclude, lpOCV->lpClsidExclude,
+ !(lpCV->dwFlags & CF_CONVERTONLY));
+
+ if (nRet == -1)
+ {
+ // bring down dialog if error when filling list box
+ PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L);
+ }
+
+ // Set the name of the current object.
+ SetDlgItemText(hDlg, IDC_CV_OBJECTTYPE, lpCV->lpszCurrentObject);
+
+ // Disable the "Activate As" button if the Activate list doesn't
+ // have any objects in it.
+ int cItemsActivate = (INT)SendMessage(lpCV->hListVisible, LB_GETCOUNT, 0, 0L);
+ if (1 >= cItemsActivate || (lpCV->dwFlags & CF_DISABLEACTIVATEAS))
+ StandardEnableDlgItem(hDlg, IDC_CV_ACTIVATEAS, FALSE);
+
+ // Set the tab width in the list to push all the tabs off the side.
+ RECT rect;
+ if (lpCV->hListVisible != NULL)
+ GetClientRect(lpCV->hListVisible, &rect);
+ else
+ GetClientRect(lpCV->hListInvisible, &rect);
+ DWORD dw = GetDialogBaseUnits();
+ rect.right = (8*rect.right)/LOWORD(dw); //Convert pixels to 2x dlg units.
+ if (lpCV->hListVisible != NULL)
+ SendMessage(lpCV->hListVisible, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)(&rect.right));
+ SendMessage(lpCV->hListInvisible, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)(&rect.right));
+
+ // Make sure that either "Convert To" or "Activate As" is selected
+ // and initialize listbox contents and selection accordingly
+ if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
+ {
+ // Don't need to adjust listbox here because FillClassList
+ // initializes to the "Activate As" state.
+ CheckRadioButton(hDlg, IDC_CV_CONVERTTO, IDC_CV_ACTIVATEAS, IDC_CV_ACTIVATEAS);
+
+ // Hide the icon stuff when Activate is selected...it gets shown
+ // again when Convert is selected.
+ StandardShowDlgItem(hDlg, IDC_CV_DISPLAYASICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, SW_HIDE);
+ }
+ else
+ {
+ // Default case. If user hasn't selected either flag, we will
+ // come here anyway.
+ // swap listboxes.
+
+ HWND hWndTemp = lpCV->hListVisible;
+
+ if (lpCV->dwFlags & CF_DISABLEDISPLAYASICON)
+ {
+ StandardShowDlgItem(hDlg, IDC_CV_DISPLAYASICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, SW_HIDE);
+ }
+
+ lpCV->dwFlags |= CF_SELECTCONVERTTO; // Make sure flag is set
+ if (!(lpCV->dwFlags & CF_CONVERTONLY))
+ CheckRadioButton(hDlg, IDC_CV_CONVERTTO, IDC_CV_ACTIVATEAS, IDC_CV_CONVERTTO);
+
+ SwapWindows(hDlg, lpCV->hListVisible, lpCV->hListInvisible);
+
+ lpCV->hListVisible = lpCV->hListInvisible;
+ lpCV->hListInvisible = hWndTemp;
+
+ if (lpCV->hListInvisible)
+ EnableWindow(lpCV->hListInvisible, FALSE);
+ EnableWindow(lpCV->hListVisible, TRUE);
+ }
+
+ // Initialize Default strings.
+
+ // Default convert string is easy...just user the user type name from
+ // the clsid we got, or the current object
+ if ((lpCV->dwFlags & CF_SETCONVERTDEFAULT)
+ && (IsValidClassID(lpCV->lpOCV->clsidConvertDefault)))
+ {
+ LPOLESTR lpszTemp = NULL;
+ if (OleRegGetUserType(lpCV->lpOCV->clsidConvertDefault, USERCLASSTYPE_FULL,
+ &lpszTemp) == NOERROR)
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpCV->lpszConvertDefault, lpszTemp, OLEUI_CCHLABELMAX);
+#else
+ lstrcpyn(lpCV->lpszConvertDefault, lpszTemp, OLEUI_CCHLABELMAX);
+#endif
+ OleStdFree(lpszTemp);
+ }
+ else
+ {
+ lstrcpy(lpCV->lpszConvertDefault, lpCV->lpszCurrentObject);
+ }
+ }
+ else
+ lstrcpy(lpCV->lpszConvertDefault, lpCV->lpszCurrentObject);
+
+
+ // Default activate is a bit trickier. We want to use the user type
+ // name if from the clsid we got (assuming we got one), or the current
+ // object if it fails or we didn't get a clsid. But...if there's a
+ // Treat As entry in the reg db, then we use that instead. So... the
+ // logic boils down to this:
+ //
+ // if ("Treat As" in reg db)
+ // use it;
+ // else
+ // if (CF_SETACTIVATEDEFAULT)
+ // use it;
+ // else
+ // use current object;
+
+ HKEY hKey;
+ LONG lRet = RegOpenKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey);
+
+ if (lRet != ERROR_SUCCESS)
+ goto CheckInputFlag;
+
+ LPOLESTR lpszCLSID;
+ StringFromCLSID(lpCV->lpOCV->clsid, &lpszCLSID);
+ TCHAR szKey[OLEUI_CCHKEYMAX];
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(szKey, lpszCLSID, OLEUI_CCHKEYMAX);
+#else
+ lstrcpy(szKey, lpszCLSID);
+#endif
+ lstrcat(szKey, TEXT("\\TreatAs"));
+ OleStdFree(lpszCLSID);
+
+ TCHAR szValue[OLEUI_CCHKEYMAX];
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szKey, szValue, (LONG*)&dw);
+
+ CLSID clsid;
+ if (lRet != ERROR_SUCCESS)
+ {
+ RegCloseKey(hKey);
+ goto CheckInputFlag;
+ }
+ else
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszValue[OLEUI_CCHKEYMAX];
+ ATOW(wszValue,szValue,OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszValue, &clsid);
+#else
+ CLSIDFromString(szValue, &clsid);
+#endif
+ LPOLESTR lpszTemp = NULL;
+ if (OleRegGetUserType(clsid, USERCLASSTYPE_FULL, &lpszTemp) == NOERROR)
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpCV->lpszActivateDefault, lpszTemp, OLEUI_CCHLABELMAX);
+#else
+ lstrcpyn(lpCV->lpszActivateDefault, lpszTemp, OLEUI_CCHLABELMAX);
+#endif
+ OleStdFree(lpszTemp);
+ }
+ else
+ {
+ RegCloseKey(hKey);
+ goto CheckInputFlag;
+ }
+ }
+ RegCloseKey(hKey);
+ goto SelectStringInListbox;
+
+CheckInputFlag:
+ if ((lpCV->dwFlags & CF_SETACTIVATEDEFAULT)
+ && (IsValidClassID(lpCV->lpOCV->clsidActivateDefault)))
+ {
+ LPOLESTR lpszTemp = NULL;
+ if (OleRegGetUserType(lpCV->lpOCV->clsidActivateDefault, USERCLASSTYPE_FULL,
+ &lpszTemp) == NOERROR)
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpCV->lpszActivateDefault, lpszTemp, OLEUI_CCHLABELMAX);
+#else
+ lstrcpyn(lpCV->lpszActivateDefault, lpszTemp, OLEUI_CCHLABELMAX);
+#endif
+ OleStdFree(lpszTemp);
+ }
+ else
+ {
+ lstrcpy(lpCV->lpszActivateDefault, lpCV->lpszCurrentObject);
+ }
+ }
+ else
+ lstrcpy((lpCV->lpszActivateDefault), lpCV->lpszCurrentObject);
+
+
+SelectStringInListbox:
+ if (lpCV->dwFlags & CF_SELECTCONVERTTO)
+ lRet = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszConvertDefault);
+ else
+ lRet = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)lpCV->lpszActivateDefault);
+
+ if (LB_ERR == lRet)
+ SendMessage(lpCV->hListVisible, LB_SETCURSEL, (WPARAM)0, 0L);
+
+ if ((HGLOBAL)NULL != lpOCV->hMetaPict)
+ {
+ HGLOBAL hMetaPict = OleDuplicateData(lpOCV->hMetaPict, CF_METAFILEPICT, NULL);
+ SendDlgItemMessage(hDlg, IDC_CV_ICONDISPLAY, IBXM_IMAGESET,
+ 0, (LPARAM)hMetaPict);
+ lpCV->fCustomIcon = TRUE;
+ }
+ else
+ {
+ UpdateClassIcon(hDlg, lpCV, lpCV->hListVisible);
+ }
+
+ // Initialize icon stuff
+ if (DVASPECT_ICON == lpCV->dvAspect )
+ {
+ SendDlgItemMessage(hDlg, IDC_CV_DISPLAYASICON, BM_SETCHECK, TRUE, 0L);
+ }
+ else
+ {
+ // Hide & disable icon stuff
+ StandardShowDlgItem(hDlg, IDC_CV_CHANGEICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_CV_ICONDISPLAY, SW_HIDE);
+ }
+
+ // Call the hook with lCustData in lParam
+ UStandardHook((LPVOID)lpCV, hDlg, WM_INITDIALOG, wParam, lpOCV->lCustData);
+
+ // Update results window
+ SetConvertResults(hDlg, lpCV);
+
+ // Update caption if lpszCaption was specified
+ if (lpCV->lpOCV->lpszCaption && !IsBadReadPtr(lpCV->lpOCV->lpszCaption, 1))
+ {
+ SetWindowText(hDlg, lpCV->lpOCV->lpszCaption);
+ }
+
+ return TRUE;
+}
+
+/*
+ * FillClassList
+ *
+ * Purpose:
+ * Enumerates available OLE object classes from the registration
+ * database that we can convert or activate the specified clsid from.
+ *
+ * Note that this function removes any prior contents of the listbox.
+ *
+ * Parameters:
+ * clsid Class ID for class to find convert classes for
+ * hList HWND to the listbox to fill.
+ * hListActivate HWND to invisible listbox that stores "activate as" list.
+ * lpszClassName LPSTR to put the (hr) class name of the clsid; we
+ * do it here since we've already got the reg db open.
+ * fIsLinkedObject BOOL is the original object a linked object
+ * wFormat WORD specifying the format of the original class.
+ * cClsidExclude UINT number of entries in exclude list
+ * lpClsidExclude LPCLSID array classes to exclude for list
+ *
+ * Return Value:
+ * UINT Number of strings added to the listbox, -1 on failure.
+ */
+UINT FillClassList(CLSID clsid, HWND hListActivate, HWND hListConvert,
+ LPTSTR FAR *lplpszCurrentClass, BOOL fIsLinkedObject,
+ WORD wFormat, UINT cClsidExclude, LPCLSID lpClsidExclude, BOOL bAddSameClass)
+{
+ // Clean out the existing strings.
+ if (hListActivate)
+ SendMessage(hListActivate, LB_RESETCONTENT, 0, 0L);
+
+ OleDbgAssert(hListConvert != NULL);
+ SendMessage(hListConvert, LB_RESETCONTENT, 0, 0L);
+
+ // Open up the root key.
+ HKEY hKey;
+ LONG lRet = RegOpenKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey);
+
+ if (ERROR_SUCCESS != lRet)
+ return (UINT)-1;
+
+ if (NULL == *lplpszCurrentClass)
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ LPOLESTR wszCurrentClass;
+ if (OleRegGetUserType(clsid, USERCLASSTYPE_FULL, &wszCurrentClass) != NOERROR)
+#else
+ if (OleRegGetUserType(clsid, USERCLASSTYPE_FULL, lplpszCurrentClass) != NOERROR)
+#endif
+ {
+ *lplpszCurrentClass = OleStdLoadString(_g_hOleStdResInst, IDS_PSUNKNOWNTYPE);
+ if (*lplpszCurrentClass == NULL)
+ {
+ RegCloseKey(hKey);
+ return (UINT)-1;
+ }
+ }
+#if defined(WIN32) && !defined(UNICODE)
+ else
+ {
+ UINT uLen = WTOALEN(wszCurrentClass);
+ *lplpszCurrentClass = (LPTSTR)OleStdMalloc(uLen);
+ if (NULL == *lplpszCurrentClass)
+ {
+ RegCloseKey(hKey);
+ OleStdFree(wszCurrentClass);
+ return (UINT)-1;
+ }
+ WTOA(*lplpszCurrentClass, wszCurrentClass, uLen);
+ OleStdFree(wszCurrentClass);
+ }
+#endif
+ }
+
+ // Get the class name of the original class.
+ LPTSTR lpszCLSID;
+#if defined(WIN32) && !defined(UNICODE)
+ // This code does not report allocation errors because neither did
+ // the original code before I extended it to support 32-bit ANSI builds.
+ // (NOTE that the result of StringFromCLSID is never checked against
+ // NULL after the #else case below, which contains the original code.)
+ // In any event, if OleStdMalloc returns NULL, then the string will
+ // simply be lost. Technically an error, but not a fatal one.
+ LPOLESTR wszCLSID;
+ StringFromCLSID(clsid, &wszCLSID);
+ lpszCLSID = NULL;
+ if (NULL != wszCLSID)
+ {
+ UINT uLen = WTOALEN(wszCLSID);
+ lpszCLSID = (LPTSTR) OleStdMalloc(uLen);
+ if (NULL != lpszCLSID)
+ {
+ WTOA(lpszCLSID, wszCLSID, uLen);
+ }
+ OleStdFree(wszCLSID);
+ }
+#else
+ StringFromCLSID(clsid, &lpszCLSID);
+#endif
+ // Here, we step through the entire registration db looking for
+ // class that can read or write the original class' format. We
+ // maintain two lists - an activate list and a convert list. The
+ // activate list is a subset of the convert list - activate == read/write
+ // and convert == read. We swap the listboxes as needed with
+ // SwapWindows, and keep track of which is which in the lpCV structure.
+
+ // Every item has the following format:
+ //
+ // Class Name\tclsid\0
+
+ UINT cStrings = 0;
+ TCHAR szClass[OLEUI_CCHKEYMAX];
+ lRet = RegEnumKey(hKey, cStrings++, szClass, OLEUI_CCHKEYMAX_SIZE);
+
+ TCHAR szFormatKey[OLEUI_CCHKEYMAX];
+ TCHAR szFormat[OLEUI_CCHKEYMAX];
+ TCHAR szHRClassName[OLEUI_CCHKEYMAX];
+ CLSID clsidForList;
+
+ while (ERROR_SUCCESS == lRet)
+ {
+ UINT j;
+ BOOL fExclude = FALSE;
+
+ //Check if this CLSID is in the exclusion list.
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszClass[OLEUI_CCHKEYMAX];
+ ATOW(wszClass, szClass, OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszClass, &clsidForList);
+#else
+ CLSIDFromString(szClass, &clsidForList);
+#endif
+ for (j = 0; j < cClsidExclude; j++)
+ {
+ if (IsEqualCLSID(clsidForList, lpClsidExclude[j]))
+ {
+ fExclude=TRUE;
+ break;
+ }
+ }
+ if (fExclude)
+ goto Next; // don't add this class to list
+
+ // Check for a \Conversion\Readwritable\Main - if its
+ // readwriteable, then the class can be added to the ActivateAs
+ // list.
+ // NOTE: the presence of this key should NOT automatically be
+ // used to add the class to the CONVERT list.
+
+ lstrcpy(szFormatKey, szClass);
+ lstrcat(szFormatKey, TEXT("\\Conversion\\Readwritable\\Main"));
+
+ DWORD dw; dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
+
+ if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
+ {
+ // Here, we've got a list of formats that this class can read
+ // and write. We need to see if the original class' format is
+ // in this list. We do that by looking for wFormat in
+ // szFormat - if it in there, then we add this class to the
+ // ACTIVATEAS list only. we do NOT automatically add it to the
+ // CONVERT list. Readable and Readwritable format lists should
+ // be handled separately.
+
+ dw=OLEUI_CCHKEYMAX_SIZE;
+ lRet=RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
+
+ if (ERROR_SUCCESS == lRet && hListActivate != NULL)
+ {
+ // only add if not already in list
+ lstrcat(szHRClassName, TEXT("\t"));
+ if (LB_ERR == SendMessage(hListActivate, LB_FINDSTRING, 0, (LPARAM)szHRClassName))
+ {
+ lstrcat(szHRClassName, szClass);
+ SendMessage(hListActivate, LB_ADDSTRING, 0, (DWORD)szHRClassName);
+ }
+ }
+ }
+
+ // Here we'll check to see if the original class' format is in the
+ // readable list. if so, we will add the class to the CONVERTLIST
+
+ // We've got a special case for a linked object here.
+ // If an object is linked, then the only class that
+ // should appear in the convert list is the object's
+ // class. So, here we check to see if the object is
+ // linked. If it is, then we compare the classes. If
+ // they aren't the same, then we just go to the next key.
+
+ if (!fIsLinkedObject || lstrcmp(lpszCLSID, szClass) == 0)
+ {
+ //Check for a \Conversion\Readable\Main entry
+ lstrcpy(szFormatKey, szClass);
+ lstrcat(szFormatKey, TEXT("\\Conversion\\Readable\\Main"));
+
+ // Check to see if this class can read the original class
+ // format. If it can, add the string to the listbox as
+ // CONVERT_LIST.
+
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
+
+ if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
+ {
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
+
+ if (ERROR_SUCCESS == lRet)
+ {
+ // only add if not already in list
+ lstrcat(szHRClassName, TEXT("\t"));
+ if (LB_ERR == SendMessage(hListConvert, LB_FINDSTRING, 0, (LPARAM)szHRClassName))
+ {
+ lstrcat(szHRClassName, szClass);
+ SendMessage(hListConvert, LB_ADDSTRING, 0, (DWORD)szHRClassName);
+ }
+ }
+ }
+ }
+Next:
+ //Continue with the next key.
+ lRet = RegEnumKey(hKey, cStrings++, szClass, OLEUI_CCHKEYMAX_SIZE);
+
+ } // end while
+
+ // If the original class isn't already in the list, add it.
+ if (bAddSameClass)
+ {
+ lstrcpy(szHRClassName, *lplpszCurrentClass);
+ lstrcat(szHRClassName, TEXT("\t"));
+ lstrcat(szHRClassName, lpszCLSID);
+
+ if (hListActivate != NULL)
+ {
+ // only add it if it's not there already.
+ lRet = SendMessage(hListActivate, LB_FINDSTRING, (WPARAM)-1, (LPARAM)szHRClassName);
+ if (LB_ERR == lRet)
+ SendMessage(hListActivate, LB_ADDSTRING, 0, (LPARAM)szHRClassName);
+ }
+
+ // only add it if it's not there already.
+ lRet = SendMessage(hListConvert, LB_FINDSTRING, (WPARAM)-1, (LPARAM)szHRClassName);
+ if (LB_ERR == lRet)
+ SendMessage(hListConvert, LB_ADDSTRING, 0, (LPARAM)szHRClassName);
+ }
+
+ // Free the string we got from StringFromCLSID.
+ OleStdFree(lpszCLSID);
+ RegCloseKey(hKey);
+
+ return cStrings; // return # of strings added
+}
+
+/*
+ * OleUICanConvertOrActivateAs
+ *
+ * Purpose:
+ * Determine if there is any OLE object class from the registration
+ * database that we can convert or activate the specified clsid from.
+ *
+ * Parameters:
+ * rClsid REFCLSID Class ID for class to find convert classes for
+ * fIsLinkedObject BOOL is the original object a linked object
+ * wFormat WORD specifying the format of the original class.
+ *
+ * Return Value:
+ * BOOL TRUE if Convert command should be enabled, else FALSE
+ */
+STDAPI_(BOOL) OleUICanConvertOrActivateAs(
+ REFCLSID rClsid, BOOL fIsLinkedObject, WORD wFormat)
+{
+ // Open up the root key.
+ HKEY hKey;
+ LONG lRet = RegOpenKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey);
+
+ if (ERROR_SUCCESS != lRet)
+ return FALSE;
+
+ // Get the class name of the original class.
+ LPTSTR lpszCLSID;
+#if defined(WIN32) && !defined(UNICODE)
+ // This code does not report allocation errors because neither did
+ // the original code before I extended it to support 32-bit ANSI builds.
+ // In any event, if OleStdMalloc returns NULL, then the string will
+ // simply be lost. Technically an error, but not a fatal one.
+ // Since this routine has no way to report errors anyway (a design flaw
+ // IMHO) I consider this to be marginally acceptable.
+ LPOLESTR wszCLSID;
+ StringFromCLSID(rClsid, &wszCLSID);
+ lpszCLSID = NULL;
+ if (NULL != wszCLSID)
+ {
+ UINT uLen = WTOALEN(wszCLSID);
+ lpszCLSID = (LPTSTR) OleStdMalloc(uLen);
+ if (NULL != lpszCLSID)
+ {
+ WTOA(lpszCLSID, wszCLSID, uLen);
+ }
+ OleStdFree(wszCLSID);
+ }
+#else
+ StringFromCLSID(rClsid, &lpszCLSID);
+#endif
+
+ // Here, we step through the entire registration db looking for
+ // class that can read or write the original class' format.
+ // This loop stops if a single class is found.
+
+ UINT cStrings = 0;
+ TCHAR szClass[OLEUI_CCHKEYMAX];
+ lRet = RegEnumKey(hKey, cStrings++, szClass, OLEUI_CCHKEYMAX_SIZE);
+
+ TCHAR szFormatKey[OLEUI_CCHKEYMAX];
+ TCHAR szFormat[OLEUI_CCHKEYMAX];
+ TCHAR szHRClassName[OLEUI_CCHKEYMAX];
+ BOOL fEnableConvert = FALSE;
+
+ while (ERROR_SUCCESS == lRet)
+ {
+ if (lstrcmp(lpszCLSID, szClass) == 0)
+ goto next; // we don't want to consider the source class
+
+ // Check for a \Conversion\ReadWriteable\Main entry first - if its
+ // readwriteable, then we don't need to bother checking to see if
+ // its readable.
+
+ lstrcpy(szFormatKey, szClass);
+ lstrcat(szFormatKey, TEXT("\\Conversion\\Readwritable\\Main"));
+ DWORD dw; dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
+
+ if (ERROR_SUCCESS != lRet)
+ {
+ // Try \\DataFormats\DefaultFile too
+ lstrcpy(szFormatKey, szClass);
+ lstrcat(szFormatKey, TEXT("\\DataFormats\\DefaultFile"));
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
+ }
+
+ if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
+ {
+ // Here, we've got a list of formats that this class can read
+ // and write. We need to see if the original class' format is
+ // in this list. We do that by looking for wFormat in
+ // szFormat - if it in there, then we add this class to the
+ // both lists and continue. If not, then we look at the
+ // class' readable formats.
+
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
+ if (ERROR_SUCCESS == lRet)
+ {
+ fEnableConvert = TRUE;
+ break; // STOP -- found one!
+ }
+ }
+
+ // We either didn't find the readwritable key, or the
+ // list of readwritable formats didn't include the
+ // original class format. So, here we'll check to
+ // see if its in the readable list.
+
+ // We've got a special case for a linked object here.
+ // If an object is linked, then the only class that
+ // should appear in the convert list is the object's
+ // class. So, here we check to see if the object is
+ // linked. If it is, then we compare the classes. If
+ // they aren't the same, then we just go to the next key.
+
+ else if (!fIsLinkedObject || lstrcmp(lpszCLSID, szClass) == 0)
+ {
+ // Check for a \Conversion\Readable\Main entry
+ lstrcpy(szFormatKey, szClass);
+ lstrcat(szFormatKey, TEXT("\\Conversion\\Readable\\Main"));
+
+ // Check to see if this class can read the original class format.
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szFormatKey, szFormat, (LONG*)&dw);
+
+ if (ERROR_SUCCESS == lRet && FormatIncluded(szFormat, wFormat))
+ {
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, szClass, szHRClassName, (LONG*)&dw);
+ if (ERROR_SUCCESS == lRet)
+ {
+ fEnableConvert = TRUE;
+ break; // STOP -- found one!
+ }
+ }
+ }
+next:
+ // Continue with the next key.
+ lRet = RegEnumKey(hKey, cStrings++, szClass, OLEUI_CCHKEYMAX_SIZE);
+ }
+
+ // Free the string we got from StringFromCLSID.
+ OleStdFree(lpszCLSID);
+ RegCloseKey(hKey);
+
+ return fEnableConvert;
+}
+
+/*
+ * FormatIncluded
+ *
+ * Purpose:
+ * Parses the string for format from the word.
+ *
+ * Parameters:
+ * szStringToSearch String to parse
+ * wFormat format to find
+ *
+ * Return Value:
+ * BOOL TRUE if format is found in string,
+ * FALSE otherwise.
+ */
+BOOL FormatIncluded(LPTSTR szStringToSearch, WORD wFormat)
+{
+ TCHAR szFormat[255];
+ if (wFormat < 0xC000)
+ wsprintf(szFormat, TEXT("%d"), wFormat);
+ else
+ GetClipboardFormatName(wFormat, szFormat, 255);
+
+ LPTSTR lpToken = szStringToSearch;
+ while (lpToken != NULL)
+ {
+ LPTSTR lpTokenNext = FindChar(lpToken, TEXT(','));
+ if (lpTokenNext != NULL)
+ {
+ *lpTokenNext = 0;
+ ++lpTokenNext;
+ }
+ if (0 == lstrcmpi(lpToken, szFormat))
+ return TRUE;
+
+ lpToken = lpTokenNext;
+ }
+ return FALSE;
+}
+
+/*
+ * UpdateClassIcon
+ *
+ * Purpose:
+ * Handles LBN_SELCHANGE for the Object Type listbox. On a selection
+ * change, we extract an icon from the server handling the currently
+ * selected object type using the utility function HIconFromClass.
+ * Note that we depend on the behavior of FillClassList to stuff the
+ * object class after a tab in the listbox string that we hide from
+ * view (see WM_INITDIALOG).
+ *
+ * Parameters
+ * hDlg HWND of the dialog box.
+ * lpCV LPCONVERT pointing to the dialog structure
+ * hList HWND of the Object Type listbox.
+ *
+ * Return Value:
+ * None
+ */
+static void UpdateClassIcon(HWND hDlg, LPCONVERT lpCV, HWND hList)
+{
+ if (GetDlgItem(hDlg, IDC_CV_ICONDISPLAY) == NULL)
+ return;
+
+ // Get current selection in the list box
+ int iSel= (UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
+ if (LB_ERR == iSel)
+ return;
+
+ // Allocate a string to hold the entire listbox string
+ DWORD cb = SendMessage(hList, LB_GETTEXTLEN, iSel, 0L);
+ LPTSTR pszName = (LPTSTR)OleStdMalloc((cb+1) * sizeof(TCHAR));
+ if (pszName == NULL)
+ return;
+
+ // Get whole string
+ SendMessage(hList, LB_GETTEXT, iSel, (LPARAM)pszName);
+
+ // Set pointer to CLSID (string)
+ LPTSTR pszCLSID = PointerToNthField(pszName, 2, '\t');
+
+ // Create the class ID with this string.
+ CLSID clsid;
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszCLSID[OLEUI_CCHKEYMAX];
+ ATOW(wszCLSID, pszCLSID, OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszCLSID, &clsid);
+#else
+ CLSIDFromString(pszCLSID, &clsid);
+#endif
+ // Get Icon for that CLSID
+ HGLOBAL hMetaPict = OleGetIconOfClass(clsid, NULL, TRUE);
+
+ // Replace current icon with the new one.
+ SendDlgItemMessage(hDlg, IDC_CV_ICONDISPLAY, IBXM_IMAGESET, 1,
+ (LPARAM)hMetaPict);
+
+ OleStdFree(pszName);
+}
+
+/*
+ * SetConvertResults
+ *
+ * Purpose:
+ * Centralizes setting of the Result display in the Convert
+ * dialog. Handles loading the appropriate string from the module's
+ * resources and setting the text, displaying the proper result picture,
+ * and showing the proper icon.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog box so we can access controls.
+ * lpCV LPCONVERT in which we assume that the dwFlags is
+ * set to the appropriate radio button selection, and
+ * the list box has the appropriate class selected.
+ *
+ * Return Value:
+ * None
+ */
+void SetConvertResults(HWND hDlg, LPCONVERT lpCV)
+{
+ HWND hList = lpCV->hListVisible;
+
+ /*
+ * We need scratch memory for loading the stringtable string, loading
+ * the object type from the listbox, loading the source object
+ * type, and constructing the final string. We therefore allocate
+ * four buffers as large as the maximum message length (512) plus
+ * the object type, guaranteeing that we have enough
+ * in all cases.
+ */
+ UINT i = (UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
+ UINT cch = 512+(UINT)SendMessage(hList, LB_GETTEXTLEN, i, 0L);
+ HGLOBAL hMem = GlobalAlloc(GHND, (DWORD)(4*cch)*sizeof(TCHAR));
+ if (NULL == hMem)
+ return;
+
+ LPTSTR lpszOutput = (LPTSTR)GlobalLock(hMem);
+ LPTSTR lpszSelObj = lpszOutput + cch;
+ LPTSTR lpszDefObj = lpszSelObj + cch;
+ LPTSTR lpszString = lpszDefObj + cch;
+
+ // Get selected object and null terminate human-readable name (1st field).
+ SendMessage(hList, LB_GETTEXT, i, (LPARAM)lpszSelObj);
+
+ LPTSTR pszT = PointerToNthField(lpszSelObj, 2, '\t');
+ pszT = CharPrev(lpszSelObj, pszT);
+ *pszT = '\0';
+
+ // Get default object
+ GetDlgItemText(hDlg, IDC_CV_OBJECTTYPE, lpszDefObj, 512);
+
+ //Default is an empty string.
+ *lpszOutput=0;
+
+ if (lpCV->dwFlags & CF_SELECTCONVERTTO)
+ {
+ if (lpCV->lpOCV->fIsLinkedObject) // working with linked object
+ LoadString(_g_hOleStdResInst, IDS_CVRESULTCONVERTLINK, lpszOutput, cch);
+ else
+ {
+ if (0 !=lstrcmp(lpszDefObj, lpszSelObj))
+ {
+ // converting to a new class
+ if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTCONVERTTO, lpszString, cch))
+ FormatString2(lpszOutput, lpszString, lpszDefObj, lpszSelObj);
+ }
+ else
+ {
+ // converting to the same class (no conversion)
+ if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTNOCHANGE, lpszString, cch))
+ wsprintf(lpszOutput, lpszString, lpszDefObj);
+ }
+ }
+
+ if (lpCV->dvAspect == DVASPECT_ICON) // Display as icon is checked
+ {
+ if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTDISPLAYASICON, lpszString, cch))
+ lstrcat(lpszOutput, lpszString);
+ }
+ }
+
+ if (lpCV->dwFlags & CF_SELECTACTIVATEAS)
+ {
+ if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTACTIVATEAS, lpszString, cch))
+ FormatString2(lpszOutput, lpszString, lpszDefObj, lpszSelObj);
+
+ // activating as a new class
+ if (0 != lstrcmp(lpszDefObj, lpszSelObj))
+ {
+ if (0 != LoadString(_g_hOleStdResInst, IDS_CVRESULTACTIVATEDIFF, lpszString, cch))
+ lstrcat(lpszOutput, lpszString);
+ }
+ else // activating as itself.
+ {
+ lstrcat(lpszOutput, TEXT("."));
+ }
+ }
+
+ // If LoadString failed, we simply clear out the results (*lpszOutput=0 above)
+ SetDlgItemText(hDlg, IDC_CV_RESULTTEXT, lpszOutput);
+
+ GlobalUnlock(hMem);
+ GlobalFree(hMem);
+}
+
+/*
+ * ConvertCleanup
+ *
+ * Purpose:
+ * Performs convert-specific cleanup before Convert termination.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog box so we can access controls.
+ *
+ * Return Value:
+ * None
+ */
+void ConvertCleanup(HWND hDlg, LPCONVERT lpCV)
+{
+ // Free our strings. Zero out the user type name string
+ // the the calling app doesn't free to it.
+
+ OleStdFree((LPVOID)lpCV->lpszConvertDefault);
+ OleStdFree((LPVOID)lpCV->lpszActivateDefault);
+ OleStdFree((LPVOID)lpCV->lpszIconSource);
+ if (lpCV->lpOCV->lpszUserType)
+ {
+ OleStdFree((LPVOID)lpCV->lpOCV->lpszUserType);
+ lpCV->lpOCV->lpszUserType = NULL;
+ }
+
+ if (lpCV->lpOCV->lpszDefLabel)
+ {
+ OleStdFree((LPVOID)lpCV->lpOCV->lpszDefLabel);
+ lpCV->lpOCV->lpszDefLabel = NULL;
+ }
+}
+
+/*
+ * SwapWindows
+ *
+ * Purpose:
+ * Moves hWnd1 to hWnd2's position and hWnd2 to hWnd1's position.
+ * Does NOT change sizes.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog box so we can turn redraw off
+ *
+ * Return Value:
+ * None
+ */
+void SwapWindows(HWND hDlg, HWND hWnd1, HWND hWnd2)
+{
+ if (hWnd1 != NULL && hWnd2 != NULL)
+ {
+ RECT rect1; GetWindowRect(hWnd1, &rect1);
+ ScreenToClient(hDlg, (LPPOINT)&rect1.left);
+ ScreenToClient(hDlg, (LPPOINT)&rect1.right);
+
+ RECT rect2; GetWindowRect(hWnd2, &rect2);
+ ScreenToClient(hDlg, (LPPOINT)&rect2.left);
+ ScreenToClient(hDlg, (LPPOINT)&rect2.right);
+
+ SetWindowPos(hWnd1, NULL,
+ rect2.left, rect2.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ SetWindowPos(hWnd2, NULL,
+ rect1.left, rect1.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ }
+}
diff --git a/private/ole2ui32/daytona/makefile b/private/ole2ui32/daytona/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ole2ui32/daytona/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ole2ui32/daytona/sources b/private/ole2ui32/daytona/sources
new file mode 100644
index 000000000..92fd5ccfa
--- /dev/null
+++ b/private/ole2ui32/daytona/sources
@@ -0,0 +1,74 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+
+
+!ENDIF
+
+DLLENTRY=DllMain
+
+DLLDEF=obj\*\oledlg.def
+
+MAJORCOMP=oledlg
+MINORCOMP=
+
+TARGETNAME=oledlg
+TARGETPATHLIB=$(BASEDIR)\public\sdk\lib
+TARGETPATH=obj
+C_DEFINES=-DWIN32 -DWINVER=0x400 -DUNICODE
+TARGETTYPE=DYNLINK
+
+UMTYPE=windows
+INCLUDES=..
+
+PRECOMPILED_INCLUDE=..\precomp.h
+PRECOMPILED_PCH=precomp.pch
+PRECOMPILED_OBJ=precomp.obj
+
+SOURCES= ..\chngsrc.cpp \
+ ..\objprop.cpp \
+ ..\busy.cpp \
+ ..\common.cpp \
+ ..\convert.cpp \
+ ..\drawicon.cpp \
+ ..\icon.cpp \
+ ..\iconbox.cpp \
+ ..\insobj.cpp \
+ ..\links.cpp \
+ ..\ole2ui.cpp \
+ ..\olestd.cpp \
+ ..\pastespl.cpp \
+ ..\targtdev.cpp \
+ ..\oleutl.cpp \
+ ..\resimage.cpp \
+ ..\utility.cpp \
+ ..\dllfuncs.cpp \
+ ..\geticon.cpp \
+ ..\wrapstub.cpp \
+ ..\ole2ui.rc
+
+USE_CRTDLL=1
+
+TARGETLIBS= \
+ $(BASEDIR)\public\sdk\lib\*\kernel32.lib \
+ $(BASEDIR)\public\sdk\lib\*\user32.lib \
+ $(BASEDIR)\public\sdk\lib\*\gdi32.lib \
+ $(BASEDIR)\public\sdk\lib\*\advapi32.lib \
+ $(BASEDIR)\public\sdk\lib\*\ole32.lib \
+ $(BASEDIR)\public\sdk\lib\*\uuid.lib
+
diff --git a/private/ole2ui32/dbgutil.cpp b/private/ole2ui32/dbgutil.cpp
new file mode 100644
index 000000000..b66c703ba
--- /dev/null
+++ b/private/ole2ui32/dbgutil.cpp
@@ -0,0 +1,372 @@
+/*************************************************************************
+**
+** OLE 2.0 Common Utilities
+**
+** dbgutil.h
+**
+** This file contains file contains functions to support debug output.
+**
+** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
+**
+*************************************************************************/
+
+#include "precomp.h"
+
+#ifdef _DEBUG
+
+static int s_nDbgIndent = 0; // indent level for debug message
+static int s_nDbgLevel = 0; // default dbg level printed
+
+STDAPI_(void) OleDbgPrint(
+ int nDbgLvl,
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ int nIndent)
+{
+ if (nDbgLvl <= s_nDbgLevel)
+ OleDbgPrintAlways(lpszPrefix, lpszMsg, nIndent);
+}
+
+STDAPI_(void) OleDbgPrintAlways(LPTSTR lpszPrefix, LPTSTR lpszMsg, int nIndent)
+{
+ if (nIndent < 0)
+ OleDbgIndent(nIndent);
+
+ if (lpszPrefix && *lpszPrefix != '\0')
+ {
+ OutputDebugString(TEXT("| "));
+ for (int i = 0; i < s_nDbgIndent; i++)
+ OutputDebugString(TEXT("----"));
+
+ OutputDebugString(lpszPrefix);
+ OutputDebugString(TEXT(": "));
+ }
+
+ OutputDebugString(lpszMsg);
+ if (nIndent > 0)
+ OleDbgIndent(nIndent);
+}
+
+STDAPI_(void) OleDbgSetDbgLevel(int nDbgLvl)
+{
+ s_nDbgLevel = nDbgLvl;
+}
+
+STDAPI_(int) OleDbgGetDbgLevel( void )
+{
+ return s_nDbgLevel;
+}
+
+STDAPI_(void) OleDbgIndent(int n)
+{
+ switch (n)
+ {
+ case -1:
+ s_nDbgIndent--;
+ break;
+ case 1:
+ s_nDbgIndent++;
+ break;
+ case -2:
+ s_nDbgIndent = 0;
+ break;
+ }
+}
+
+
+STDAPI_(void) OleDbgPrintRefCnt(
+ int nDbgLvl,
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPVOID lpObj,
+ ULONG refcnt)
+{
+ if (nDbgLvl <= s_nDbgLevel)
+ OleDbgPrintRefCntAlways(lpszPrefix, lpszMsg, lpObj, refcnt);
+}
+
+
+STDAPI_(void) OleDbgPrintRefCntAlways(
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPVOID lpObj,
+ ULONG refcnt)
+{
+ TCHAR szBuf[256];
+ wsprintf(szBuf, TEXT("[obj=(0x%lx) cnt=%ld] %s"), lpObj, refcnt, lpszMsg);
+ OleDbgPrintAlways(lpszPrefix, szBuf, 0);
+}
+
+STDAPI_(void) OleDbgPrintRect(
+ int nDbgLvl,
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPRECT lpRect)
+{
+ if (nDbgLvl <= s_nDbgLevel)
+ OleDbgPrintRectAlways(lpszPrefix, lpszMsg, lpRect);
+}
+
+
+STDAPI_(void) OleDbgPrintRectAlways(
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPRECT lpRect)
+{
+ TCHAR szBuf[256];
+ wsprintf(
+ szBuf,
+ TEXT("%s: (%d,%d)-(%d,%d) %dx%d\r\n"),
+ lpszMsg,
+ lpRect->left,
+ lpRect->top,
+ lpRect->right,
+ lpRect->bottom,
+ (lpRect->right-lpRect->left),
+ (lpRect->bottom-lpRect->top)
+ );
+ OleDbgPrintAlways(lpszPrefix, szBuf, 0);
+}
+
+
+#define CASE_SCODE(sc) \
+ case sc: \
+ pszErrName = TEXT(#sc); \
+ break;
+
+STDAPI_(void) OleDbgPrintScodeAlways(LPTSTR lpszPrefix, LPTSTR lpszMsg, SCODE sc)
+{
+ const TCHAR* pszErrName;
+
+ switch (sc)
+ {
+ /* SCODE's defined in SCODE.H */
+
+ CASE_SCODE(S_OK)
+ CASE_SCODE(S_FALSE)
+ CASE_SCODE(E_UNEXPECTED)
+ CASE_SCODE(E_OUTOFMEMORY)
+ CASE_SCODE(E_INVALIDARG)
+ CASE_SCODE(E_NOINTERFACE)
+ CASE_SCODE(E_POINTER)
+ CASE_SCODE(E_HANDLE)
+ CASE_SCODE(E_ABORT)
+ CASE_SCODE(E_FAIL)
+ CASE_SCODE(E_ACCESSDENIED)
+
+ /* SCODE's defined in OLE2.H */
+
+ CASE_SCODE(OLE_E_OLEVERB)
+ CASE_SCODE(OLE_E_ADVF)
+ CASE_SCODE(OLE_E_ENUM_NOMORE)
+ CASE_SCODE(OLE_E_ADVISENOTSUPPORTED)
+ CASE_SCODE(OLE_E_NOCONNECTION)
+ CASE_SCODE(OLE_E_NOTRUNNING)
+ CASE_SCODE(OLE_E_NOCACHE)
+ CASE_SCODE(OLE_E_BLANK)
+ CASE_SCODE(OLE_E_CLASSDIFF)
+ CASE_SCODE(OLE_E_CANT_GETMONIKER)
+ CASE_SCODE(OLE_E_CANT_BINDTOSOURCE)
+ CASE_SCODE(OLE_E_STATIC)
+ CASE_SCODE(OLE_E_PROMPTSAVECANCELLED)
+ CASE_SCODE(OLE_E_INVALIDRECT)
+ CASE_SCODE(OLE_E_WRONGCOMPOBJ)
+ CASE_SCODE(OLE_E_INVALIDHWND)
+ CASE_SCODE(OLE_E_NOT_INPLACEACTIVE)
+ CASE_SCODE(OLE_E_CANTCONVERT)
+ CASE_SCODE(OLE_E_NOSTORAGE)
+
+ CASE_SCODE(DV_E_FORMATETC)
+ CASE_SCODE(DV_E_DVTARGETDEVICE)
+ CASE_SCODE(DV_E_STGMEDIUM)
+ CASE_SCODE(DV_E_STATDATA)
+ CASE_SCODE(DV_E_LINDEX)
+ CASE_SCODE(DV_E_TYMED)
+ CASE_SCODE(DV_E_CLIPFORMAT)
+ CASE_SCODE(DV_E_DVASPECT)
+ CASE_SCODE(DV_E_DVTARGETDEVICE_SIZE)
+ CASE_SCODE(DV_E_NOIVIEWOBJECT)
+
+ CASE_SCODE(OLE_S_USEREG)
+ CASE_SCODE(OLE_S_STATIC)
+ CASE_SCODE(OLE_S_MAC_CLIPFORMAT)
+
+ CASE_SCODE(CONVERT10_E_OLESTREAM_GET)
+ CASE_SCODE(CONVERT10_E_OLESTREAM_PUT)
+ CASE_SCODE(CONVERT10_E_OLESTREAM_FMT)
+ CASE_SCODE(CONVERT10_E_OLESTREAM_BITMAP_TO_DIB)
+ CASE_SCODE(CONVERT10_E_STG_FMT)
+ CASE_SCODE(CONVERT10_E_STG_NO_STD_STREAM)
+ CASE_SCODE(CONVERT10_E_STG_DIB_TO_BITMAP)
+ CASE_SCODE(CONVERT10_S_NO_PRESENTATION)
+
+ CASE_SCODE(CLIPBRD_E_CANT_OPEN)
+ CASE_SCODE(CLIPBRD_E_CANT_EMPTY)
+ CASE_SCODE(CLIPBRD_E_CANT_SET)
+ CASE_SCODE(CLIPBRD_E_BAD_DATA)
+ CASE_SCODE(CLIPBRD_E_CANT_CLOSE)
+
+ CASE_SCODE(DRAGDROP_E_NOTREGISTERED)
+ CASE_SCODE(DRAGDROP_E_ALREADYREGISTERED)
+ CASE_SCODE(DRAGDROP_E_INVALIDHWND)
+ CASE_SCODE(DRAGDROP_S_DROP)
+ CASE_SCODE(DRAGDROP_S_CANCEL)
+ CASE_SCODE(DRAGDROP_S_USEDEFAULTCURSORS)
+
+ CASE_SCODE(OLEOBJ_E_NOVERBS)
+ CASE_SCODE(OLEOBJ_E_INVALIDVERB)
+ CASE_SCODE(OLEOBJ_S_INVALIDVERB)
+ CASE_SCODE(OLEOBJ_S_CANNOT_DOVERB_NOW)
+ CASE_SCODE(OLEOBJ_S_INVALIDHWND)
+ CASE_SCODE(INPLACE_E_NOTUNDOABLE)
+ CASE_SCODE(INPLACE_E_NOTOOLSPACE)
+ CASE_SCODE(INPLACE_S_TRUNCATED)
+
+ /* SCODE's defined in COMPOBJ.H */
+
+ CASE_SCODE(CO_E_NOTINITIALIZED)
+ CASE_SCODE(CO_E_ALREADYINITIALIZED)
+ CASE_SCODE(CO_E_CANTDETERMINECLASS)
+ CASE_SCODE(CO_E_CLASSSTRING)
+ CASE_SCODE(CO_E_IIDSTRING)
+ CASE_SCODE(CO_E_APPNOTFOUND)
+ CASE_SCODE(CO_E_APPSINGLEUSE)
+ CASE_SCODE(CO_E_ERRORINAPP)
+ CASE_SCODE(CO_E_DLLNOTFOUND)
+ CASE_SCODE(CO_E_ERRORINDLL)
+ CASE_SCODE(CO_E_WRONGOSFORAPP)
+ CASE_SCODE(CO_E_OBJNOTREG)
+ CASE_SCODE(CO_E_OBJISREG)
+ CASE_SCODE(CO_E_OBJNOTCONNECTED)
+ CASE_SCODE(CO_E_APPDIDNTREG)
+ CASE_SCODE(CLASS_E_NOAGGREGATION)
+ CASE_SCODE(CLASS_E_CLASSNOTAVAILABLE)
+ CASE_SCODE(REGDB_E_READREGDB)
+ CASE_SCODE(REGDB_E_WRITEREGDB)
+ CASE_SCODE(REGDB_E_KEYMISSING)
+ CASE_SCODE(REGDB_E_INVALIDVALUE)
+ CASE_SCODE(REGDB_E_CLASSNOTREG)
+ CASE_SCODE(REGDB_E_IIDNOTREG)
+ CASE_SCODE(RPC_E_CALL_REJECTED)
+ CASE_SCODE(RPC_E_CALL_CANCELED)
+ CASE_SCODE(RPC_E_CANTPOST_INSENDCALL)
+ CASE_SCODE(RPC_E_CANTCALLOUT_INASYNCCALL)
+ CASE_SCODE(RPC_E_CANTCALLOUT_INEXTERNALCALL)
+ CASE_SCODE(RPC_E_CONNECTION_TERMINATED)
+ CASE_SCODE(RPC_E_SERVER_DIED)
+ CASE_SCODE(RPC_E_CLIENT_DIED)
+ CASE_SCODE(RPC_E_INVALID_DATAPACKET)
+ CASE_SCODE(RPC_E_CANTTRANSMIT_CALL)
+ CASE_SCODE(RPC_E_CLIENT_CANTMARSHAL_DATA)
+ CASE_SCODE(RPC_E_CLIENT_CANTUNMARSHAL_DATA)
+ CASE_SCODE(RPC_E_SERVER_CANTMARSHAL_DATA)
+ CASE_SCODE(RPC_E_SERVER_CANTUNMARSHAL_DATA)
+ CASE_SCODE(RPC_E_INVALID_DATA)
+ CASE_SCODE(RPC_E_INVALID_PARAMETER)
+ CASE_SCODE(RPC_E_UNEXPECTED)
+
+ /* SCODE's defined in DVOBJ.H */
+
+ CASE_SCODE(DATA_S_SAMEFORMATETC)
+ CASE_SCODE(VIEW_E_DRAW)
+ CASE_SCODE(VIEW_S_ALREADY_FROZEN)
+ CASE_SCODE(CACHE_E_NOCACHE_UPDATED)
+ CASE_SCODE(CACHE_S_FORMATETC_NOTSUPPORTED)
+ CASE_SCODE(CACHE_S_SAMECACHE)
+ CASE_SCODE(CACHE_S_SOMECACHES_NOTUPDATED)
+
+ /* SCODE's defined in STORAGE.H */
+
+ CASE_SCODE(STG_E_INVALIDFUNCTION)
+ CASE_SCODE(STG_E_FILENOTFOUND)
+ CASE_SCODE(STG_E_PATHNOTFOUND)
+ CASE_SCODE(STG_E_TOOMANYOPENFILES)
+ CASE_SCODE(STG_E_ACCESSDENIED)
+ CASE_SCODE(STG_E_INVALIDHANDLE)
+ CASE_SCODE(STG_E_INSUFFICIENTMEMORY)
+ CASE_SCODE(STG_E_INVALIDPOINTER)
+ CASE_SCODE(STG_E_NOMOREFILES)
+ CASE_SCODE(STG_E_DISKISWRITEPROTECTED)
+ CASE_SCODE(STG_E_SEEKERROR)
+ CASE_SCODE(STG_E_WRITEFAULT)
+ CASE_SCODE(STG_E_READFAULT)
+ CASE_SCODE(STG_E_SHAREVIOLATION)
+ CASE_SCODE(STG_E_LOCKVIOLATION)
+ CASE_SCODE(STG_E_FILEALREADYEXISTS)
+ CASE_SCODE(STG_E_INVALIDPARAMETER)
+ CASE_SCODE(STG_E_MEDIUMFULL)
+ CASE_SCODE(STG_E_ABNORMALAPIEXIT)
+ CASE_SCODE(STG_E_INVALIDHEADER)
+ CASE_SCODE(STG_E_INVALIDNAME)
+ CASE_SCODE(STG_E_UNKNOWN)
+ CASE_SCODE(STG_E_UNIMPLEMENTEDFUNCTION)
+ CASE_SCODE(STG_E_INVALIDFLAG)
+ CASE_SCODE(STG_E_INUSE)
+ CASE_SCODE(STG_E_NOTCURRENT)
+ CASE_SCODE(STG_E_REVERTED)
+ CASE_SCODE(STG_E_CANTSAVE)
+ CASE_SCODE(STG_E_OLDFORMAT)
+ CASE_SCODE(STG_E_OLDDLL)
+ CASE_SCODE(STG_E_SHAREREQUIRED)
+ CASE_SCODE(STG_E_NOTFILEBASEDSTORAGE)
+ CASE_SCODE(STG_E_EXTANTMARSHALLINGS)
+ CASE_SCODE(STG_S_CONVERTED)
+
+ /* SCODE's defined in STORAGE.H */
+
+ CASE_SCODE(MK_E_CONNECTMANUALLY)
+ CASE_SCODE(MK_E_EXCEEDEDDEADLINE)
+ CASE_SCODE(MK_E_NEEDGENERIC)
+ CASE_SCODE(MK_E_UNAVAILABLE)
+ CASE_SCODE(MK_E_SYNTAX)
+ CASE_SCODE(MK_E_NOOBJECT)
+ CASE_SCODE(MK_E_INVALIDEXTENSION)
+ CASE_SCODE(MK_E_INTERMEDIATEINTERFACENOTSUPPORTED)
+ CASE_SCODE(MK_E_NOTBINDABLE)
+ CASE_SCODE(MK_E_NOTBOUND)
+ CASE_SCODE(MK_E_CANTOPENFILE)
+ CASE_SCODE(MK_E_MUSTBOTHERUSER)
+ CASE_SCODE(MK_E_NOINVERSE)
+ CASE_SCODE(MK_E_NOSTORAGE)
+ CASE_SCODE(MK_E_NOPREFIX)
+ CASE_SCODE(MK_S_REDUCED_TO_SELF)
+ CASE_SCODE(MK_S_ME)
+ CASE_SCODE(MK_S_HIM)
+ CASE_SCODE(MK_S_US)
+ CASE_SCODE(MK_S_MONIKERALREADYREGISTERED)
+
+ default:
+ pszErrName = TEXT("UNKNOWN SCODE");
+ break;
+ }
+
+ TCHAR szBuf[256];
+ wsprintf(szBuf, TEXT("%s %s (0x%lx)\n"), lpszMsg, pszErrName, sc);
+ OleDbgPrintAlways(lpszPrefix, szBuf, 0);
+}
+
+STDAPI OleStdAssert(LPTSTR lpstrExpr, LPTSTR lpstrMsg, LPTSTR lpstrFileName, UINT iLine)
+{
+ TCHAR buf[4096];
+ wsprintf(buf, _T("Expr: %s Msg: (%s)\n")
+ _T("File: %s, line: %ud"), lpstrExpr, lpstrMsg, lpstrFileName, iLine);
+ int i = MessageBox(GetActiveWindow(), buf, _T("Assertion Failed!"),
+ MB_TASKMODAL|MB_ABORTRETRYIGNORE);
+ switch (i)
+ {
+ case IDABORT:
+ ExitProcess((UINT)-3);
+ break;
+
+ case IDRETRY:
+ #ifdef _X86_
+ _asm int 3;
+ #else
+ DebugBreak();
+ #endif
+ break;
+ }
+ return NOERROR;
+}
+
+#endif //_DEBUG
diff --git a/private/ole2ui32/dirs b/private/ole2ui32/dirs
new file mode 100644
index 000000000..0980150c3
--- /dev/null
+++ b/private/ole2ui32/dirs
@@ -0,0 +1,40 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ dirs.
+
+Abstract:
+
+ This file specifies the subdirectories of the current directory that
+ contain component makefiles.
+
+
+Author:
+
+ Drew Bliss (DrewB) 21-Dec-1993
+
+!ENDIF
+
+#
+# This is a list of all subdirectories that build required components.
+# Each subdirectory name should appear on a line by itself. The build
+# follows the order in which the subdirectories are specified.
+#
+
+DIRS=
+
+#
+# This is a list of all subdirectories that build optional components.
+# Each subdirectory name should appear on a line by itself. The build
+# follows the order in which the subdirectories are specified.
+#
+
+OPTIONAL_DIRS= \
+ \
+ daytona \
+ win32s \
+ mfcui \
+ test
diff --git a/private/ole2ui32/dllfuncs.cpp b/private/ole2ui32/dllfuncs.cpp
new file mode 100644
index 000000000..830d2079c
--- /dev/null
+++ b/private/ole2ui32/dllfuncs.cpp
@@ -0,0 +1,65 @@
+/*
+ * DLLFUNCS.CPP
+ *
+ * Contains entry and exit points for the DLL implementation
+ * of the OLE 2.0 User Interface Support Library.
+ *
+ * This file is not needed if we are linking the static library
+ * version of this library.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "uiclass.h"
+
+OLEDBGDATA_MAIN(TEXT("OLEDLG"))
+
+/*
+ * DllMain
+ *
+ * Purpose:
+ * DLL-specific entry point called from LibEntry.
+ */
+
+STDAPI_(BOOL) OleUIInitialize(HINSTANCE, HINSTANCE);
+STDAPI_(BOOL) OleUIUnInitialize();
+
+#pragma code_seg(".text$initseg")
+
+BOOL WINAPI DllMain(HINSTANCE hInst, DWORD Reason, LPVOID lpv)
+{
+ if (Reason == DLL_PROCESS_DETACH)
+ {
+ OleDbgOut2(TEXT("DllMain: OLEDLG.DLL unloaded\r\n"));
+
+ OleUIUnInitialize();
+ }
+ else if (Reason == DLL_PROCESS_ATTACH)
+ {
+ OSVERSIONINFO sVersion;
+
+ sVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ if (GetVersionEx(&sVersion))
+ {
+ if (VER_PLATFORM_WIN32s == sVersion.dwPlatformId)
+ {
+ if ((1 == sVersion.dwMajorVersion) && (30 > sVersion.dwMinorVersion))
+ {
+ return(FALSE); // fail to load on older versions of Win32s
+ }
+ }
+ }
+
+ OleDbgOut2(TEXT("DllMain: OLEDLG.DLL loaded\r\n"));
+
+ DisableThreadLibraryCalls(hInst);
+
+ OleUIInitialize(hInst, (HINSTANCE)0);
+ }
+ return TRUE;
+}
+
+#pragma code_seg()
diff --git a/private/ole2ui32/drawicon.cpp b/private/ole2ui32/drawicon.cpp
new file mode 100644
index 000000000..1fd01514b
--- /dev/null
+++ b/private/ole2ui32/drawicon.cpp
@@ -0,0 +1,674 @@
+/*
+ * DRAWICON.CPP
+ *
+ * Functions to handle creation of metafiles with icons and labels
+ * as well as functions to draw such metafiles with or without the label.
+ *
+ * The metafile is created with a comment that marks the records containing
+ * the label code. Drawing the metafile enumerates the records, draws
+ * all records up to that point, then decides to either skip the label
+ * or draw it.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "utility.h"
+#include "malloc.h"
+
+// Private implementation
+
+//Structure for label and source extraction from a metafile
+typedef struct tagLABELEXTRACT
+{
+ LPTSTR lpsz;
+ UINT Index; // index in lpsz (so we can retrieve 2+ lines)
+ DWORD PrevIndex; // index of last line (so we can mimic word wrap)
+
+ union
+ {
+ UINT cch; //Length of label for label extraction
+ UINT iIcon; //Index of icon in source extraction.
+ } u;
+
+ //For internal use in enum procs
+ BOOL fFoundIconOnly;
+ BOOL fFoundSource;
+ BOOL fFoundIndex;
+} LABELEXTRACT, FAR * LPLABELEXTRACT;
+
+
+//Structure for extracting icons from a metafile (CreateIcon parameters)
+typedef struct tagICONEXTRACT
+{
+ HICON hIcon; //Icon created in the enumeration proc.
+
+ /*
+ * Since we want to handle multitasking well we have the caller
+ * of the enumeration proc instantiate these variables instead of
+ * using statics in the enum proc (which would be bad).
+ */
+ BOOL fAND;
+ HGLOBAL hMemAND; //Enumeration proc allocates and copies
+} ICONEXTRACT, FAR * LPICONEXTRACT;
+
+
+//Structure to use to pass info to EnumMetafileDraw
+typedef struct tagDRAWINFO
+{
+ RECT Rect;
+ BOOL fIconOnly;
+} DRAWINFO, FAR * LPDRAWINFO;
+
+
+int CALLBACK EnumMetafileIconDraw(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPARAM);
+int CALLBACK EnumMetafileExtractLabel(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPLABELEXTRACT);
+int CALLBACK EnumMetafileExtractIcon(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPICONEXTRACT);
+int CALLBACK EnumMetafileExtractIconSource(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPLABELEXTRACT);
+
+/*
+ * Strings for metafile comments. KEEP THESE IN SYNC WITH THE
+ * STRINGS IN GETICON.CPP
+ */
+
+static const char szIconOnly[] = "IconOnly"; // Where to stop to exclude label.
+
+/*
+ * OleUIMetafilePictIconFree
+ *
+ * Purpose:
+ * Deletes the metafile contained in a METAFILEPICT structure and
+ * frees the memory for the structure itself.
+ *
+ * Parameters:
+ * hMetaPict HGLOBAL metafilepict structure created in
+ * OleMetafilePictFromIconAndLabel
+ *
+ * Return Value:
+ * None
+ */
+
+STDAPI_(void) OleUIMetafilePictIconFree(HGLOBAL hMetaPict)
+{
+ if (NULL != hMetaPict)
+ {
+ STGMEDIUM stgMedium;
+ stgMedium.tymed = TYMED_MFPICT;
+ stgMedium.hMetaFilePict = hMetaPict;
+ stgMedium.pUnkForRelease = NULL;
+ ReleaseStgMedium(&stgMedium);
+ }
+}
+
+/*
+ * OleUIMetafilePictIconDraw
+ *
+ * Purpose:
+ * Draws the metafile from OleMetafilePictFromIconAndLabel, either with
+ * the label or without.
+ *
+ * Parameters:
+ * hDC HDC on which to draw.
+ * pRect LPRECT in which to draw the metafile.
+ * hMetaPict HGLOBAL to the METAFILEPICT from
+ * OleMetafilePictFromIconAndLabel
+ * fIconOnly BOOL specifying to draw the label or not.
+ *
+ * Return Value:
+ * BOOL TRUE if the function is successful, FALSE if the
+ * given metafilepict is invalid.
+ */
+
+STDAPI_(BOOL) OleUIMetafilePictIconDraw(HDC hDC, LPCRECT pRect,
+ HGLOBAL hMetaPict, BOOL fIconOnly)
+{
+ if (NULL == hMetaPict)
+ return FALSE;
+
+ LPMETAFILEPICT pMF = (LPMETAFILEPICT)GlobalLock(hMetaPict);
+
+ if (NULL == pMF)
+ return FALSE;
+
+ DRAWINFO di;
+ di.Rect = *pRect;
+ di.fIconOnly = fIconOnly;
+
+ //Transform to back to pixels
+ int cx = XformWidthInHimetricToPixels(hDC, pMF->xExt);
+ int cy = XformHeightInHimetricToPixels(hDC, pMF->yExt);
+
+ SaveDC(hDC);
+
+ SetMapMode(hDC, pMF->mm);
+ SetViewportOrgEx(hDC, (pRect->right - cx) / 2, 0, NULL);
+ SetViewportExtEx(hDC, min ((pRect->right - cx) / 2 + cx, cx), cy, NULL);
+
+ if (fIconOnly)
+ EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileIconDraw, (LPARAM)&di);
+ else
+ PlayMetaFile(hDC, pMF->hMF);
+
+ RestoreDC(hDC, -1);
+
+ GlobalUnlock(hMetaPict);
+ return TRUE;
+}
+
+/*
+ * EnumMetafileIconDraw
+ *
+ * Purpose:
+ * EnumMetaFile callback function that draws either the icon only or
+ * the icon and label depending on given flags.
+ *
+ * Parameters:
+ * hDC HDC into which the metafile should be played.
+ * phTable HANDLETABLE FAR * providing handles selected into the DC.
+ * pMFR METARECORD FAR * giving the enumerated record.
+ * lParam LPARAM flags passed in EnumMetaFile.
+ *
+ * Return Value:
+ * int 0 to stop enumeration, 1 to continue.
+ */
+int CALLBACK EnumMetafileIconDraw(HDC hDC, HANDLETABLE FAR *phTable,
+ METARECORD FAR *pMFR, int cObj, LPARAM lParam)
+{
+ LPDRAWINFO lpdi = (LPDRAWINFO)lParam;
+
+ /*
+ * We play everything blindly except for DIBBITBLT (or DIBSTRETCHBLT)
+ * and ESCAPE with MFCOMMENT. For the BitBlts we change the x,y to
+ * draw at (0,0) instead of wherever it was written to draw. The
+ * comment tells us there to stop if we don't want to draw the label.
+ */
+
+ //If we're playing icon only, stop enumeration at the comment.
+ if (lpdi->fIconOnly)
+ {
+ if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0])
+ {
+ if (0 == lstrcmpiA(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
+ return 0;
+ }
+
+ /*
+ * Check for the records in which we want to munge the coordinates.
+ * destX is offset 6 for BitBlt, offset 9 for StretchBlt, either of
+ * which may appear in the metafile.
+ */
+ if (META_DIBBITBLT == pMFR->rdFunction)
+ pMFR->rdParm[6]=0;
+
+ if (META_DIBSTRETCHBLT == pMFR->rdFunction)
+ pMFR->rdParm[9] = 0;
+ }
+
+ PlayMetaFileRecord(hDC, phTable, pMFR, cObj);
+ return 1;
+}
+
+
+/*
+ * OleUIMetafilePictExtractLabel
+ *
+ * Purpose:
+ * Retrieves the label string from metafile representation of an icon.
+ *
+ * Parameters:
+ * hMetaPict HGLOBAL to the METAFILEPICT containing the metafile.
+ * lpszLabel LPSTR in which to store the label.
+ * cchLabel UINT length of lpszLabel.
+ * lpWrapIndex DWORD index of first character in last line. Can be NULL
+ * if calling function doesn't care about word wrap.
+ *
+ * Return Value:
+ * UINT Number of characters copied.
+ */
+STDAPI_(UINT) OleUIMetafilePictExtractLabel(HGLOBAL hMetaPict, LPTSTR lpszLabel,
+ UINT cchLabel, LPDWORD lpWrapIndex)
+{
+ if (NULL == hMetaPict || NULL == lpszLabel || 0 == cchLabel)
+ return FALSE;
+
+ /*
+ * We extract the label by getting a screen DC and walking the metafile
+ * records until we see the ExtTextOut record we put there. That
+ * record will have the string embedded in it which we then copy out.
+ */
+ LPMETAFILEPICT pMF = (LPMETAFILEPICT)GlobalLock(hMetaPict);
+
+ if (NULL == pMF)
+ return FALSE;
+
+ LABELEXTRACT le;
+ le.lpsz=lpszLabel;
+ le.u.cch=cchLabel;
+ le.Index=0;
+ le.fFoundIconOnly=FALSE;
+ le.fFoundSource=FALSE; //Unused for this function.
+ le.fFoundIndex=FALSE; //Unused for this function.
+ le.PrevIndex = 0;
+
+ //Use a screen DC so we have something valid to pass in.
+ HDC hDC = GetDC(NULL);
+ EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractLabel, (LONG)(LPLABELEXTRACT)&le);
+ ReleaseDC(NULL, hDC);
+
+ GlobalUnlock(hMetaPict);
+
+ //Tell where we wrapped (if calling function cares)
+ if (NULL != lpWrapIndex)
+ *lpWrapIndex = le.PrevIndex;
+
+ //Return amount of text copied
+ return le.u.cch;
+}
+
+/*
+ * EnumMetafileExtractLabel
+ *
+ * Purpose:
+ * EnumMetaFile callback function that walks a metafile looking for
+ * ExtTextOut, then concatenates the text from each one into a buffer
+ * in lParam.
+ *
+ * Parameters:
+ * hDC HDC into which the metafile should be played.
+ * phTable HANDLETABLE FAR * providing handles selected into the DC.
+ * pMFR METARECORD FAR * giving the enumerated record.
+ * pLE LPLABELEXTRACT providing the destination buffer and length.
+ *
+ * Return Value:
+ * int 0 to stop enumeration, 1 to continue.
+ */
+
+int CALLBACK EnumMetafileExtractLabel(HDC hDC, HANDLETABLE FAR *phTable,
+ METARECORD FAR *pMFR, int cObj, LPLABELEXTRACT pLE)
+{
+ /*
+ * We don't allow anything to happen until we see "IconOnly"
+ * in an MFCOMMENT that is used to enable everything else.
+ */
+ if (!pLE->fFoundIconOnly)
+ {
+ if (META_ESCAPE == pMFR->rdFunction && MFCOMMENT == pMFR->rdParm[0])
+ {
+ if (0 == lstrcmpiA(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
+ pLE->fFoundIconOnly=TRUE;
+ }
+ return 1;
+ }
+
+ //Enumerate all records looking for META_EXTTEXTOUT - there can be more
+ //than one.
+ if (META_EXTTEXTOUT == pMFR->rdFunction)
+ {
+ /*
+ * If ExtTextOut has NULL fuOptions, then the rectangle is omitted
+ * from the record, and the string starts at rdParm[4]. If
+ * fuOptions is non-NULL, then the string starts at rdParm[8]
+ * (since the rectange takes up four WORDs in the array). In
+ * both cases, the string continues for (rdParm[2]+1) >> 1
+ * words. We just cast a pointer to rdParm[8] to an LPSTR and
+ * lstrcpyn into the buffer we were given.
+ *
+ * Note that we use element 8 in rdParm instead of 4 because we
+ * passed ETO_CLIPPED in for the options on ExtTextOut--docs say
+ * [4] which is rect doesn't exist if we passed zero there.
+ *
+ */
+
+ UINT cchMax = min(pLE->u.cch - pLE->Index, (UINT)pMFR->rdParm[2]);
+ LPTSTR lpszTemp = pLE->lpsz + pLE->Index;
+#ifdef _UNICODE
+ MultiByteToWideChar(CP_ACP, 0, (LPSTR)&pMFR->rdParm[8], cchMax,
+ lpszTemp, cchMax+1);
+#else
+ lstrcpyn(lpszTemp, (LPSTR)&pMFR->rdParm[8], cchMax+1);
+#endif
+ lpszTemp[cchMax+1] = 0;
+
+ pLE->PrevIndex = pLE->Index;
+ pLE->Index += cchMax;
+ }
+ return 1;
+}
+
+/*
+ * OleUIMetafilePictExtractIcon
+ *
+ * Purpose:
+ * Retrieves the icon from metafile into which DrawIcon was done before.
+ *
+ * Parameters:
+ * hMetaPict HGLOBAL to the METAFILEPICT containing the metafile.
+ *
+ * Return Value:
+ * HICON Icon recreated from the data in the metafile.
+ */
+STDAPI_(HICON) OleUIMetafilePictExtractIcon(HGLOBAL hMetaPict)
+{
+ if (NULL == hMetaPict)
+ return NULL;
+
+ /*
+ * We extract the label by getting a screen DC and walking the metafile
+ * records until we see the ExtTextOut record we put there. That
+ * record will have the string embedded in it which we then copy out.
+ */
+ LPMETAFILEPICT pMF = (LPMETAFILEPICT)GlobalLock(hMetaPict);
+
+ if (NULL == pMF)
+ return FALSE;
+
+ ICONEXTRACT ie;
+ ie.fAND = TRUE;
+
+ //Use a screen DC so we have something valid to pass in.
+ HDC hDC=GetDC(NULL);
+ EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractIcon, (LONG)&ie);
+ ReleaseDC(NULL, hDC);
+
+ GlobalUnlock(hMetaPict);
+
+ return ie.hIcon;
+}
+
+/*
+ * EnumMetafileExtractIcon
+ *
+ * Purpose:
+ * EnumMetaFile callback function that walks a metafile looking for
+ * StretchBlt (3.1) and BitBlt (3.0) records. We expect to see two
+ * of them, the first being the AND mask and the second being the XOR
+ * data. We
+ * ExtTextOut, then copies the text into a buffer in lParam.
+ *
+ * Parameters:
+ * hDC HDC into which the metafile should be played.
+ * phTable HANDLETABLE FAR * providing handles selected into the DC.
+ * pMFR METARECORD FAR * giving the enumerated record.
+ * pIE LPICONEXTRACT providing the destination buffer and length.
+ *
+ * Return Value:
+ * int 0 to stop enumeration, 1 to continue.
+ */
+
+int CALLBACK EnumMetafileExtractIcon(HDC hDC, HANDLETABLE FAR *phTable,
+ METARECORD FAR *pMFR, int cObj, LPICONEXTRACT pIE)
+{
+ //Continue enumeration if we don't see the records we want.
+ if (META_DIBBITBLT != pMFR->rdFunction && META_DIBSTRETCHBLT != pMFR->rdFunction)
+ return 1;
+
+ UNALIGNED BITMAPINFO* lpBI;
+ UINT uWidth, uHeight;
+ /*
+ * Windows 3.0 DrawIcon uses META_DIBBITBLT in whereas 3.1 uses
+ * META_DIBSTRETCHBLT so we have to handle each case separately.
+ */
+ if (META_DIBBITBLT==pMFR->rdFunction) //Win3.0
+ {
+ //Get dimensions and the BITMAPINFO struct.
+ uHeight = pMFR->rdParm[1];
+ uWidth = pMFR->rdParm[2];
+ lpBI = (LPBITMAPINFO)&(pMFR->rdParm[8]);
+ }
+
+ if (META_DIBSTRETCHBLT == pMFR->rdFunction) //Win3.1
+ {
+ //Get dimensions and the BITMAPINFO struct.
+ uHeight = pMFR->rdParm[2];
+ uWidth = pMFR->rdParm[3];
+ lpBI = (LPBITMAPINFO)&(pMFR->rdParm[10]);
+ }
+
+ UNALIGNED BITMAPINFOHEADER* lpBH=(LPBITMAPINFOHEADER)&(lpBI->bmiHeader);
+
+ //Pointer to the bits which follows the BITMAPINFO structure.
+ LPBYTE lpbSrc=(LPBYTE)lpBI+sizeof(BITMAPINFOHEADER);
+
+ //Add the length of the color table (if one exists)
+ if (0 != lpBH->biClrUsed)
+ {
+ // If we have an explicit count of colors used, we
+ // can find the offset to the data directly
+ lpbSrc += (lpBH->biClrUsed*sizeof(RGBQUAD));
+ }
+ else if (lpBH->biCompression == BI_BITFIELDS)
+ {
+ // 16 or 32 bpp, indicated by BI_BITFIELDS in the compression
+ // field, have 3 DWORD masks for adjusting subsequent
+ // direct-color values, and no palette
+ lpbSrc += 3 * sizeof(DWORD);
+ }
+ else
+ {
+ // In other cases, there is an array of RGBQUAD entries
+ // equal to 2^(biBitCount) where biBitCount is the number
+ // of bits per pixel. The exception is 24 bpp bitmaps,
+ // which have no color table and just use direct RGB values.
+ lpbSrc += (lpBH->biBitCount == 24) ? 0 :
+ (1 << (lpBH->biBitCount)) * sizeof(RGBQUAD);
+ }
+
+ // copy into aligned stack space (since SetDIBits needs aligned data)
+ size_t nSize = lpbSrc - (LPBYTE)lpBI;
+ LPBITMAPINFO lpTemp = (LPBITMAPINFO)_alloca(nSize);
+ memcpy(lpTemp, lpBI, nSize);
+
+ /*
+ * All the bits we have in lpbSrc are device-independent, so we
+ * need to change them over to be device-dependent using SetDIBits.
+ * Once we have a bitmap with the device-dependent bits, we can
+ * GetBitmapBits to have buffers with the real data.
+ *
+ * For each pass we have to allocate memory for the bits. We save
+ * the memory for the mask between passes.
+ */
+
+ HBITMAP hBmp;
+
+ //Use CreateBitmap for ANY monochrome bitmaps
+ if (pIE->fAND || 1==lpBH->biBitCount)
+ hBmp=CreateBitmap((UINT)lpBH->biWidth, (UINT)lpBH->biHeight, 1, 1, NULL);
+ else
+ hBmp=CreateCompatibleBitmap(hDC, (UINT)lpBH->biWidth, (UINT)lpBH->biHeight);
+
+ if (!hBmp || !SetDIBits(hDC, hBmp, 0, (UINT)lpBH->biHeight, (LPVOID)lpbSrc, lpTemp, DIB_RGB_COLORS))
+ {
+ if (!pIE->fAND)
+ GlobalFree(pIE->hMemAND);
+
+ DeleteObject(hBmp);
+ return 0;
+ }
+
+ //Allocate memory and get the DDBits into it.
+ BITMAP bm;
+ GetObject(hBmp, sizeof(bm), &bm);
+
+ DWORD cb = bm.bmHeight*bm.bmWidthBytes * bm.bmPlanes;
+ HGLOBAL hMem = GlobalAlloc(GHND, cb);
+
+ if (NULL==hMem)
+ {
+ if (NULL != pIE->hMemAND)
+ GlobalFree(pIE->hMemAND);
+
+ DeleteObject(hBmp);
+ return 0;
+ }
+
+ LPBYTE lpbDst = (LPBYTE)GlobalLock(hMem);
+ GetBitmapBits(hBmp, cb, (LPVOID)lpbDst);
+ DeleteObject(hBmp);
+ GlobalUnlock(hMem);
+
+ /*
+ * If this is the first pass (pIE->fAND==TRUE) then save the memory
+ * of the AND bits for the next pass.
+ */
+ if (pIE->fAND)
+ {
+ pIE->fAND = FALSE;
+ pIE->hMemAND = hMem;
+
+ //Continue enumeration looking for the next blt record.
+ return 1;
+ }
+ else
+ {
+ //Get the AND pointer again.
+ lpbSrc=(LPBYTE)GlobalLock(pIE->hMemAND);
+
+ /*
+ * Create the icon now that we have all the data. lpbDst already
+ * points to the XOR bits.
+ */
+
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+
+ pIE->hIcon = CreateIcon(_g_hOleStdInst, uWidth, uHeight,
+ (BYTE)bm.bmPlanes, (BYTE)bm.bmBitsPixel, lpbSrc, lpbDst);
+
+ GlobalUnlock(pIE->hMemAND);
+ GlobalFree(pIE->hMemAND);
+ GlobalFree(hMem);
+
+ return 0;
+ }
+}
+
+
+/*
+ * OleUIMetafilePictExtractIconSource
+ *
+ * Purpose:
+ * Retrieves the filename and index of the icon source from a metafile
+ * created with OleMetafilePictFromIconAndLabel.
+ *
+ * Parameters:
+ * hMetaPict HGLOBAL to the METAFILEPICT containing the metafile.
+ * lpszSource LPTSTR in which to store the source filename. This
+ * buffer should be MAX_PATH characters.
+ * piIcon UINT FAR * in which to store the icon's index
+ * within lpszSource
+ *
+ * Return Value:
+ * BOOL TRUE if the records were found, FALSE otherwise.
+ */
+STDAPI_(BOOL) OleUIMetafilePictExtractIconSource(HGLOBAL hMetaPict,
+ LPTSTR lpszSource, UINT FAR *piIcon)
+{
+ if (NULL == hMetaPict || NULL == lpszSource || NULL == piIcon)
+ return FALSE;
+
+ /*
+ * We will walk the metafile looking for the two comment records
+ * following the IconOnly comment. The flags fFoundIconOnly and
+ * fFoundSource indicate if we have found IconOnly and if we have
+ * found the source comment already.
+ */
+
+ LPMETAFILEPICT pMF = (LPMETAFILEPICT)GlobalLock(hMetaPict);
+ if (NULL == pMF)
+ return FALSE;
+
+ LABELEXTRACT le;
+ le.lpsz = lpszSource;
+ le.fFoundIconOnly = FALSE;
+ le.fFoundSource = FALSE;
+ le.fFoundIndex = FALSE;
+
+ //Use a screen DC so we have something valid to pass in.
+ HDC hDC = GetDC(NULL);
+ EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractIconSource,
+ (LONG)(LPLABELEXTRACT)&le);
+ ReleaseDC(NULL, hDC);
+ GlobalUnlock(hMetaPict);
+
+ //Copy the icon index to the caller's variable.
+ *piIcon=le.u.iIcon;
+
+ //Check that we found everything.
+ return (le.fFoundIconOnly && le.fFoundSource && le.fFoundIndex);
+}
+
+
+/*
+ * EnumMetafileExtractIconSource
+ *
+ * Purpose:
+ * EnumMetaFile callback function that walks a metafile skipping the first
+ * comment record, extracting the source filename from the second, and
+ * the index of the icon in the third.
+ *
+ * Parameters:
+ * hDC HDC into which the metafile should be played.
+ * phTable HANDLETABLE FAR * providing handles selected into the DC.
+ * pMFR METARECORD FAR * giving the enumerated record.
+ * pLE LPLABELEXTRACT providing the destination buffer and
+ * area to store the icon index.
+ *
+ * Return Value:
+ * int 0 to stop enumeration, 1 to continue.
+ */
+
+int CALLBACK EnumMetafileExtractIconSource(HDC hDC, HANDLETABLE FAR *phTable,
+ METARECORD FAR *pMFR, int cObj, LPLABELEXTRACT pLE)
+{
+ /*
+ * We don't allow anything to happen until we see "IconOnly"
+ * in an MFCOMMENT that is used to enable everything else.
+ */
+ if (!pLE->fFoundIconOnly)
+ {
+ if (META_ESCAPE == pMFR->rdFunction && MFCOMMENT == pMFR->rdParm[0])
+ {
+ if (0 == lstrcmpiA(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
+ pLE->fFoundIconOnly=TRUE;
+ }
+ return 1;
+ }
+
+ //Now see if we find the source string.
+ if (!pLE->fFoundSource)
+ {
+ if (META_ESCAPE == pMFR->rdFunction && MFCOMMENT == pMFR->rdParm[0])
+ {
+#ifdef _UNICODE
+ MultiByteToWideChar(CP_ACP, 0, (LPSTR)&pMFR->rdParm[2], -1,
+ pLE->lpsz, MAX_PATH);
+#else
+ lstrcpyn(pLE->lpsz, (LPSTR)&pMFR->rdParm[2], MAX_PATH);
+#endif
+ pLE->lpsz[MAX_PATH-1] = '\0';
+ pLE->fFoundSource=TRUE;
+ }
+ return 1;
+ }
+
+ //Next comment will be the icon index.
+ if (META_ESCAPE == pMFR->rdFunction && MFCOMMENT == pMFR->rdParm[0])
+ {
+ /*
+ * This string contains the icon index in string form,
+ * so we need to convert back to a UINT. After we see this
+ * we can stop the enumeration. The comment will have
+ * a null terminator because we made sure to save it.
+ */
+ LPSTR psz = (LPSTR)&pMFR->rdParm[2];
+ pLE->u.iIcon = 0;
+
+ //Do Ye Olde atoi
+ while (*psz)
+ pLE->u.iIcon = (10*pLE->u.iIcon)+((*psz++)-'0');
+
+ pLE->fFoundIndex=TRUE;
+ return 0;
+ }
+ return 1;
+}
diff --git a/private/ole2ui32/geticon.cpp b/private/ole2ui32/geticon.cpp
new file mode 100644
index 000000000..1bb6fca92
--- /dev/null
+++ b/private/ole2ui32/geticon.cpp
@@ -0,0 +1,166 @@
+/*
+ * GETICON.CPP
+ *
+ * Functions to create DVASPECT_ICON metafile from filename or classname.
+ *
+ * OleMetafilePictFromIconAndLabel
+ *
+ * (c) Copyright Microsoft Corp. 1992-1993 All Rights Reserved
+ */
+
+
+/*******
+ *
+ * ICON (DVASPECT_ICON) METAFILE FORMAT:
+ *
+ * The metafile generated with OleMetafilePictFromIconAndLabel contains
+ * the following records which are used by the functions in DRAWICON.CPP
+ * to draw the icon with and without the label and to extract the icon,
+ * label, and icon source/index.
+ *
+ * SetWindowOrg
+ * SetWindowExt
+ * DrawIcon:
+ * Inserts records of DIBBITBLT or DIBSTRETCHBLT, once for the
+ * AND mask, one for the image bits.
+ * Escape with the comment "IconOnly"
+ * This indicates where to stop record enumeration to draw only
+ * the icon.
+ * SetTextColor
+ * SetTextAlign
+ * SetBkColor
+ * CreateFont
+ * SelectObject on the font.
+ * ExtTextOut
+ * One or more ExtTextOuts occur if the label is wrapped. The
+ * text in these records is used to extract the label.
+ * SelectObject on the old font.
+ * DeleteObject on the font.
+ * Escape with a comment that contains the path to the icon source.
+ * Escape with a comment that is the ASCII of the icon index.
+ *
+ *******/
+
+#include "precomp.h"
+#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <commdlg.h>
+#include <memory.h>
+#include <cderr.h>
+#include "utility.h"
+
+OLEDBGDATA
+
+static const TCHAR szSeparators[] = TEXT(" \t\\/!:");
+
+#define IS_SEPARATOR(c) ( (c) == ' ' || (c) == '\\' \
+ || (c) == '/' || (c) == '\t' \
+ || (c) == '!' || (c) == ':')
+#define IS_FILENAME_DELIM(c) ( (c) == '\\' || (c) == '/' || (c) == ':' )
+
+#define IS_SPACE(c) ( (c) == ' ' || (c) == '\t' || (c) == '\n' )
+
+/*
+ * GetAssociatedExecutable
+ *
+ * Purpose: Finds the executable associated with the provided extension
+ *
+ * Parameters:
+ * lpszExtension LPSTR points to the extension we're trying to find
+ * an exe for. Does **NO** validation.
+ *
+ * lpszExecutable LPSTR points to where the exe name will be returned.
+ * No validation here either - pass in 128 char buffer.
+ *
+ * Return:
+ * BOOL TRUE if we found an exe, FALSE if we didn't.
+ *
+ */
+BOOL FAR PASCAL GetAssociatedExecutable(LPTSTR lpszExtension, LPTSTR lpszExecutable)
+{
+ HKEY hKey;
+ LRESULT lRet = RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey);
+ if (ERROR_SUCCESS != lRet)
+ return FALSE;
+
+ LONG dw = MAX_PATH_SIZE;
+ TCHAR szValue[OLEUI_CCHKEYMAX];
+ lRet = RegQueryValue(hKey, lpszExtension, szValue, &dw); //ProgId
+ if (ERROR_SUCCESS != lRet)
+ {
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ // szValue now has ProgID
+ TCHAR szKey[OLEUI_CCHKEYMAX];
+ lstrcpy(szKey, szValue);
+ lstrcat(szKey, TEXT("\\Shell\\Open\\Command"));
+
+ dw = MAX_PATH_SIZE;
+ lRet = RegQueryValue(hKey, szKey, szValue, &dw);
+ if (ERROR_SUCCESS != lRet)
+ {
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ // szValue now has an executable name in it. Let's null-terminate
+ // at the first post-executable space (so we don't have cmd line
+ // args.
+ LPTSTR lpszTemp = szValue;
+ while ('\0' != *lpszTemp && IS_SPACE(*lpszTemp))
+ lpszTemp = CharNext(lpszTemp); // Strip off leading spaces
+
+ LPTSTR lpszExe = lpszTemp;
+ while ('\0' != *lpszTemp && !IS_SPACE(*lpszTemp))
+ lpszTemp = CharNext(lpszTemp); // Step through exe name
+ *lpszTemp = '\0'; // null terminate at first space (or at end).
+
+ lstrcpy(lpszExecutable, lpszExe);
+ return TRUE;
+}
+
+
+/*
+ * PointerToNthField
+ *
+ * Purpose:
+ * Returns a pointer to the beginning of the nth field.
+ * Assumes null-terminated string.
+ *
+ * Parameters:
+ * lpszString string to parse
+ * nField field to return starting index of.
+ * chDelimiter char that delimits fields
+ *
+ * Return Value:
+ * LPSTR pointer to beginning of nField field.
+ * NOTE: If the null terminator is found
+ * Before we find the Nth field, then
+ * we return a pointer to the null terminator -
+ * calling app should be sure to check for
+ * this case.
+ *
+ */
+LPTSTR FAR PASCAL PointerToNthField(LPTSTR lpszString, int nField, TCHAR chDelimiter)
+{
+ if (1 == nField)
+ return lpszString;
+
+ int cFieldFound = 1;
+ LPTSTR lpField = lpszString;
+ while (*lpField != '\0')
+ {
+ if (*lpField++ == chDelimiter)
+ {
+ cFieldFound++;
+ if (nField == cFieldFound)
+ return lpField;
+ }
+ }
+ return lpField;
+}
+
diff --git a/private/ole2ui32/icon.cpp b/private/ole2ui32/icon.cpp
new file mode 100644
index 000000000..d112bdbf2
--- /dev/null
+++ b/private/ole2ui32/icon.cpp
@@ -0,0 +1,1316 @@
+/*
+ * ICON.CPP
+ *
+ * Implements the OleUIChangeIcon function which invokes the complete
+ * Change Icon dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+#include "iconbox.h"
+
+OLEDBGDATA
+
+ULONG
+GetLongPathName(LPCTSTR pcsPath,
+ LPTSTR pcsLongPath,
+ ULONG cchLongPath);
+
+#define CXICONPAD (12)
+#define CYICONPAD (4)
+
+// Internally used structure
+typedef struct tagCHANGEICON
+{
+ LPOLEUICHANGEICON lpOCI; //Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ /*
+ * What we store extra in this structure besides the original caller's
+ * pointer are those fields that we need to modify during the life of
+ * the dialog but that we don't want to change in the original structure
+ * until the user presses OK.
+ */
+ DWORD dwFlags;
+ HICON hCurIcon;
+ TCHAR szLabel[OLEUI_CCHLABELMAX+1];
+ TCHAR szFile[MAX_PATH];
+ UINT iIcon;
+ HICON hDefIcon;
+ TCHAR szDefIconFile[MAX_PATH];
+ UINT iDefIcon;
+ UINT nBrowseHelpID; // Help ID callback for Browse dlg
+
+} CHANGEICON, *PCHANGEICON, FAR *LPCHANGEICON;
+
+// Internal function prototypes
+// ICON.CPP
+
+BOOL CALLBACK ChangeIconDialogProc(HWND, UINT, WPARAM, LPARAM);
+BOOL FChangeIconInit(HWND, WPARAM, LPARAM);
+UINT UFillIconList(HWND, UINT, LPTSTR, BOOL);
+BOOL FDrawListIcon(LPDRAWITEMSTRUCT);
+void UpdateResultIcon(LPCHANGEICON, HWND, UINT);
+
+/*
+ * OleUIChangeIcon
+ *
+ * Purpose:
+ * Invokes the standard OLE Change Icon dialog box allowing the user
+ * to select an icon from an icon file, executable, or DLL.
+ *
+ * Parameters:
+ * lpCI LPOLEUIChangeIcon pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * UINT OLEUI_SUCCESS or OLEUI_OK if all is well, otherwise
+ * an error value.
+ */
+STDAPI_(UINT) OleUIChangeIcon(LPOLEUICHANGEICON lpCI)
+{
+ HGLOBAL hMemDlg = NULL;
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpCI, sizeof(OLEUICHANGEICON),
+ &hMemDlg);
+
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+ // Check for a valid hMetaPict.
+ if (NULL == lpCI->hMetaPict && NULL == lpCI->szIconExe && CLSID_NULL == lpCI->clsid)
+ {
+ return(OLEUI_CIERR_MUSTHAVECURRENTMETAFILE);
+ }
+ if (lpCI->hMetaPict != NULL && !IsValidMetaPict(lpCI->hMetaPict))
+ {
+ return(OLEUI_CIERR_MUSTHAVECURRENTMETAFILE);
+ }
+
+ // Test to be sure that the class ID matches a registered class ID
+ // so we can return OLEUI_CIERR_MUSTHAVECLSID if necessary.
+ HGLOBAL hTemp = OleGetIconOfClass(lpCI->clsid, NULL, TRUE);
+ if (hTemp == NULL)
+ {
+ return(OLEUI_CIERR_MUSTHAVECLSID);
+ }
+ OleUIMetafilePictIconFree(hTemp);
+
+ if (lpCI->dwFlags & CIF_USEICONEXE &&
+ (lpCI->cchIconExe < 1 || lpCI->cchIconExe > MAX_PATH))
+ {
+ uRet = OLEUI_CIERR_SZICONEXEINVALID;
+ }
+
+ if (OLEUI_ERR_STANDARDMIN <= uRet)
+ {
+ return uRet;
+ }
+
+ // Now that we've validated everything, we can invoke the dialog.
+ uRet = UStandardInvocation(ChangeIconDialogProc, (LPOLEUISTANDARD)lpCI,
+ hMemDlg, MAKEINTRESOURCE(IDD_CHANGEICON));
+ return uRet;
+}
+
+/*
+ * ChangeIconDialogProc
+ *
+ * Purpose:
+ * Implements the OLE Change Icon dialog as invoked through the
+ * OleUIChangeIcon function.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ */
+BOOL CALLBACK ChangeIconDialogProc(HWND hDlg, UINT iMsg,
+ WPARAM wParam, LPARAM lParam)
+{
+
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ UINT uRet = 0;
+ LPCHANGEICON lpCI = (LPCHANGEICON)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
+
+ // If the hook processed the message, we're done.
+ if (0 != uRet)
+ return uRet;
+
+ // Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ TCHAR szTemp[MAX_PATH];
+ HICON hIcon;
+ HGLOBAL hMetaPict;
+
+ switch (iMsg)
+ {
+ case WM_DESTROY:
+ if (lpCI)
+ {
+ SendDlgItemMessage(hDlg, IDC_CI_ICONLIST, LB_RESETCONTENT, 0, 0L);
+ StandardCleanup(lpCI, hDlg);
+ }
+ break;
+ case WM_INITDIALOG:
+ FChangeIconInit(hDlg, wParam, lParam);
+ return TRUE;
+
+ case WM_MEASUREITEM:
+ {
+ LPMEASUREITEMSTRUCT lpMI = (LPMEASUREITEMSTRUCT)lParam;
+
+ // All icons are system metric+padding in width and height
+ lpMI->itemWidth = GetSystemMetrics(SM_CXICON)+CXICONPAD;
+ lpMI->itemHeight= GetSystemMetrics(SM_CYICON)+CYICONPAD;
+ }
+ break;
+
+ case WM_DRAWITEM:
+ return FDrawListIcon((LPDRAWITEMSTRUCT)lParam);
+
+ case WM_DELETEITEM:
+ DestroyIcon((HICON)(((LPDELETEITEMSTRUCT)lParam)->itemData));
+ break;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_CI_CURRENT:
+ case IDC_CI_DEFAULT:
+ case IDC_CI_FROMFILE:
+ UpdateResultIcon(lpCI, hDlg, (UINT)-1);
+ break;
+
+ case IDC_CI_LABELEDIT:
+ if (lpCI != NULL && EN_KILLFOCUS == wCode)
+ UpdateResultIcon(lpCI, hDlg, (UINT)-1);
+ break;
+
+ case IDC_CI_FROMFILEEDIT:
+ GetDlgItemText(hDlg, IDC_CI_FROMFILEEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR));
+ if (lpCI != NULL)
+ {
+ if (wCode == EN_KILLFOCUS)
+ {
+ if (lstrcmpi(szTemp, lpCI->szFile))
+ {
+ lstrcpy(lpCI->szFile, szTemp);
+ UFillIconList(hDlg, IDC_CI_ICONLIST, lpCI->szFile, FALSE);
+ UpdateResultIcon(lpCI, hDlg, IDC_CI_FROMFILE);
+ }
+ }
+ else if (wCode == EN_SETFOCUS)
+ {
+ UpdateResultIcon(lpCI, hDlg, IDC_CI_FROMFILE);
+ }
+ }
+ break;
+
+ case IDC_CI_ICONLIST:
+ switch (wCode)
+ {
+ case LBN_SETFOCUS:
+ // If we got the focus, see about updating.
+ GetDlgItemText(hDlg, IDC_CI_FROMFILEEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR));
+
+ // Check if file changed and update the list if so
+ if (lpCI && 0 != lstrcmpi(szTemp, lpCI->szFile))
+ {
+ lstrcpy(lpCI->szFile, szTemp);
+ UFillIconList(hDlg, IDC_CI_ICONLIST, lpCI->szFile, FALSE);
+ }
+ UpdateResultIcon(lpCI, hDlg, IDC_CI_FROMFILE);
+ break;
+
+ case LBN_SELCHANGE:
+ UpdateResultIcon(lpCI, hDlg, IDC_CI_FROMFILE);
+ break;
+
+ case LBN_DBLCLK:
+ SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
+ break;
+ }
+ break;
+
+ case IDC_CI_BROWSE:
+ {
+ lstrcpyn(szTemp, lpCI->szFile, sizeof(szTemp)/sizeof(TCHAR));
+ uRet = UStandardHook(lpCI, hDlg, uMsgBrowse, MAX_PATH_SIZE,
+ (LPARAM)lpCI->szFile);
+
+ DWORD dwOfnFlags = OFN_FILEMUSTEXIST;
+ if (lpCI->lpOCI->dwFlags & CIF_SHOWHELP)
+ dwOfnFlags |= OFN_SHOWHELP;
+
+ if (0 == uRet)
+ {
+ uRet = (BOOL)Browse(hDlg, lpCI->szFile, NULL, MAX_PATH_SIZE,
+ IDS_ICONFILTERS, dwOfnFlags, ID_BROWSE_CHANGEICON, NULL);
+ }
+
+ if (0 != uRet && 0 != lstrcmpi(szTemp, lpCI->szFile))
+ {
+ SetDlgItemText(hDlg, IDC_CI_FROMFILEEDIT, lpCI->szFile);
+ UFillIconList(hDlg, IDC_CI_ICONLIST, lpCI->szFile, TRUE);
+ UpdateResultIcon(lpCI, hDlg, IDC_CI_FROMFILE);
+ }
+ }
+ break;
+
+ case IDOK:
+ {
+ HWND hwndCtl = GetDlgItem(hDlg, IDOK);
+ if (hwndCtl == GetFocus())
+ {
+ GetDlgItemText(hDlg, IDC_CI_FROMFILEEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR));
+
+ // Check if the file name is valid
+ // if SelectFromFile radio button selected
+ if (lpCI->dwFlags & CIF_SELECTFROMFILE)
+ {
+ // Check if the file changed at all.
+ if (0 != lstrcmpi(szTemp, lpCI->szFile))
+ {
+ lstrcpy(lpCI->szFile, szTemp);
+ // file changed. May need to expand the name
+ // calling DoesFileExist will do the trick
+ DoesFileExist(lpCI->szFile, MAX_PATH);
+ UFillIconList(hDlg, IDC_CI_ICONLIST, lpCI->szFile, TRUE);
+ SetDlgItemText(hDlg, IDC_CI_FROMFILEEDIT, lpCI->szFile);
+ UpdateResultIcon(lpCI, hDlg, IDC_CI_FROMFILE);
+ return TRUE; // eat this message to prevent focus change.
+ }
+ if (!DoesFileExist(lpCI->szFile, MAX_PATH))
+ {
+ OpenFileError(hDlg, ERROR_FILE_NOT_FOUND, lpCI->szFile);
+ HWND hWnd = GetDlgItem(hDlg, IDC_CI_FROMFILEEDIT);
+ SetFocus(hWnd);
+ SendMessage(hWnd, EM_SETSEL, 0, -1);
+ return TRUE; // eat this message
+ }
+ }
+
+ // Get current metafile image
+ UpdateResultIcon(lpCI, hDlg, (UINT)-1);
+ hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, IDC_CI_ICONDISPLAY,
+ IBXM_IMAGEGET, 0, 0);
+
+ // Clean up the current icon that we extracted.
+ hIcon = (HICON)SendDlgItemMessage(hDlg, IDC_CI_CURRENTICON, STM_GETICON, 0, 0L);
+ DestroyIcon(hIcon);
+
+ // Clean up the default icon
+ DestroyIcon(lpCI->hDefIcon);
+
+ // Remove the prop set on our parent
+ RemoveProp(lpCI->lpOCI->hWndOwner, PROP_HWND_CHGICONDLG);
+
+ OleUIMetafilePictIconFree(lpCI->lpOCI->hMetaPict);
+ lpCI->lpOCI->hMetaPict = hMetaPict;
+ lpCI->lpOCI->dwFlags = lpCI->dwFlags;
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ }
+ else
+ {
+ SetFocus(hwndCtl);
+ SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
+ }
+ break;
+ }
+
+ case IDCANCEL:
+ // Free current icon display image
+ SendDlgItemMessage(hDlg, IDC_CI_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0);
+
+ // Clean up the current icon that we extracted.
+ hIcon = (HICON)SendDlgItemMessage(hDlg, IDC_CI_CURRENTICON, STM_GETICON, 0, 0L);
+ DestroyIcon(hIcon);
+
+ // Clean up the default icon
+ DestroyIcon(lpCI->hDefIcon);
+
+ // Remove the prop set on our parent
+ RemoveProp(lpCI->lpOCI->hWndOwner, PROP_HWND_CHGICONDLG);
+
+ // We leave hMetaPict intact on Cancel; caller's responsibility
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
+ break;
+
+ case IDC_OLEUIHELP:
+ PostMessage(lpCI->lpOCI->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_CHANGEICON, 0));
+ break;
+ }
+ break;
+
+ default:
+ if (lpCI && iMsg == lpCI->nBrowseHelpID)
+ {
+ PostMessage(lpCI->lpOCI->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_CHANGEICONBROWSE, 0));
+ }
+ if (iMsg == uMsgBrowseOFN &&
+ lpCI && lpCI->lpOCI && lpCI->lpOCI->hWndOwner)
+ {
+ SendMessage(lpCI->lpOCI->hWndOwner, uMsgBrowseOFN, wParam, lParam);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * FChangeIconInit
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the Change Icon dialog box.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+BOOL FChangeIconInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ LPCHANGEICON lpCI = (LPCHANGEICON)LpvStandardInit(hDlg, sizeof(CHANGEICON));
+
+ // LpvStandardInit send a termination to us already.
+ if (NULL == lpCI)
+ return FALSE;
+
+ // Save the original pointer and copy necessary information.
+ LPOLEUICHANGEICON lpOCI = (LPOLEUICHANGEICON)lParam;
+ lpCI->lpOCI = lpOCI;
+ lpCI->nIDD = IDD_CHANGEICON;
+ lpCI->dwFlags = lpOCI->dwFlags;
+
+ // Go extract the icon source from the metafile.
+ TCHAR szTemp[MAX_PATH];
+ OleUIMetafilePictExtractIconSource(lpOCI->hMetaPict, szTemp, &lpCI->iIcon);
+ GetLongPathName(szTemp, lpCI->szFile, MAX_PATH);
+
+ // Go extract the icon and the label from the metafile
+ OleUIMetafilePictExtractLabel(lpOCI->hMetaPict, lpCI->szLabel, OLEUI_CCHLABELMAX_SIZE, NULL);
+ lpCI->hCurIcon = OleUIMetafilePictExtractIcon(lpOCI->hMetaPict);
+
+ // Show or hide the help button
+ if (!(lpCI->dwFlags & CIF_SHOWHELP))
+ StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
+
+ // Set text limits and initial control contents
+ SendDlgItemMessage(hDlg, IDC_CI_LABELEDIT, EM_LIMITTEXT, OLEUI_CCHLABELMAX, 0L);
+ SendDlgItemMessage(hDlg, IDC_CI_FROMFILEEDIT, EM_LIMITTEXT, MAX_PATH, 0L);
+ SetDlgItemText(hDlg, IDC_CI_FROMFILEEDIT, lpCI->szFile);
+
+ // Copy the label text into the edit and static controls.
+ SetDlgItemText(hDlg, IDC_CI_LABELEDIT, lpCI->szLabel);
+
+ lpCI->hDefIcon = NULL;
+ if (lpCI->dwFlags & CIF_USEICONEXE)
+ {
+ lpCI->hDefIcon = StandardExtractIcon(_g_hOleStdInst, lpCI->lpOCI->szIconExe, 0);
+ if (NULL != lpCI->hDefIcon)
+ {
+ lstrcpy(lpCI->szDefIconFile, lpCI->lpOCI->szIconExe);
+ lpCI->iDefIcon = 0;
+ }
+ }
+
+ if (NULL == lpCI->hDefIcon)
+ {
+ HGLOBAL hMetaPict;
+ hMetaPict = OleGetIconOfClass(lpCI->lpOCI->clsid, NULL, TRUE);
+ lpCI->hDefIcon = OleUIMetafilePictExtractIcon(hMetaPict);
+ TCHAR szTemp[MAX_PATH];
+ OleUIMetafilePictExtractIconSource(hMetaPict,
+ szTemp, &lpCI->iDefIcon);
+ GetLongPathName(szTemp, lpCI->szDefIconFile, MAX_PATH);
+ OleUIMetafilePictIconFree(hMetaPict);
+ }
+
+ // Initialize all the icon displays.
+ SendDlgItemMessage(hDlg, IDC_CI_CURRENTICON, STM_SETICON,
+ (WPARAM)lpCI->hCurIcon, 0L);
+ SendDlgItemMessage(hDlg, IDC_CI_DEFAULTICON, STM_SETICON,
+ (WPARAM)lpCI->hDefIcon, 0L);
+
+ /*
+ * Since we cannot predict the size of icons on any display,
+ * we have to resize the icon listbox to the size of an icon
+ * (plus padding), a scrollbar, and two borders (top & bottom).
+ */
+ UINT cyList = GetSystemMetrics(SM_CYICON)+GetSystemMetrics(SM_CYHSCROLL)
+ +GetSystemMetrics(SM_CYBORDER)*2+CYICONPAD;
+ HWND hList = GetDlgItem(hDlg, IDC_CI_ICONLIST);
+ RECT rc;
+ GetClientRect(hList, &rc);
+ SetWindowPos(hList, NULL, 0, 0, rc.right, cyList, SWP_NOMOVE | SWP_NOZORDER);
+
+ // Set the columns in this multi-column listbox to hold one icon
+ SendMessage(hList, LB_SETCOLUMNWIDTH,
+ GetSystemMetrics(SM_CXICON)+CXICONPAD,0L);
+
+ /*
+ * If the listbox expanded below the group box, then size
+ * the groupbox down, move the label static and exit controls
+ * down, and expand the entire dialog appropriately.
+ */
+ GetWindowRect(hList, &rc);
+ RECT rcG;
+ GetWindowRect(GetDlgItem(hDlg, IDC_CI_GROUP), &rcG);
+ if (rc.bottom > rcG.bottom)
+ {
+ // Calculate amount to move things down.
+ cyList=(rcG.bottom-rcG.top)-(rc.bottom-rc.top-cyList);
+
+ // Expand the group box.
+ rcG.right -=rcG.left;
+ rcG.bottom-=rcG.top;
+ SetWindowPos(GetDlgItem(hDlg, IDC_CI_GROUP), NULL, 0, 0,
+ rcG.right, rcG.bottom+cyList, SWP_NOMOVE | SWP_NOZORDER);
+
+ // Expand the dialog box.
+ GetClientRect(hDlg, &rc);
+ SetWindowPos(hDlg, NULL, 0, 0, rc.right, rc.bottom+cyList,
+ SWP_NOMOVE | SWP_NOZORDER);
+
+ // Move the label and edit controls down.
+ GetClientRect(GetDlgItem(hDlg, IDC_CI_LABEL), &rc);
+ SetWindowPos(GetDlgItem(hDlg, IDC_CI_LABEL), NULL, 0, cyList,
+ rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER);
+
+ GetClientRect(GetDlgItem(hDlg, IDC_CI_LABELEDIT), &rc);
+ SetWindowPos(GetDlgItem(hDlg, IDC_CI_LABELEDIT), NULL, 0, cyList,
+ rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER);
+ }
+
+ /*
+ * Select Current, Default, or From File radiobuttons appropriately.
+ * The CheckRadioButton call sends WM_COMMANDs which handle
+ * other actions. Note that if we check From File, which
+ * takes an icon from the list, we better fill the list.
+ * This will also fill the list even if default is selected.
+ */
+ if (0 != UFillIconList(hDlg, IDC_CI_ICONLIST, lpCI->szFile, FALSE))
+ {
+ // If szFile worked, then select the source icon in the listbox.
+ SendDlgItemMessage(hDlg, IDC_CI_ICONLIST, LB_SETCURSEL, lpCI->iIcon, 0L);
+ }
+
+ if (lpCI->dwFlags & CIF_SELECTCURRENT)
+ {
+ CheckRadioButton(hDlg, IDC_CI_CURRENT, IDC_CI_FROMFILE, IDC_CI_CURRENT);
+ }
+ else
+ {
+ UINT uID = (lpCI->dwFlags & CIF_SELECTFROMFILE) ? IDC_CI_FROMFILE : IDC_CI_DEFAULT;
+ CheckRadioButton(hDlg, IDC_CI_CURRENT, IDC_CI_FROMFILE, uID);
+ }
+ UpdateResultIcon(lpCI, hDlg, (UINT)-1);
+
+ // Change the caption
+ if (NULL!=lpOCI->lpszCaption)
+ SetWindowText(hDlg, lpOCI->lpszCaption);
+
+ /* Give our parent window access to our hDlg (via a special SetProp).
+ * The PasteSpecial dialog may need to force our dialog down if the
+ * clipboard contents change underneath it. if so it will send
+ * us a IDCANCEL command.
+ */
+ SetProp(lpCI->lpOCI->hWndOwner, PROP_HWND_CHGICONDLG, hDlg);
+ lpCI->nBrowseHelpID = RegisterWindowMessage(HELPMSGSTRING);
+
+ // Call the hook with lCustData in lParam
+ UStandardHook(lpCI, hDlg, WM_INITDIALOG, wParam, lpOCI->lCustData);
+ return TRUE;
+}
+
+/*
+ * UFillIconList
+ *
+ * Purpose:
+ * Given a listbox and a filename, attempts to open that file and
+ * read all the icons that exist therein, adding them to the listbox
+ * hList as owner-draw items. If the file does not exist or has no
+ * icons, then you get no icons and an appropriate warning message.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog containing the listbox.
+ * idList UINT identifier of the listbox to fill.
+ * pszFile LPSTR of the file from which to extract icons.
+ *
+ * Return Value:
+ * UINT Number of items added to the listbox. 0 on failure.
+ */
+UINT UFillIconList(HWND hDlg, UINT idList, LPTSTR pszFile, BOOL bError)
+{
+ HWND hList = GetDlgItem(hDlg, idList);
+ if (NULL == hList)
+ return 0;
+
+ // Clean out the listbox.
+ SendMessage(hList, LB_RESETCONTENT, 0, 0L);
+
+ // If we have an empty string, just exit leaving the listbox empty as well
+ if (0 == lstrlen(pszFile))
+ return 0;
+
+ // Turn on the hourglass
+ HCURSOR hCur = HourGlassOn();
+ UINT nFileError = 0;
+
+ // Check if the file is valid.
+ TCHAR szPathName[MAX_PATH];
+ LPTSTR lpszFilePart = NULL;
+ UINT cIcons = 0;
+ if (SearchPath(NULL, pszFile, NULL, MAX_PATH, szPathName, &lpszFilePart) != 0)
+ {
+ // This hack is still necessary in Win32 because even under
+ // Win32s this ExtractIcon bug appears.
+ #ifdef EXTRACTICONWORKS
+ // Get the icon count for this file.
+ cIcons = (UINT)StandardExtractIcon(_g_hOleStdInst, szPathName, (UINT)-1);
+ #else
+ /*
+ * ExtractIcon in Windows 3.1 with -1 eats a selector, leaving an
+ * extra global memory object around for this applciation. Since
+ * changing icons may happen very often with all OLE apps in
+ * the system, we have to work around it. So we'll say we
+ * have lots of icons and just call ExtractIcon until it
+ * fails. We check if there's any around by trying to get
+ * the first one.
+ */
+ cIcons = 0xFFFF;
+ HICON hIcon = StandardExtractIcon(_g_hOleStdInst, szPathName, 0);
+
+ // Fake a failure with cIcons=0, or cleanup hIcon from this test.
+ if (NULL == hIcon || 1 == (int)hIcon)
+ cIcons = 0;
+ else
+ DestroyIcon(hIcon);
+ #endif
+
+ if (0 != cIcons)
+ {
+ SendMessage(hList, WM_SETREDRAW, FALSE, 0L);
+ for (UINT i = 0; i < cIcons; i++)
+ {
+ hIcon=StandardExtractIcon(_g_hOleStdInst, szPathName, i);
+ if (hIcon != NULL)
+ SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)hIcon);
+ else
+ break;
+ }
+
+ //Force complete repaint
+ SendMessage(hList, WM_SETREDRAW, TRUE, 0L);
+ InvalidateRect(hList, NULL, TRUE);
+
+ //Select an icon
+ SendMessage(hList, LB_SETCURSEL, 0, 0L);
+ }
+ else
+ nFileError = IDS_CINOICONSINFILE;
+ }
+ else
+ nFileError = ERROR_FILE_NOT_FOUND;
+
+ // show error if necessary and possible
+ if (nFileError && bError)
+ {
+ ErrorWithFile(hDlg, _g_hOleStdResInst, nFileError, szPathName,
+ MB_OK | MB_ICONEXCLAMATION);
+ }
+
+ HourGlassOff(hCur);
+ return cIcons;
+}
+
+/*
+ * FDrawListIcon
+ *
+ * Purpose:
+ * Handles WM_DRAWITEM for the icon listbox.
+ *
+ * Parameters:
+ * lpDI LPDRAWITEMSTRUCT from WM_DRAWITEM
+ *
+ * Return Value:
+ * BOOL TRUE if we did anything, FALSE if there are no items
+ * in the list.
+ */
+BOOL FDrawListIcon(LPDRAWITEMSTRUCT lpDI)
+{
+ /*
+ * If there are no items in the list, then itemID is negative according
+ * to the Win3.1 SDK. Unfortunately DRAWITEMSTRUCT has an unsigned int
+ * for this field, so we need the typecast to do a signed comparison.
+ */
+ if ((int)lpDI->itemID < 0)
+ return FALSE;
+
+ /*
+ * For selection or draw entire case we just draw the entire item all
+ * over again. For focus cases, we only call DrawFocusRect.
+ */
+ if (lpDI->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))
+ {
+ COLORREF cr;
+
+ // Clear background and draw the icon.
+ if (lpDI->itemState & ODS_SELECTED)
+ cr = SetBkColor(lpDI->hDC, GetSysColor(COLOR_HIGHLIGHT));
+ else
+ cr = SetBkColor(lpDI->hDC, GetSysColor(COLOR_WINDOW));
+
+ // Draw a cheap rectangle.
+ ExtTextOut(lpDI->hDC, 0, 0, ETO_OPAQUE, &lpDI->rcItem, NULL, 0, NULL);
+ DrawIcon(lpDI->hDC, lpDI->rcItem.left+(CXICONPAD/2),
+ lpDI->rcItem.top+(CYICONPAD/2), (HICON)(lpDI->itemData));
+
+ // Restore original background for DrawFocusRect
+ SetBkColor(lpDI->hDC, cr);
+ }
+
+ // Always change focus on the focus action.
+ if (lpDI->itemAction & ODA_FOCUS || lpDI->itemState & ODS_FOCUS)
+ DrawFocusRect(lpDI->hDC, &lpDI->rcItem);
+
+ return TRUE;
+}
+
+/*
+ * UpdateResultIcon
+ *
+ * Purpose:
+ * Updates the result icon using the current icon in the default display
+ * or the icon listbox depending on fFromDefault.
+ *
+ * Parameters:
+ * lpCI LPCHANGEICON containing dialog flags.
+ * hDlg HWND of the dialog
+ * uID UINT identifying the radiobutton selected.
+ *
+ * Return Value:
+ * None
+ */
+void UpdateResultIcon(LPCHANGEICON lpCI, HWND hDlg, UINT uID)
+{
+ if (uID == -1)
+ {
+ if (SendDlgItemMessage(hDlg, IDC_CI_CURRENT, BM_GETCHECK, 0, 0))
+ uID = IDC_CI_CURRENT;
+ else if (SendDlgItemMessage(hDlg, IDC_CI_DEFAULT, BM_GETCHECK, 0, 0))
+ uID = IDC_CI_DEFAULT;
+ else if (SendDlgItemMessage(hDlg, IDC_CI_FROMFILE, BM_GETCHECK, 0, 0))
+ uID = IDC_CI_FROMFILE;
+ }
+
+ lpCI->dwFlags &= ~(CIF_SELECTCURRENT | CIF_SELECTDEFAULT | CIF_SELECTFROMFILE);
+ LONG lTemp = -1;
+
+ switch (uID)
+ {
+ case IDC_CI_CURRENT:
+ lTemp = SendDlgItemMessage(hDlg, IDC_CI_CURRENTICON, STM_GETICON, 0, 0L);
+ lpCI->dwFlags |= CIF_SELECTCURRENT;
+ break;
+
+ case IDC_CI_DEFAULT:
+ lTemp = SendDlgItemMessage(hDlg, IDC_CI_DEFAULTICON, STM_GETICON, 0, 0L);
+ lpCI->dwFlags |= CIF_SELECTDEFAULT;
+ break;
+
+ case IDC_CI_FROMFILE:
+ {
+ // Get the selected icon from the list and place it in the result
+ lpCI->dwFlags |= CIF_SELECTFROMFILE;
+ UINT iSel = (UINT)SendDlgItemMessage(hDlg, IDC_CI_ICONLIST, LB_GETCURSEL, 0, 0L);
+ if (LB_ERR == (int)iSel)
+ lTemp = SendDlgItemMessage(hDlg, IDC_CI_DEFAULTICON, STM_GETICON, 0, 0L);
+ else
+ lTemp = SendDlgItemMessage(hDlg, IDC_CI_ICONLIST, LB_GETITEMDATA, iSel, 0);
+ break;
+ }
+
+ default:
+ OleDbgAssert(FALSE);
+ break;
+ }
+ CheckRadioButton(hDlg, IDC_CI_CURRENT, IDC_CI_FROMFILE, uID);
+
+ // set current icon display as a result of the controls
+ LPTSTR lpszSourceFile = lpCI->szFile;
+ if (lpCI->dwFlags & CIF_SELECTDEFAULT)
+ {
+ // use defaults
+ lpszSourceFile = lpCI->szDefIconFile;
+ lpCI->iIcon = lpCI->iDefIcon;
+ }
+ else if (lpCI->dwFlags & CIF_SELECTCURRENT)
+ {
+ TCHAR szTemp[MAX_PATH];
+ OleUIMetafilePictExtractIconSource(lpCI->lpOCI->hMetaPict,
+ szTemp, &lpCI->iIcon);
+ GetLongPathName(szTemp, lpszSourceFile, MAX_PATH);
+ }
+ else if (lpCI->dwFlags & CIF_SELECTFROMFILE)
+ {
+ // get from file and index
+ GetDlgItemText(hDlg, IDC_CI_FROMFILEEDIT, lpszSourceFile, MAX_PATH);
+ lpCI->iIcon = (UINT)SendDlgItemMessage(hDlg,
+ IDC_CI_ICONLIST, LB_GETCURSEL, 0, 0L);
+ }
+
+ // Get new hMetaPict and set result text
+ TCHAR szTemp[MAX_PATH];
+ GetDlgItemText(hDlg, IDC_CI_LABELEDIT, szTemp, MAX_PATH);
+ TCHAR szShortFile[MAX_PATH];
+ GetShortPathName(lpszSourceFile, szShortFile, MAX_PATH);
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszTemp[MAX_PATH];
+ OLECHAR wszSourceFile[MAX_PATH];
+ ATOW(wszTemp, szTemp, MAX_PATH);
+ ATOW(wszSourceFile, szShortFile, MAX_PATH);
+ HGLOBAL hMetaPict = OleMetafilePictFromIconAndLabel(
+ (HICON)lTemp, wszTemp, wszSourceFile, lpCI->iIcon);
+#else
+ HGLOBAL hMetaPict = OleMetafilePictFromIconAndLabel(
+ (HICON)lTemp, szTemp, szShortFile, lpCI->iIcon);
+#endif
+ SendDlgItemMessage(hDlg, IDC_CI_ICONDISPLAY, IBXM_IMAGESET, 1,
+ (LPARAM)hMetaPict);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: IsLongComponent, public
+//
+// Synopsis: Determines whether the current path component is a legal
+// 8.3 name or not. If not, it is considered to be a long
+// component.
+//
+// Arguments: [pwcsPath] - Path to check
+// [ppwcsEnd] - Return for end of component pointer
+//
+// Returns: BOOL
+//
+// Modifies: [ppwcsEnd]
+//
+// History: 28-Aug-94 DrewB Created
+// 5-04-95 stevebl Modified for use by oledlg
+//
+// Notes: An empty path is considered to be long
+// The following characters are not valid in file name domain:
+// * + , : ; < = > ? [ ] |
+//
+//----------------------------------------------------------------------------
+
+BOOL IsLongComponent(LPCTSTR pwcsPath,
+ PTSTR *ppwcsEnd)
+{
+ LPTSTR pwcEnd, pwcDot;
+ BOOL fLongNameFound;
+ TCHAR wc;
+
+ pwcEnd = (LPTSTR)pwcsPath;
+ fLongNameFound = FALSE;
+ pwcDot = NULL;
+
+ while (TRUE)
+ {
+ wc = *pwcEnd;
+
+ if (wc == '\\' || wc == 0)
+ {
+ *ppwcsEnd = pwcEnd;
+
+ // We're at a component terminator, so make the
+ // determination of whether what we've seen is a long
+ // name or short one
+
+ // If we've aready seen illegal characters or invalid
+ // structure for a short name, don't bother to check lengths
+ if (pwcEnd-pwcsPath > 0 && !fLongNameFound)
+ {
+ // If this component fits in 8.3 then it is a short name
+ if ((!pwcDot && (ULONG)(pwcEnd - pwcsPath) <= 8) ||
+ (pwcDot && ((ULONG)(pwcEnd - pwcDot) <= 3 + 1 &&
+ (ULONG)(pwcEnd - pwcsPath) <= 8 + 3 + 1)))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ // Handle dots
+ if (wc == '.')
+ {
+ // If two or more '.' or the base name is longer than
+ // 8 characters or no base name at all, it is an illegal dos
+ // file name
+ if (pwcDot != NULL ||
+ ((ULONG)(pwcEnd - pwcsPath)) > 8 ||
+ (pwcEnd == pwcsPath && *(pwcEnd + 1) != '\\'))
+ {
+ fLongNameFound = TRUE;
+ }
+
+ pwcDot = pwcEnd;
+ }
+
+ // Check for characters which aren't valid in short names
+ else if (wc <= ' ' ||
+ wc == '*' ||
+ wc == '+' ||
+ wc == ',' ||
+ wc == ':' ||
+ wc == ';' ||
+ wc == '<' ||
+ wc == '=' ||
+ wc == '>' ||
+ wc == '?' ||
+ wc == '[' ||
+ wc == ']' ||
+ wc == '|')
+ {
+ fLongNameFound = TRUE;
+ }
+
+ pwcEnd++;
+ }
+}
+
+//
+// The following code was stolen from NT's RTL in curdir.c
+//
+
+#define IS_PATH_SEPARATOR(wch) \
+ ((wch) == '\\' || (wch) == '/')
+
+typedef enum
+{
+ PATH_TYPE_UNKNOWN,
+ PATH_TYPE_UNC_ABSOLUTE,
+ PATH_TYPE_LOCAL_DEVICE,
+ PATH_TYPE_ROOT_LOCAL_DEVICE,
+ PATH_TYPE_DRIVE_ABSOLUTE,
+ PATH_TYPE_DRIVE_RELATIVE,
+ PATH_TYPE_ROOTED,
+ PATH_TYPE_RELATIVE
+} PATH_TYPE;
+
+PATH_TYPE
+DetermineDosPathNameType(
+ IN LPCTSTR DosFileName
+ )
+
+/*++
+
+Routine Description:
+
+ This function examines the Dos format file name and determines the
+ type of file name (i.e. UNC, DriveAbsolute, Current Directory
+ rooted, or Relative.
+
+Arguments:
+
+ DosFileName - Supplies the Dos format file name whose type is to be
+ determined.
+
+Return Value:
+
+ PATH_TYPE_UNKNOWN - The path type can not be determined
+
+ PATH_TYPE_UNC_ABSOLUTE - The path specifies a Unc absolute path
+ in the format \\server-name\sharename\rest-of-path
+
+ PATH_TYPE_LOCAL_DEVICE - The path specifies a local device in the format
+ \\.\rest-of-path this can be used for any device where the nt and
+ Win32 names are the same. For example mailslots.
+
+ PATH_TYPE_ROOT_LOCAL_DEVICE - The path specifies the root of the local
+ devices in the format \\.
+
+ PATH_TYPE_DRIVE_ABSOLUTE - The path specifies a drive letter absolute
+ path in the form drive:\rest-of-path
+
+ PATH_TYPE_DRIVE_RELATIVE - The path specifies a drive letter relative
+ path in the form drive:rest-of-path
+
+ PATH_TYPE_ROOTED - The path is rooted relative to the current disk
+ designator (either Unc disk, or drive). The form is \rest-of-path.
+
+ PATH_TYPE_RELATIVE - The path is relative (i.e. not absolute or rooted).
+
+--*/
+
+{
+ PATH_TYPE ReturnValue;
+
+ if ( IS_PATH_SEPARATOR(*DosFileName) )
+ {
+ if ( IS_PATH_SEPARATOR(*(DosFileName+1)) )
+ {
+ if ( DosFileName[2] == '.' )
+ {
+ if ( IS_PATH_SEPARATOR(*(DosFileName+3)) )
+ {
+ ReturnValue = PATH_TYPE_LOCAL_DEVICE;
+ }
+ else if ( (*(DosFileName+3)) == 0 )
+ {
+ ReturnValue = PATH_TYPE_ROOT_LOCAL_DEVICE;
+ }
+ else
+ {
+ ReturnValue = PATH_TYPE_UNC_ABSOLUTE;
+ }
+ }
+ else
+ {
+ ReturnValue = PATH_TYPE_UNC_ABSOLUTE;
+ }
+ }
+ else
+ {
+ ReturnValue = PATH_TYPE_ROOTED;
+ }
+ }
+ else if (*(DosFileName+1) == ':')
+ {
+ if (IS_PATH_SEPARATOR(*(DosFileName+2)))
+ {
+ ReturnValue = PATH_TYPE_DRIVE_ABSOLUTE;
+ }
+ else
+ {
+ ReturnValue = PATH_TYPE_DRIVE_RELATIVE;
+ }
+ }
+ else
+ {
+ ReturnValue = PATH_TYPE_RELATIVE;
+ }
+
+ return ReturnValue;
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: GetLongPathName, public
+//
+// Synopsis: Expand each component of the given path into its
+// long form
+//
+// Arguments: [pwcsPath] - Path
+// [pwcsLongPath] - Long path return buffer
+// [cchLongPath] - Size of return buffer in characters
+//
+// Returns: 0 for errors
+// Number of characters needed for buffer if buffer is too small
+// includes NULL terminator
+// Length of long path, doesn't include NULL terminator
+//
+// Modifies: [pwcsLongPath]
+//
+// History: 28-Aug-94 DrewB Created
+// 11-Nov-94 BruceMa Modifed to use for Chicago at
+// FindFirstFile
+// 5-04-95 stevebl Modified for use by OLEDLG
+//
+// Notes: The source and destination buffers can be the same memory
+// Doesn't handle paths with internal . and .., although
+// they are handled at the beginning
+//
+//----------------------------------------------------------------------------
+
+ULONG
+GetLongPathName(LPCTSTR pcsPath,
+ LPTSTR pwcsLongPath,
+ ULONG cchLongPath)
+{
+ PATH_TYPE pt;
+ HANDLE h;
+ LPTSTR pwcsLocalLongPath;
+ ULONG cchReturn, cb, cch, cchOutput;
+ LPTSTR pwcStart = NULL;
+ LPTSTR pwcEnd;
+ LPTSTR pwcLong;
+ TCHAR wcSave;
+ BOOL fLong;
+ WIN32_FIND_DATA wfd;
+ cchReturn = 0;
+ pwcsLocalLongPath = NULL;
+
+ __try
+ {
+ //
+ // First, run down the string checking for tilde's. Any path
+ // that has a short name section to it will have a tilde. If
+ // there are no tilde's, then we already have the long path,
+ // so we can return the string.
+ //
+ fLong = TRUE;
+ for (pwcLong = (LPTSTR)pcsPath; *pwcLong != 0; pwcLong++)
+ {
+ if (*pwcLong == L'~')
+ {
+ fLong = FALSE;
+ }
+ }
+ //
+ // This derives the number of characters, including the NULL
+ //
+ cch = (pwcLong - pcsPath) + 1;
+
+ //
+ // If it isn't a long path already, then we are going to have
+ // to parse it.
+ //
+ if (!fLong)
+ {
+ // Decide the path type, we want find out the position of
+ // the first character of the first name
+ pt = DetermineDosPathNameType(pcsPath);
+ switch(pt)
+ {
+ // Form: "\\server_name\share_name\rest_of_the_path"
+ case PATH_TYPE_UNC_ABSOLUTE:
+#if defined(UNICODE)
+ if ((pwcStart = wcschr(pcsPath + 2, L'\\')) != NULL &&
+ (pwcStart = wcschr(pwcStart + 1, L'\\')) != NULL)
+#else
+ if ((pwcStart = strchr(pcsPath + 2, '\\')) != NULL &&
+ (pwcStart = strchr(pwcStart + 1, '\\')) != NULL)
+#endif
+ {
+ pwcStart++;
+ }
+ else
+ {
+ pwcStart = NULL;
+ }
+ break;
+
+ // Form: "\\.\rest_of_the_path"
+ case PATH_TYPE_LOCAL_DEVICE:
+ pwcStart = (LPTSTR)pcsPath + 4;
+ break;
+
+ // Form: "\\."
+ case PATH_TYPE_ROOT_LOCAL_DEVICE:
+ pwcStart = NULL;
+ break;
+
+ // Form: "D:\rest_of_the_path"
+ case PATH_TYPE_DRIVE_ABSOLUTE:
+ pwcStart = (LPTSTR)pcsPath + 3;
+ break;
+
+ // Form: "rest_of_the_path"
+ case PATH_TYPE_RELATIVE:
+ pwcStart = (LPTSTR) pcsPath;
+ goto EatDots;
+
+ // Form: "D:rest_of_the_path"
+ case PATH_TYPE_DRIVE_RELATIVE:
+ pwcStart = (LPTSTR)pcsPath+2;
+
+ EatDots:
+ // Handle .\ and ..\ cases
+ while (*pwcStart != 0 && *pwcStart == L'.')
+ {
+ if (pwcStart[1] == L'\\')
+ {
+ pwcStart += 2;
+ }
+ else if (pwcStart[1] == L'.' && pwcStart[2] == L'\\')
+ {
+ pwcStart += 3;
+ }
+ else
+ {
+ break;
+ }
+ }
+ break;
+
+ // Form: "\rest_of_the_path"
+ case PATH_TYPE_ROOTED:
+ pwcStart = (LPTSTR)pcsPath + 1;
+ break;
+
+ default:
+ pwcStart = NULL;
+ break;
+ }
+ }
+
+ // In the special case where we have no work to do, exit quickly
+ // This saves a lot of instructions for trivial cases
+ // In one case the path as given requires no processing
+ // The middle case, we determine there were no tilde's in the path
+ // In the other, the path only has one component and it is already
+ // long
+ ///
+ if (pwcStart == NULL ||
+ (fLong == TRUE) ||
+ ((fLong = IsLongComponent(pwcStart, &pwcEnd)) &&
+ *pwcEnd == 0))
+ {
+ // Nothing to convert, copy down the source string
+ // to the buffer if necessary
+
+ if (pwcStart != NULL)
+ {
+ cch = (ULONG)(pwcEnd - pcsPath + 1);
+ }
+
+ if (cchLongPath >= cch)
+ {
+ memcpy(pwcsLongPath, pcsPath, cch * sizeof(TCHAR));
+
+ cchReturn = cch - 1;
+ goto gsnTryExit;
+ }
+ else
+ {
+ cchReturn = cch;
+ goto gsnTryExit;
+ }
+ }
+
+ // Make a local buffer so that we won't overlap the
+ // source pathname in case the long name is longer than the
+ // source name.
+ if (cchLongPath > 0)
+ {
+ pwcsLocalLongPath = (PTCHAR)malloc(cchLongPath * sizeof(TCHAR));
+ if (pwcsLocalLongPath == NULL)
+ {
+ goto gsnTryExit;
+ }
+ }
+
+ // Set up pointer to copy output to
+ pwcLong = pwcsLocalLongPath;
+ cchOutput = 0;
+
+ // Copy the portions of the path that we skipped initially
+ cch = pwcStart-pcsPath;
+ cchOutput += cch;
+ if (cchOutput <= cchLongPath)
+ {
+ memcpy(pwcLong, pcsPath, cch*sizeof(TCHAR));
+ pwcLong += cch;
+ }
+
+ for (;;)
+ {
+ // Determine whether the current component is long or short
+ cch = pwcEnd-pwcStart+1;
+ cb = cch*sizeof(TCHAR);
+
+ if (fLong)
+ {
+ // If the component is already long, just copy it into
+ // the output. Copy the terminating character along with it
+ // so the output remains properly punctuated
+
+ cchOutput += cch;
+ if (cchOutput <= cchLongPath)
+ {
+ memcpy(pwcLong, pwcStart, cb);
+ pwcLong += cch;
+ }
+ }
+ else
+ {
+ TCHAR wcsTmp[MAX_PATH];
+
+ // For a short component we need to determine the
+ // long name, if there is one. The only way to
+ // do this reliably is to enumerate for the child
+
+ wcSave = *pwcEnd;
+ *pwcEnd = 0;
+
+ h = FindFirstFile(pcsPath, &wfd);
+ *pwcEnd = wcSave;
+
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ goto gsnTryExit;
+ }
+
+ FindClose(h);
+
+ lstrcpy(wcsTmp, wfd.cFileName);
+
+ // Copy the filename returned by the query into the output
+ // Copy the terminator from the original component into
+ // the output to maintain punctuation
+ cch = lstrlen(wcsTmp)+1;
+ cchOutput += cch;
+ if (cchOutput <= cchLongPath)
+ {
+ memcpy(pwcLong, wcsTmp, (cch-1)*sizeof(TCHAR));
+ pwcLong += cch;
+ *(pwcLong-1) = *pwcEnd;
+ }
+ }
+
+ if (*pwcEnd == 0)
+ {
+ break;
+ }
+
+ // Update start pointer to next component
+ pwcStart = pwcEnd+1;
+ fLong = IsLongComponent(pwcStart, &pwcEnd);
+ }
+
+ // Copy local output buffer to given output buffer if necessary
+ if (cchLongPath >= cchOutput)
+ {
+ memcpy(pwcsLongPath, pwcsLocalLongPath, cchOutput * sizeof(TCHAR));
+ cchReturn = cchOutput-1;
+ }
+ else
+ {
+ cchReturn = cchOutput;
+ }
+
+gsnTryExit:;
+ }
+ __finally
+ {
+ if (pwcsLocalLongPath != NULL)
+ {
+ free(pwcsLocalLongPath);
+ pwcsLocalLongPath = NULL;
+ }
+ }
+
+ return cchReturn;
+}
+
diff --git a/private/ole2ui32/iconbox.cpp b/private/ole2ui32/iconbox.cpp
new file mode 100644
index 000000000..d18adb8be
--- /dev/null
+++ b/private/ole2ui32/iconbox.cpp
@@ -0,0 +1,215 @@
+/*
+ * ICONBOX.CPP
+ *
+ * Implemenatation of an IconBox control for OLE 2.0 UI dialogs that we'll
+ * use wherever a dialog needs an icon/label display. Through the control's
+ * interface we can change the image or control label visibility.
+ *
+ * The IconBox discusses images in CF_METAFILEPICT format. When drawing
+ * such a metafile, the entire aspect is centered in the IconBox, so long
+ * labels are chopped at either end.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "iconbox.h"
+#include "utility.h"
+#include "uiclass.h"
+
+OLEDBGDATA
+
+//Flag indicating if we've registered the class
+static BOOL fRegistered;
+
+
+/*
+ * FIconBoxInitialize
+ *
+ * Purpose:
+ * Registers the IconBox control class.
+ *
+ * Parameters:
+ * hInst HINSTANCE instance of the DLL.
+ *
+ * hPrevInst HINSTANCE of the previous instance. Used to
+ * determine whether to register window classes or not.
+ *
+ * Return Value:
+ * BOOL TRUE if all initialization succeeded, FALSE otherwise.
+ */
+
+#pragma code_seg(".text$initseg")
+
+BOOL FIconBoxInitialize(HINSTANCE hInst, HINSTANCE hPrevInst)
+{
+ // Only register class if we're the first instance
+ if (hPrevInst)
+ fRegistered = TRUE;
+ else
+ {
+ // Static flag fRegistered guards against calling this function more
+ // than once
+ if (!fRegistered)
+ {
+ WNDCLASS wc;
+ wc.lpfnWndProc =IconBoxWndProc;
+ wc.cbClsExtra =0;
+ wc.cbWndExtra =CBICONBOXWNDEXTRA;
+ wc.hInstance =hInst;
+ wc.hIcon =NULL;
+ wc.hCursor =LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground =(HBRUSH)NULL;
+ wc.lpszMenuName =NULL;
+ wc.style =CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
+
+ wc.lpszClassName = TEXT(SZCLASSICONBOX1);
+ fRegistered = RegisterClass(&wc);
+
+ wc.lpszClassName = TEXT(SZCLASSICONBOX2);
+ fRegistered = RegisterClass(&wc);
+
+ wc.lpszClassName = TEXT(SZCLASSICONBOX3);
+ fRegistered = RegisterClass(&wc);
+ }
+ }
+ return fRegistered;
+}
+
+#pragma code_seg()
+
+
+/*
+ * IconBoxUninitialize
+ *
+ * Purpose:
+ * Cleans up anything done in FIconBoxInitialize. Currently there is
+ * nothing, but we do this for symmetry.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ */
+
+void IconBoxUninitialize(void)
+{
+ return;
+}
+
+/*
+ * IconBoxWndProc
+ *
+ * Purpose:
+ * Window Procedure for the IconBox custom control. Only handles
+ * WM_CREATE, WM_PAINT, and private messages to manipulate the image.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ */
+
+LONG CALLBACK IconBoxWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ //Handle standard Windows messages.
+ switch (iMsg)
+ {
+ case WM_CREATE:
+ SetWindowLong(hWnd, IBWW_HIMAGE, 0);
+ SetWindowWord(hWnd, IBWW_FLABEL, TRUE);
+ return 0L;
+
+ case WM_ERASEBKGND:
+ {
+
+ RECT rect;
+ GetClientRect(hWnd, &rect);
+ HBRUSH hBrush = (HBRUSH)SendMessage(GetParent(hWnd), WM_CTLCOLORDLG,
+ wParam, (LPARAM)GetParent(hWnd));
+
+ if (!hBrush)
+ return FALSE;
+
+ UnrealizeObject(hBrush);
+
+ SetBrushOrgEx((HDC)wParam, 0, 0, NULL);
+ FillRect((HDC)wParam, &rect, hBrush);
+ return TRUE;
+ }
+
+ case WM_PAINT:
+ {
+ HGLOBAL hMF = (HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE);
+
+ //BeginPaint and EndPaint clear us even if hMF is NULL.
+ PAINTSTRUCT ps;
+ HDC hDC = BeginPaint(hWnd, &ps);
+
+ if (NULL != hMF)
+ {
+ //Now we get to paint the metafile, centered in our rect.
+ RECT rc;
+ GetClientRect(hWnd, &rc);
+
+ /*
+ * If we're doing icon only, then place the metafile
+ * at the center of our box minus half the icon width.
+ * Top is top.
+ */
+ BOOL fLabel = GetWindowWord(hWnd, IBWW_FLABEL);
+
+ //Go draw where we decided to place it.
+ OleUIMetafilePictIconDraw(hDC, &rc, hMF, !fLabel);
+ }
+ EndPaint(hWnd, &ps);
+ }
+ break;
+
+ case IBXM_IMAGESET:
+ {
+ /*
+ * wParam is a flag to delete the old or not.
+ * lParam contains the new handle.
+ */
+ HGLOBAL hMF = (HGLOBAL)SetWindowLong(hWnd, IBWW_HIMAGE, lParam);
+ InvalidateRect(hWnd, NULL, TRUE);
+ UpdateWindow(hWnd);
+
+ //Delete the old handle if requested
+ if (0L!=wParam)
+ {
+ OleUIMetafilePictIconFree(hMF);
+ hMF=NULL;
+ }
+ return (LONG)(UINT)hMF;
+ }
+
+ case IBXM_IMAGEGET:
+ {
+ //Return the current index.
+ HGLOBAL hMF=(HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE);
+ return (LONG)(UINT)hMF;
+ }
+
+ case IBXM_IMAGEFREE:
+ {
+ //Free up whatever we're holding.
+ HGLOBAL hMF=(HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE);
+ OleUIMetafilePictIconFree(hMF);
+ SetWindowLong(hWnd, IBWW_HIMAGE, 0);
+ return 1L;
+ }
+
+ case IBXM_LABELENABLE:
+ //wParam has the new flag, returns the previous flag.
+ return (LONG)SetWindowWord(hWnd, IBWW_FLABEL, (WORD)wParam);
+
+ default:
+ return DefWindowProc(hWnd, iMsg, wParam, lParam);
+ }
+
+ return 0L;
+}
diff --git a/private/ole2ui32/iconbox.h b/private/ole2ui32/iconbox.h
new file mode 100644
index 000000000..dc6084052
--- /dev/null
+++ b/private/ole2ui32/iconbox.h
@@ -0,0 +1,29 @@
+/*
+ * ICONBOX.H
+ *
+ * Structures and definitions for the IconBox control.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+
+#ifndef _ICONBOX_H_
+#define _ICONBOX_H_
+
+// Function prototypes
+BOOL FIconBoxInitialize(HINSTANCE, HINSTANCE);
+void IconBoxUninitialize(void);
+LONG CALLBACK IconBoxWndProc(HWND, UINT, WPARAM, LPARAM);
+
+// Window extra bytes contain the bitmap index we deal with currently.
+#define CBICONBOXWNDEXTRA (sizeof(HGLOBAL)+sizeof(BOOL))
+#define IBWW_HIMAGE 0
+#define IBWW_FLABEL (sizeof(HGLOBAL))
+
+// Control messages
+#define IBXM_IMAGESET (WM_USER+0)
+#define IBXM_IMAGEGET (WM_USER+1)
+#define IBXM_IMAGEFREE (WM_USER+2)
+#define IBXM_LABELENABLE (WM_USER+3)
+
+#endif //_ICONBOX_H_
diff --git a/private/ole2ui32/insobj.cpp b/private/ole2ui32/insobj.cpp
new file mode 100644
index 000000000..6421bad4b
--- /dev/null
+++ b/private/ole2ui32/insobj.cpp
@@ -0,0 +1,1850 @@
+/*
+ * INSOBJ.CPP
+ *
+ * Implements the OleUIInsertObject function which invokes the complete
+ * Insert Object dialog. Makes use of the OleChangeIcon function in
+ * ICON.CPP.
+ *
+ * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include <commdlg.h>
+#include <memory.h>
+#include <dos.h>
+#include <stdlib.h>
+#include "utility.h"
+#include "resimage.h"
+#include "iconbox.h"
+
+OLEDBGDATA
+
+// Internally used structure
+typedef struct tagINSERTOBJECT
+{
+ LPOLEUIINSERTOBJECT lpOIO; // Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ /*
+ * What we store extra in this structure besides the original caller's
+ * pointer are those fields that we need to modify during the life of
+ * the dialog but that we don't want to change in the original structure
+ * until the user presses OK.
+ */
+ DWORD dwFlags;
+ CLSID clsid;
+ TCHAR szFile[MAX_PATH];
+ BOOL fFileSelected; // Enables Display As Icon for links
+ BOOL fAsIconNew;
+ BOOL fAsIconFile;
+ BOOL fFileDirty;
+ BOOL fFileValid;
+ UINT nErrCode;
+ HGLOBAL hMetaPictFile;
+ UINT nBrowseHelpID; // Help ID callback for Browse dlg
+ BOOL bObjectListFilled;
+ BOOL bControlListFilled;
+ BOOL bControlListActive;
+
+} INSERTOBJECT, *PINSERTOBJECT, FAR *LPINSERTOBJECT;
+
+// Internal function prototypes
+// INSOBJ.CPP
+
+BOOL CALLBACK InsertObjectDialogProc(HWND, UINT, WPARAM, LPARAM);
+BOOL FInsertObjectInit(HWND, WPARAM, LPARAM);
+UINT UFillClassList(HWND, UINT, LPCLSID, BOOL, BOOL);
+UINT URefillClassList(HWND, LPINSERTOBJECT);
+BOOL FToggleObjectSource(HWND, LPINSERTOBJECT, DWORD);
+void UpdateClassType(HWND, LPINSERTOBJECT, BOOL);
+void SetInsertObjectResults(HWND, LPINSERTOBJECT);
+BOOL FValidateInsertFile(HWND, BOOL, UINT FAR*);
+void InsertObjectCleanup(HWND);
+static void UpdateClassIcon(HWND hDlg, LPINSERTOBJECT lpIO, HWND hList);
+BOOL CALLBACK HookDlgProc(HWND, UINT, WPARAM, LPARAM);
+
+#define IS_FILENAME_DELIM(c) ( (c) == '\\' || (c) == '/' || (c) == ':')
+
+BOOL CALLBACK HookDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+#ifdef CHICO
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ TCHAR szTemp[MAX_PATH];
+ LoadString(_g_hOleStdResInst, IDS_INSERT , szTemp, MAX_PATH);
+ CommDlg_OpenSave_SetControlText(GetParent(hDlg), IDOK, szTemp);
+ return(TRUE);
+ default:
+ break;
+ }
+#endif
+ return(FALSE);
+}
+
+/*
+ * OleUIInsertObject
+ *
+ * Purpose:
+ * Invokes the standard OLE Insert Object dialog box allowing the
+ * user to select an object source and classname as well as the option
+ * to display the object as itself or as an icon.
+ *
+ * Parameters:
+ * lpIO LPOLEUIINSERTOBJECT pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * UINT OLEUI_SUCCESS or OLEUI_OK if all is well, otherwise
+ * an error value.
+ */
+
+STDAPI_(UINT) OleUIInsertObject(LPOLEUIINSERTOBJECT lpIO)
+{
+ HGLOBAL hMemDlg = NULL;
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpIO, sizeof(OLEUIINSERTOBJECT),
+ &hMemDlg);
+
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+ //Now we can do Insert Object specific validation.
+
+ if (NULL != lpIO->lpszFile &&
+ (lpIO->cchFile <= 0 || lpIO->cchFile > MAX_PATH))
+ {
+ uRet = OLEUI_IOERR_CCHFILEINVALID;
+ }
+
+ // NULL is NOT valid for lpszFile
+ if (lpIO->lpszFile == NULL)
+ {
+ uRet = OLEUI_IOERR_LPSZFILEINVALID;
+ }
+ else
+ {
+ if (IsBadWritePtr(lpIO->lpszFile, lpIO->cchFile*sizeof(TCHAR)))
+ uRet = OLEUI_IOERR_LPSZFILEINVALID;
+ }
+
+ if (0 != lpIO->cClsidExclude &&
+ IsBadReadPtr(lpIO->lpClsidExclude, lpIO->cClsidExclude * sizeof(CLSID)))
+ {
+ uRet = OLEUI_IOERR_LPCLSIDEXCLUDEINVALID;
+ }
+
+ //If we have flags to create any object, validate necessary data.
+ if (lpIO->dwFlags & (IOF_CREATENEWOBJECT | IOF_CREATEFILEOBJECT | IOF_CREATELINKOBJECT))
+ {
+ if (NULL != lpIO->lpFormatEtc
+ && IsBadReadPtr(lpIO->lpFormatEtc, sizeof(FORMATETC)))
+ uRet = OLEUI_IOERR_LPFORMATETCINVALID;
+
+ if (NULL != lpIO->ppvObj && IsBadWritePtr(lpIO->ppvObj, sizeof(LPVOID)))
+ uRet = OLEUI_IOERR_PPVOBJINVALID;
+
+ if (NULL != lpIO->lpIOleClientSite
+ && IsBadReadPtr(*(VOID**)&lpIO->lpIOleClientSite, sizeof(DWORD)))
+ uRet = OLEUI_IOERR_LPIOLECLIENTSITEINVALID;
+
+ if (NULL != lpIO->lpIStorage
+ && IsBadReadPtr(*(VOID**)&lpIO->lpIStorage, sizeof(DWORD)))
+ uRet = OLEUI_IOERR_LPISTORAGEINVALID;
+ }
+
+ if (OLEUI_ERR_STANDARDMIN <= uRet)
+ {
+ return uRet;
+ }
+
+ //Now that we've validated everything, we can invoke the dialog.
+ uRet = UStandardInvocation(InsertObjectDialogProc, (LPOLEUISTANDARD)lpIO,
+ hMemDlg, MAKEINTRESOURCE(IDD_INSERTOBJECT));
+
+ //Stop here if we cancelled or had an error.
+ if (OLEUI_SUCCESS !=uRet && OLEUI_OK!=uRet)
+ return uRet;
+
+ /*
+ * If any of the flags specify that we're to create objects on return
+ * from this dialog, then do so. If we encounter an error in this
+ * processing, we return OLEUI_IOERR_SCODEHASERROR. Since the
+ * three select flags are mutually exclusive, we don't have to
+ * if...else here, just if each case (keeps things cleaner that way).
+ */
+
+ lpIO->sc = S_OK;
+
+ // Check if Create New was selected and we have IOF_CREATENEWOBJECT
+ if ((lpIO->dwFlags & (IOF_SELECTCREATENEW|IOF_SELECTCREATECONTROL)) &&
+ (lpIO->dwFlags & IOF_CREATENEWOBJECT))
+ {
+ HRESULT hrErr = OleCreate(lpIO->clsid, lpIO->iid, lpIO->oleRender,
+ lpIO->lpFormatEtc, lpIO->lpIOleClientSite, lpIO->lpIStorage,
+ lpIO->ppvObj);
+ lpIO->sc = GetScode(hrErr);
+ }
+
+ // Try Create From File
+ if ((lpIO->dwFlags & IOF_SELECTCREATEFROMFILE))
+ {
+ if (!(lpIO->dwFlags & IOF_CHECKLINK) && (lpIO->dwFlags & IOF_CREATEFILEOBJECT))
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszFile[MAX_PATH];
+ ATOW(wszFile, lpIO->lpszFile, MAX_PATH);
+ HRESULT hrErr=OleCreateFromFile(CLSID_NULL, wszFile, lpIO->iid,
+ lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite,
+ lpIO->lpIStorage, lpIO->ppvObj);
+#else
+ HRESULT hrErr=OleCreateFromFile(CLSID_NULL, lpIO->lpszFile, lpIO->iid,
+ lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite,
+ lpIO->lpIStorage, lpIO->ppvObj);
+#endif
+ lpIO->sc = GetScode(hrErr);
+ }
+
+ if ((lpIO->dwFlags & IOF_CHECKLINK) && (lpIO->dwFlags & IOF_CREATELINKOBJECT))
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszFile[MAX_PATH];
+ ATOW(wszFile, lpIO->lpszFile, MAX_PATH);
+ HRESULT hrErr=OleCreateLinkToFile(wszFile, lpIO->iid,
+ lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite,
+ lpIO->lpIStorage, lpIO->ppvObj);
+#else
+ HRESULT hrErr=OleCreateLinkToFile(lpIO->lpszFile, lpIO->iid,
+ lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite,
+ lpIO->lpIStorage, lpIO->ppvObj);
+#endif
+ lpIO->sc = GetScode(hrErr);
+ }
+ }
+
+ //If we tried but failed a create option, then return the appropriate error
+ if (S_OK != lpIO->sc)
+ uRet = OLEUI_IOERR_SCODEHASERROR;
+
+ return uRet;
+}
+
+/*
+ * InsertObjectDialogProc
+ *
+ * Purpose:
+ * Implements the OLE Insert Object dialog as invoked through the
+ * OleUIInsertObject function.
+ */
+
+BOOL CALLBACK InsertObjectDialogProc(HWND hDlg, UINT iMsg,
+ WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uRet = 0;
+ LPINSERTOBJECT lpIO = (LPINSERTOBJECT)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
+
+ // If the hook processed the message, we're done.
+ if (0 != uRet)
+ return (BOOL)uRet;
+
+ // Process help message from Change Icon
+ if (iMsg == uMsgHelp)
+ {
+ PostMessage(lpIO->lpOIO->hWndOwner, uMsgHelp, wParam, lParam);
+ return FALSE;
+ }
+
+ // Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ switch (iMsg)
+ {
+ case WM_DESTROY:
+ if (lpIO)
+ {
+ InsertObjectCleanup(hDlg);
+ StandardCleanup(lpIO, hDlg);
+ }
+ break;
+ case WM_INITDIALOG:
+ return FInsertObjectInit(hDlg, wParam, lParam);
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_IO_CREATENEW:
+ if (1 == IsDlgButtonChecked(hDlg, IDC_IO_CREATENEW))
+ {
+ FToggleObjectSource(hDlg, lpIO, IOF_SELECTCREATENEW);
+ }
+ break;
+
+ case IDC_IO_CREATEFROMFILE:
+ if (1 == IsDlgButtonChecked(hDlg, IDC_IO_CREATEFROMFILE))
+ {
+ FToggleObjectSource(hDlg, lpIO, IOF_SELECTCREATEFROMFILE);
+ }
+ break;
+
+ case IDC_IO_INSERTCONTROL:
+ if (1 == IsDlgButtonChecked(hDlg, IDC_IO_INSERTCONTROL))
+ {
+ FToggleObjectSource(hDlg, lpIO, IOF_SELECTCREATECONTROL);
+ }
+ break;
+
+ case IDC_IO_LINKFILE:
+ {
+ BOOL fCheck=IsDlgButtonChecked(hDlg, wID);
+ if (fCheck)
+ lpIO->dwFlags |=IOF_CHECKLINK;
+ else
+ lpIO->dwFlags &=~IOF_CHECKLINK;
+
+ // Results change here, so be sure to update it.
+ SetInsertObjectResults(hDlg, lpIO);
+ UpdateClassIcon(hDlg, lpIO, NULL);
+ }
+ break;
+
+ case IDC_IO_OBJECTTYPELIST:
+ switch (wCode)
+ {
+ case LBN_SELCHANGE:
+ UpdateClassIcon(hDlg, lpIO, hWndMsg);
+ SetInsertObjectResults(hDlg, lpIO);
+ break;
+
+ case LBN_DBLCLK:
+ SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
+ break;
+ }
+ break;
+
+ case IDC_IO_FILEDISPLAY:
+ // If there are characters, enable OK and Display As Icon
+ if (EN_CHANGE == wCode)
+ {
+ lpIO->fFileDirty = TRUE;
+ lpIO->fFileValid = FALSE;
+ lpIO->fFileSelected = (0L != SendMessage(hWndMsg, EM_LINELENGTH, 0, 0L));
+ StandardEnableDlgItem(hDlg, IDC_IO_LINKFILE, lpIO->fFileSelected);
+ StandardEnableDlgItem(hDlg, IDC_IO_DISPLAYASICON, lpIO->fFileSelected);
+ StandardEnableDlgItem(hDlg, IDC_IO_CHANGEICON, lpIO->fFileSelected);
+ StandardEnableDlgItem(hDlg, IDOK, lpIO->fFileSelected);
+ }
+ if (EN_KILLFOCUS == wCode && NULL != lpIO)
+ {
+ if (FValidateInsertFile(hDlg, FALSE, &lpIO->nErrCode))
+ {
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = TRUE;
+ UpdateClassIcon(hDlg, lpIO, NULL);
+ UpdateClassType(hDlg, lpIO, TRUE);
+ }
+ else
+ {
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = FALSE;
+ UpdateClassType(hDlg, lpIO, FALSE);
+ }
+ }
+ break;
+
+ case IDC_IO_DISPLAYASICON:
+ {
+ BOOL fCheck = IsDlgButtonChecked(hDlg, wID);
+ StandardEnableDlgItem(hDlg, IDC_IO_CHANGEICON, fCheck);
+ if (fCheck)
+ lpIO->dwFlags |=IOF_CHECKDISPLAYASICON;
+ else
+ lpIO->dwFlags &=~IOF_CHECKDISPLAYASICON;
+
+ // Update the internal flag based on this checking
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ lpIO->fAsIconNew = fCheck;
+ else
+ lpIO->fAsIconFile = fCheck;
+
+ // Re-read the class icon on Display checked
+ if (fCheck)
+ {
+ if (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE)
+ {
+ if (FValidateInsertFile(hDlg, TRUE,&lpIO->nErrCode))
+ {
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = TRUE;
+ UpdateClassIcon(hDlg, lpIO,
+ GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST));
+ UpdateClassType(hDlg, lpIO, TRUE);
+ }
+ else
+ {
+ lpIO->fAsIconFile= FALSE;
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = FALSE;
+ SendDlgItemMessage(hDlg, IDC_IO_ICONDISPLAY,
+ IBXM_IMAGESET, 0, 0L);
+ UpdateClassType(hDlg, lpIO, FALSE);
+
+ lpIO->dwFlags &=~IOF_CHECKDISPLAYASICON;
+ CheckDlgButton(hDlg, IDC_IO_DISPLAYASICON, 0);
+
+ HWND hWndEC = GetDlgItem(hDlg, IDC_IO_FILEDISPLAY);
+ SetFocus(hWndEC);
+ SendMessage(hWndEC, EM_SETSEL, 0, -1);
+ return TRUE;
+ }
+ }
+ else
+ UpdateClassIcon(hDlg, lpIO,
+ GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST));
+ }
+
+ // Results change here, so be sure to update it.
+ SetInsertObjectResults(hDlg, lpIO);
+
+ /*
+ * Show or hide controls as appropriate. Do the icon
+ * display last because it will take some time to repaint.
+ * If we do it first then the dialog looks too sluggish.
+ */
+ UINT i = (fCheck) ? SW_SHOWNORMAL : SW_HIDE;
+ StandardShowDlgItem(hDlg, IDC_IO_CHANGEICON, i);
+ StandardShowDlgItem(hDlg, IDC_IO_ICONDISPLAY, i);
+ }
+ break;
+
+ case IDC_IO_CHANGEICON:
+ {
+ // if we're in SELECTCREATEFROMFILE mode, then we need to Validate
+ // the contents of the edit control first.
+
+ if (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE)
+ {
+ if (lpIO->fFileDirty &&
+ !FValidateInsertFile(hDlg, TRUE, &lpIO->nErrCode))
+ {
+ HWND hWndEC;
+ lpIO->fFileValid = FALSE;
+ hWndEC = GetDlgItem(hDlg, IDC_IO_FILEDISPLAY);
+ SetFocus(hWndEC);
+ SendMessage(hWndEC, EM_SETSEL, 0, -1);
+ return TRUE;
+ }
+ else
+ {
+ lpIO->fFileDirty = FALSE;
+ }
+ }
+
+ // Initialize the structure for the hook.
+ OLEUICHANGEICON ci; memset(&ci, 0, sizeof(ci));
+ ci.cbStruct = sizeof(ci);
+ ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
+ IDC_IO_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ ci.hWndOwner= hDlg;
+ ci.dwFlags = CIF_SELECTCURRENT;
+ if (lpIO->dwFlags & IOF_SHOWHELP)
+ ci.dwFlags |= CIF_SHOWHELP;
+
+ HWND hList = GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST);
+ int iCurSel = (int)SendMessage(hList, LB_GETCURSEL, 0, 0L);
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ {
+ LPTSTR pszString = (LPTSTR)OleStdMalloc(
+ OLEUI_CCHKEYMAX_SIZE + OLEUI_CCHCLSIDSTRING_SIZE);
+
+ SendMessage(hList, LB_GETTEXT, iCurSel, (LONG)pszString);
+
+ LPTSTR pszCLSID = PointerToNthField(pszString, 2, '\t');
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszCLSID[OLEUI_CCHKEYMAX];
+ ATOW(wszCLSID, pszCLSID, OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszCLSID, &ci.clsid);
+#else
+ CLSIDFromString(pszCLSID, &ci.clsid);
+#endif
+ OleStdFree((LPVOID)pszString);
+ }
+ else // IOF_SELECTCREATEFROMFILE
+ {
+ TCHAR szFileName[MAX_PATH];
+ GetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, szFileName, MAX_PATH);
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszFileName[MAX_PATH];
+ ATOW(wszFileName, szFileName, MAX_PATH);
+ if (NOERROR != GetClassFile(wszFileName, &ci.clsid))
+#else
+ if (NOERROR != GetClassFile(szFileName, &ci.clsid))
+#endif
+ {
+ int istrlen = lstrlen(szFileName);
+ LPTSTR lpszExtension = szFileName + istrlen -1;
+
+ while (lpszExtension > szFileName &&
+ *lpszExtension != '.')
+ {
+ lpszExtension = CharPrev(szFileName, lpszExtension);
+ }
+
+ GetAssociatedExecutable(lpszExtension, ci.szIconExe);
+ ci.cchIconExe = lstrlen(ci.szIconExe);
+ ci.dwFlags |= CIF_USEICONEXE;
+ }
+ }
+
+ // Let the hook in to customize Change Icon if desired.
+ uRet = UStandardHook(lpIO, hDlg, uMsgChangeIcon, 0, (LONG)&ci);
+
+ if (0 == uRet)
+ uRet = (UINT)(OLEUI_OK == OleUIChangeIcon(&ci));
+
+ // Update the display and itemdata if necessary.
+ if (0 != uRet)
+ {
+ /*
+ * OleUIChangeIcon will have already freed our
+ * current hMetaPict that we passed in when OK is
+ * pressed in that dialog. So we use 0L as lParam
+ * here so the IconBox doesn't try to free the
+ * metafilepict again.
+ */
+ SendDlgItemMessage(hDlg, IDC_IO_ICONDISPLAY,
+ IBXM_IMAGESET, 0, (LPARAM)ci.hMetaPict);
+
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ SendMessage(hList, LB_SETITEMDATA, iCurSel, (LPARAM)ci.hMetaPict);
+ }
+ }
+ break;
+
+ case IDC_IO_FILE:
+ {
+ /*
+ * To allow the hook to customize the browse dialog, we
+ * send OLEUI_MSG_BROWSE. If the hook returns FALSE
+ * we use the default, otherwise we trust that it retrieved
+ * a filename for us. This mechanism prevents hooks from
+ * trapping IDC_IO_BROWSE to customize the dialog and from
+ * trying to figure out what we do after we have the name.
+ */
+ TCHAR szTemp[MAX_PATH];
+ int nChars = GetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, szTemp, MAX_PATH);
+
+ TCHAR szInitialDir[MAX_PATH];
+ BOOL fUseInitialDir = FALSE;
+ if (FValidateInsertFile(hDlg, FALSE, &lpIO->nErrCode))
+ {
+ StandardGetFileTitle(szTemp, lpIO->szFile, MAX_PATH);
+ int istrlen = lstrlen(lpIO->szFile);
+
+ lstrcpyn(szInitialDir, szTemp, nChars - istrlen);
+ fUseInitialDir = TRUE;
+ }
+ else // file name isn't valid...lop off end of szTemp to get a
+ // valid directory
+ {
+ TCHAR szBuffer[MAX_PATH];
+ lstrcpyn(szBuffer, szTemp, sizeof(szBuffer)/sizeof(TCHAR));
+
+ if ('\\' == szBuffer[nChars-1])
+ szBuffer[nChars-1] = '\0';
+
+ DWORD Attribs = GetFileAttributes(szBuffer);
+ if (Attribs != 0xffffffff &&
+ (Attribs & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ lstrcpy(szInitialDir, szBuffer);
+ fUseInitialDir = TRUE;
+ }
+ *lpIO->szFile = '\0';
+ }
+
+ uRet = UStandardHook(lpIO, hDlg, uMsgBrowse,
+ MAX_PATH, (LPARAM)(LPSTR)lpIO->szFile);
+
+ if (0 == uRet)
+ {
+ DWORD dwOfnFlags = OFN_FILEMUSTEXIST | OFN_ENABLEHOOK;
+ if (lpIO->lpOIO->dwFlags & IOF_SHOWHELP)
+ dwOfnFlags |= OFN_SHOWHELP;
+
+ uRet = (UINT)Browse(hDlg, lpIO->szFile,
+ fUseInitialDir ? szInitialDir : NULL, MAX_PATH,
+ IDS_FILTERS, dwOfnFlags, ID_BROWSE_INSERTFILE, (LPOFNHOOKPROC)HookDlgProc);
+ }
+
+ // Only update if the file changed.
+ if (0 != uRet && 0 != lstrcmpi(szTemp, lpIO->szFile))
+ {
+ SetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, lpIO->szFile);
+ lpIO->fFileSelected=TRUE;
+
+ if (FValidateInsertFile(hDlg, TRUE, &lpIO->nErrCode))
+ {
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = TRUE;
+ UpdateClassIcon(hDlg, lpIO, NULL);
+ UpdateClassType(hDlg, lpIO, TRUE);
+ // auto set OK to be default button if valid file
+ SendMessage(hDlg, DM_SETDEFID,
+ (WPARAM)GetDlgItem(hDlg, IDOK), 0L);
+ SetFocus(GetDlgItem(hDlg, IDOK));
+ }
+ else // filename is invalid - set focus back to ec
+ {
+ HWND hWnd;
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = FALSE;
+ hWnd = GetDlgItem(hDlg, IDC_IO_FILEDISPLAY);
+ SetFocus(hWnd);
+ SendMessage(hWnd, EM_SETSEL, 0, -1);
+ }
+
+ // Once we have a file, Display As Icon is always enabled
+ StandardEnableDlgItem(hDlg, IDC_IO_DISPLAYASICON, TRUE);
+
+ // As well as OK
+ StandardEnableDlgItem(hDlg, IDOK, TRUE);
+ }
+ }
+ break;
+
+ case IDC_IO_ADDCONTROL:
+ {
+ TCHAR szFileName[MAX_PATH];
+ szFileName[0] = 0;
+
+ // allow hook to customize
+ uRet = UStandardHook(lpIO, hDlg, uMsgAddControl,
+ MAX_PATH, (LPARAM)szFileName);
+
+ if (0 == uRet)
+ {
+ DWORD dwOfnFlags = OFN_FILEMUSTEXIST | OFN_ENABLEHOOK;
+ if (lpIO->lpOIO->dwFlags & IOF_SHOWHELP)
+ dwOfnFlags |= OFN_SHOWHELP;
+ uRet = (UINT)Browse(hDlg, szFileName, NULL, MAX_PATH,
+ IDS_OCX_FILTERS, dwOfnFlags, ID_BROWSE_ADDCONTROL , (LPOFNHOOKPROC)HookDlgProc);
+ }
+
+ if (0 != uRet)
+ {
+ // try to register the control DLL
+ HINSTANCE hInst = LoadLibrary(szFileName);
+ if (hInst == NULL)
+ {
+ PopupMessage(hDlg, IDS_ADDCONTROL, IDS_CANNOTLOADOCX,
+ MB_OK | MB_ICONEXCLAMATION);
+ break;
+ }
+
+ HRESULT (FAR STDAPICALLTYPE* lpfn)(void);
+ (FARPROC&)lpfn = GetProcAddress(hInst, "DllRegisterServer");
+ if (lpfn == NULL)
+ {
+ PopupMessage(hDlg, IDS_ADDCONTROL, IDS_NODLLREGISTERSERVER,
+ MB_OK | MB_ICONEXCLAMATION);
+ FreeLibrary(hInst);
+ break;
+ }
+
+ if (FAILED((*lpfn)()))
+ {
+ PopupMessage(hDlg, IDS_ADDCONTROL, IDS_DLLREGISTERFAILED,
+ MB_OK | MB_ICONEXCLAMATION);
+ FreeLibrary(hInst);
+ break;
+ }
+
+ // cleanup the DLL from memory
+ FreeLibrary(hInst);
+
+ // registered successfully -- refill the list box
+ lpIO->bControlListFilled = FALSE;
+ lpIO->bObjectListFilled = FALSE;
+ URefillClassList(hDlg, lpIO);
+ }
+ }
+ break;
+
+ case IDOK:
+ {
+ if ((HWND)lParam != GetFocus())
+ SetFocus((HWND)lParam);
+
+ // If the file name is clean (already validated), or
+ // if Create New is selected, then we can skip this part.
+
+ if ((lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) &&
+ lpIO->fFileDirty)
+ {
+ if (FValidateInsertFile(hDlg, TRUE, &lpIO->nErrCode))
+ {
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = TRUE;
+ UpdateClassIcon(hDlg, lpIO, NULL);
+ UpdateClassType(hDlg, lpIO, TRUE);
+ }
+ else // filename is invalid - set focus back to ec
+ {
+ HWND hWnd;
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = FALSE;
+ hWnd = GetDlgItem(hDlg, IDC_IO_FILEDISPLAY);
+ SetFocus(hWnd);
+ SendMessage(hWnd, EM_SETSEL, 0, -1);
+ UpdateClassType(hDlg, lpIO, FALSE);
+ }
+ return TRUE; // eat this message
+ }
+ else if ((lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) &&
+ !lpIO->fFileValid)
+ {
+ // filename is invalid - set focus back to ec
+ HWND hWnd;
+ TCHAR szFile[MAX_PATH];
+
+ if (0 != GetDlgItemText(hDlg, IDC_IO_FILEDISPLAY,
+ szFile, MAX_PATH))
+ {
+ OpenFileError(hDlg, lpIO->nErrCode, szFile);
+ }
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = FALSE;
+ hWnd = GetDlgItem(hDlg, IDC_IO_FILEDISPLAY);
+ SetFocus(hWnd);
+ SendMessage(hWnd, EM_SETSEL, 0, -1);
+ UpdateClassType(hDlg, lpIO, FALSE);
+ return TRUE; // eat this message
+ }
+
+ // Copy the necessary information back to the original struct
+ LPOLEUIINSERTOBJECT lpOIO = lpIO->lpOIO;
+ lpOIO->dwFlags = lpIO->dwFlags;
+
+ if (lpIO->dwFlags & (IOF_SELECTCREATENEW|IOF_SELECTCREATECONTROL))
+ {
+ HWND hListBox = GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST);
+ UINT iCurSel = (UINT)SendMessage(hListBox, LB_GETCURSEL, 0, 0);
+
+ if (lpIO->dwFlags & IOF_CHECKDISPLAYASICON)
+ {
+ lpOIO->hMetaPict=(HGLOBAL)SendMessage(hListBox,
+ LB_GETITEMDATA, iCurSel, 0L);
+
+ /*
+ * Set the item data to 0 here so that the cleanup
+ * code doesn't delete the metafile.
+ */
+ SendMessage(hListBox, LB_SETITEMDATA, iCurSel, 0L);
+ }
+ else
+ lpOIO->hMetaPict = (HGLOBAL)NULL;
+
+ TCHAR szBuffer[OLEUI_CCHKEYMAX+OLEUI_CCHCLSIDSTRING];
+ SendMessage(hListBox, LB_GETTEXT, iCurSel, (LPARAM)szBuffer);
+
+ LPTSTR lpszCLSID = PointerToNthField(szBuffer, 2, '\t');
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszCLSID[OLEUI_CCHKEYMAX];
+ ATOW(wszCLSID, lpszCLSID, OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszCLSID, &lpOIO->clsid);
+#else
+ CLSIDFromString(lpszCLSID, &lpOIO->clsid);
+#endif
+ }
+ else // IOF_SELECTCREATEFROMFILE
+ {
+ if (lpIO->dwFlags & IOF_CHECKDISPLAYASICON)
+ {
+ // get metafile here
+ lpOIO->hMetaPict = (HGLOBAL)SendDlgItemMessage(
+ hDlg, IDC_IO_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ }
+ else
+ lpOIO->hMetaPict = (HGLOBAL)NULL;
+ }
+
+ GetDlgItemText(hDlg, IDC_IO_FILEDISPLAY,
+ lpIO->szFile, lpOIO->cchFile);
+ lstrcpyn(lpOIO->lpszFile, lpIO->szFile, lpOIO->cchFile);
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ }
+ break;
+
+ case IDCANCEL:
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
+ break;
+
+ case IDC_OLEUIHELP:
+ PostMessage(lpIO->lpOIO->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_INSERTOBJECT, 0));
+ break;
+ }
+ break;
+
+ default:
+ if (lpIO && iMsg == lpIO->nBrowseHelpID)
+ {
+ PostMessage(lpIO->lpOIO->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_INSERTFILEBROWSE, 0));
+ }
+ if (iMsg == uMsgBrowseOFN &&
+ lpIO && lpIO->lpOIO && lpIO->lpOIO->hWndOwner)
+ {
+ SendMessage(lpIO->lpOIO->hWndOwner, uMsgBrowseOFN, wParam, lParam);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: CheckButton
+//
+// Synopsis: Handles checking the radio buttons
+//
+// Arguments: [hDlg] - dialog handle
+// [iID] - ID of the button to check
+//
+// Returns: nothing
+//
+// History: 1-19-95 stevebl Created
+//
+// Notes: Used in place of CheckRadioButtons to avoid a GP fault under
+// win32s that arises from IDC_IO_CREATENEW, IDC_IO_CREATEFROMFILE
+// and IDC_IO_INSERTCONTROL not being contiguous.
+//
+//----------------------------------------------------------------------------
+
+void CheckButton(HWND hDlg, int iID)
+{
+ CheckDlgButton(hDlg, IDC_IO_CREATENEW, iID == IDC_IO_CREATENEW ? 1 : 0);
+ CheckDlgButton(hDlg, IDC_IO_CREATEFROMFILE, iID == IDC_IO_CREATEFROMFILE ? 1 : 0);
+ CheckDlgButton(hDlg, IDC_IO_INSERTCONTROL, iID == IDC_IO_INSERTCONTROL ? 1 : 0);
+}
+
+
+/*
+ * FInsertObjectInit
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the Insert Object dialog box.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+BOOL FInsertObjectInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ HFONT hFont;
+ LPINSERTOBJECT lpIO = (LPINSERTOBJECT)LpvStandardInit(hDlg, sizeof(INSERTOBJECT), &hFont);
+
+ // PvStandardInit send a termination to us already.
+ if (NULL == lpIO)
+ return FALSE;
+
+ LPOLEUIINSERTOBJECT lpOIO = (LPOLEUIINSERTOBJECT)lParam;
+
+ // Save the original pointer and copy necessary information.
+ lpIO->lpOIO = lpOIO;
+ lpIO->nIDD = IDD_INSERTOBJECT;
+ lpIO->dwFlags = lpOIO->dwFlags;
+ lpIO->clsid = lpOIO->clsid;
+
+ if ((lpOIO->lpszFile) && ('\0' != *lpOIO->lpszFile))
+ lstrcpyn(lpIO->szFile, lpOIO->lpszFile, MAX_PATH);
+ else
+ *(lpIO->szFile) = '\0';
+
+ lpIO->hMetaPictFile = (HGLOBAL)NULL;
+
+ // If we got a font, send it to the necessary controls.
+ if (NULL != hFont)
+ {
+ SendDlgItemMessage(hDlg, IDC_IO_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L);
+ SendDlgItemMessage(hDlg, IDC_IO_FILETYPE, WM_SETFONT, (WPARAM)hFont, 0L);
+ }
+
+ // Initilize the file name display to cwd if we don't have any name.
+ if ('\0' == *(lpIO->szFile))
+ {
+ TCHAR szCurDir[MAX_PATH];
+ int nLen;
+ GetCurrentDirectory(MAX_PATH, szCurDir);
+ nLen = lstrlen(szCurDir);
+ if (nLen != 0 && szCurDir[nLen-1] != '\\')
+ lstrcat(szCurDir, _T("\\"));
+ SetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, szCurDir);
+ lpIO->fFileDirty = TRUE; // cwd is not a valid filename
+ }
+ else
+ {
+ SetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, lpIO->szFile);
+ if (FValidateInsertFile(hDlg, FALSE, &lpIO->nErrCode))
+ {
+ lpIO->fFileDirty = FALSE;
+ lpIO->fFileValid = TRUE;
+ }
+ else
+ {
+ lpIO->fFileDirty = TRUE;
+ lpIO->fFileValid = FALSE;
+ }
+ }
+
+ // Initialize radio button and related controls
+ if (lpIO->dwFlags & IOF_CHECKDISPLAYASICON)
+ {
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ lpIO->fAsIconNew = TRUE;
+ else
+ lpIO->fAsIconFile = TRUE;
+ }
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ CheckButton(hDlg, IDC_IO_CREATENEW);
+ if (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE)
+ CheckButton(hDlg, IDC_IO_CREATEFROMFILE);
+ if (lpIO->dwFlags & IOF_SELECTCREATECONTROL)
+ CheckButton(hDlg, IDC_IO_INSERTCONTROL);
+ CheckDlgButton(hDlg, IDC_IO_LINKFILE, (BOOL)(0L != (lpIO->dwFlags & IOF_CHECKLINK)));
+
+ lpIO->dwFlags &=
+ ~(IOF_SELECTCREATENEW|IOF_SELECTCREATEFROMFILE|IOF_SELECTCREATECONTROL);
+ FToggleObjectSource(hDlg, lpIO, lpOIO->dwFlags &
+ (IOF_SELECTCREATENEW|IOF_SELECTCREATEFROMFILE|IOF_SELECTCREATECONTROL));
+
+ // Show or hide the help button
+ if (!(lpIO->dwFlags & IOF_SHOWHELP))
+ StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
+
+ // Show or hide the Change icon button
+ if (lpIO->dwFlags & IOF_HIDECHANGEICON)
+ DestroyWindow(GetDlgItem(hDlg, IDC_IO_CHANGEICON));
+
+ // Hide Insert Control button if necessary
+ if (!(lpIO->dwFlags & IOF_SHOWINSERTCONTROL))
+ StandardShowDlgItem(hDlg, IDC_IO_INSERTCONTROL, SW_HIDE);
+
+ // Initialize the result display
+ UpdateClassIcon(hDlg, lpIO, GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST));
+ SetInsertObjectResults(hDlg, lpIO);
+
+ // Change the caption
+ if (NULL!=lpOIO->lpszCaption)
+ SetWindowText(hDlg, lpOIO->lpszCaption);
+
+ // Hide all DisplayAsIcon related controls if it should be disabled
+ if (lpIO->dwFlags & IOF_DISABLEDISPLAYASICON)
+ {
+ StandardShowDlgItem(hDlg, IDC_IO_DISPLAYASICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_IO_CHANGEICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_IO_ICONDISPLAY, SW_HIDE);
+ }
+
+ lpIO->nBrowseHelpID = RegisterWindowMessage(HELPMSGSTRING);
+
+ // All Done: call the hook with lCustData
+ UStandardHook(lpIO, hDlg, WM_INITDIALOG, wParam, lpOIO->lCustData);
+
+ /*
+ * We either set focus to the listbox or the edit control. In either
+ * case we don't want Windows to do any SetFocus, so we return FALSE.
+ */
+ return FALSE;
+}
+
+/*
+ * URefillClassList
+ *
+ * Purpose:
+ * Fills the class list box with names as appropriate for the current
+ * flags. This function is called when the user changes the flags
+ * via the "exclusion" radio buttons.
+ *
+ * Note that this function removes any prior contents of the listbox.
+ *
+ * Parameters:
+ * hDlg HWND to the dialog box.
+ * lpIO pointer to LPINSERTOBJECT structure
+ *
+ * Return Value:
+ * UINT Number of strings added to the listbox, -1 on failure.
+ */
+UINT URefillClassList(HWND hDlg, LPINSERTOBJECT lpIO)
+{
+ OleDbgAssert(lpIO->dwFlags & (IOF_SELECTCREATECONTROL|IOF_SELECTCREATENEW));
+
+ // always the same dialog ID because they are swapped
+ HWND hList = GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST);
+
+ // determine if already filled
+ BOOL bFilled;
+ if (lpIO->dwFlags & IOF_SELECTCREATECONTROL)
+ bFilled = lpIO->bControlListFilled;
+ else
+ bFilled = lpIO->bObjectListFilled;
+
+ if (!bFilled)
+ {
+ // fill the list
+ LPOLEUIINSERTOBJECT lpOIO = lpIO->lpOIO;
+ UINT uResult = UFillClassList(hList, lpOIO->cClsidExclude, lpOIO->lpClsidExclude,
+ (BOOL)(lpIO->dwFlags & IOF_VERIFYSERVERSEXIST),
+ (lpIO->dwFlags & IOF_SELECTCREATECONTROL));
+
+ // mark the list as filled
+ if (lpIO->dwFlags & IOF_SELECTCREATECONTROL)
+ lpIO->bControlListFilled = TRUE;
+ else
+ lpIO->bObjectListFilled = TRUE;
+ }
+
+ // return number of items now in the list
+ return SendMessage(hList, LB_GETCOUNT, 0, 0);
+}
+
+
+/*
+ * UFillClassList
+ *
+ * Purpose:
+ * Enumerates available OLE object classes from the registration
+ * database and fills a listbox with those names.
+ *
+ * Note that this function removes any prior contents of the listbox.
+ *
+ * Parameters:
+ * hList HWND to the listbox to fill.
+ * cIDEx UINT number of CLSIDs to exclude in lpIDEx
+ * lpIDEx LPCLSID to CLSIDs to leave out of the listbox.
+ * fVerify BOOL indicating if we are to validate existence of
+ * servers before putting them in the list.
+ *
+ * Return Value:
+ * UINT Number of strings added to the listbox, -1 on failure.
+ */
+
+UINT UFillClassList(HWND hList, UINT cIDEx, LPCLSID lpIDEx, BOOL fVerify,
+ BOOL fExcludeObjects)
+{
+ OleDbgAssert(hList != NULL);
+
+ // Set the tab width in the list to push all the tabs off the side.
+ RECT rc;
+ GetClientRect(hList, &rc);
+ DWORD dw = GetDialogBaseUnits();
+ rc.right =(8*rc.right)/LOWORD(dw); //Convert pixels to 2x dlg units.
+ SendMessage(hList, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&rc.right);
+
+ LPTSTR pszExec = (LPTSTR)OleStdMalloc(OLEUI_CCHKEYMAX_SIZE*4);
+ if (NULL == pszExec)
+ return (UINT)-1;
+
+ LPTSTR pszClass = pszExec+OLEUI_CCHKEYMAX;
+ LPTSTR pszKey = pszClass+OLEUI_CCHKEYMAX;
+
+ // Open up the root key.
+ HKEY hKey;
+ LONG lRet = RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey);
+ if ((LONG)ERROR_SUCCESS!=lRet)
+ {
+ OleStdFree((LPVOID)pszExec);
+ return (UINT)-1;
+ }
+
+ // Clean out the existing strings.
+ SendMessage(hList, LB_RESETCONTENT, 0, 0L);
+ UINT cStrings = 0;
+
+ while (TRUE)
+ {
+ BOOL bHaveCLSID = FALSE;// assume not yet (for handling of OLE1.0 compat case)
+ LPTSTR pszID = pszKey+OLEUI_CCHKEYMAX;
+
+ lRet = RegEnumKey(hKey, cStrings++, pszClass, OLEUI_CCHKEYMAX_SIZE);
+ if ((LONG)ERROR_SUCCESS != lRet)
+ break;
+
+ // Cheat on lstrcat by using lstrcpy after this string, saving time
+ UINT cch = lstrlen(pszClass);
+
+ // Check for \NotInsertable. If this is found then this overrides
+ // all other keys; this class will NOT be added to the InsertObject
+ // list.
+
+ lstrcpy(pszClass+cch, TEXT("\\NotInsertable"));
+ HKEY hKeyTemp = NULL;
+ lRet = RegOpenKey(hKey, pszClass, &hKeyTemp);
+ if (hKeyTemp != NULL)
+ RegCloseKey(hKeyTemp);
+ if ((LONG)ERROR_SUCCESS == lRet)
+ continue; // NotInsertable IS found--skip this class
+
+ // Check for a \protocol\StdFileEditing\server entry.
+ lstrcpy(pszClass+cch, TEXT("\\protocol\\StdFileEditing\\server"));
+ DWORD dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszClass, pszKey, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS == lRet)
+ {
+ // This is not a control -- skip it if excluding non-controls
+ if (fExcludeObjects)
+ continue;
+
+ // Check if the EXE actually exists. By default we don't do this
+ // to bring up the dialog faster. If an application wants to be
+ // stringent, they can provide IOF_VERIFYSERVERSEXIST.
+ if (fVerify && !DoesFileExist(pszKey, OLEUI_CCHKEYMAX))
+ continue;
+
+ // get readable class name
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ *(pszClass+cch) = 0; // set back to rootkey
+ lRet=RegQueryValue(hKey, pszClass, pszKey, (LONG*)&dw);
+
+ // attempt to get clsid directly from registry
+ lstrcpy(pszClass+cch, TEXT("\\CLSID"));
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszClass, pszID, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS == lRet)
+ bHaveCLSID = TRUE;
+ *(pszClass+cch) = 0; // set back to rootkey
+ }
+ else
+ {
+ // No \protocol\StdFileEditing\server entry.
+
+ // Check for CLSID
+ lstrcpy(pszClass+cch, TEXT("\\CLSID"));
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszClass, pszID, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS != lRet)
+ continue; // CLSID subkey not found
+
+ // But it does have a CLSID entry so it's a control.
+
+ // CLSID\ is 6, dw contains pszID length.
+ cch = 6 + ((UINT)dw/sizeof(TCHAR)) - 1;
+ lstrcpy(pszExec, TEXT("CLSID\\"));
+ lstrcpy(pszExec+6, pszID);
+
+ // Check for CLISD\clsid\Control
+ // (needed for inclusion in the Insert Control list box)
+
+ // fExcludeObjects is TRUE for the Insert Control box.
+ // It's FALSE for the Insert Object box.
+
+ lstrcpy(pszExec+cch, TEXT("\\Control"));
+ hKeyTemp = NULL;
+ lRet = RegOpenKey(hKey, pszExec, &hKeyTemp);
+ if (hKeyTemp != NULL)
+ RegCloseKey(hKeyTemp);
+ if ((LONG)ERROR_SUCCESS != lRet && fExcludeObjects)
+ continue;
+
+ // Check for CLSID\clsid\Insertable
+ // (needed for inclusion in the Insert Object list box)
+
+ lstrcpy(pszExec+cch, TEXT("\\Insertable"));
+ hKeyTemp = NULL;
+ lRet = RegOpenKey(hKey, pszExec, &hKeyTemp);
+ if (hKeyTemp != NULL)
+ RegCloseKey(hKeyTemp);
+ if ((LONG)ERROR_SUCCESS != lRet && !fExcludeObjects)
+ continue;
+
+ // Check \LocalServer32, LocalServer, and \InprocServer
+
+ // Try LocalServer32
+ lstrcpy(pszExec+cch, TEXT("\\LocalServer32"));
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszExec, pszKey, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS != lRet)
+ {
+ // Try LocalServer
+ lstrcpy(pszExec+cch, TEXT("\\LocalServer"));
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszExec, pszKey, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS != lRet)
+ {
+ // Try InprocServer32
+ lstrcpy(pszExec+cch, TEXT("\\InProcServer32"));
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszExec, pszKey, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS != lRet)
+ {
+ // Try InprocServer
+ lstrcpy(pszExec+cch, TEXT("\\InProcServer"));
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszExec, pszKey, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS != lRet)
+ continue;
+ }
+ }
+ }
+
+ if (fVerify && !DoesFileExist(pszKey, OLEUI_CCHKEYMAX))
+ continue;
+
+ *(pszExec+cch) = 0; //Remove \\*Server
+ dw = OLEUI_CCHKEYMAX_SIZE;
+ lRet = RegQueryValue(hKey, pszExec, pszKey, (LONG*)&dw);
+ if ((LONG)ERROR_SUCCESS!=lRet)
+ continue;
+
+ bHaveCLSID = TRUE;
+ }
+
+ // get CLSID to add to listbox.
+ CLSID clsid;
+ if (!bHaveCLSID)
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszClass[OLEUI_CCHKEYMAX];
+ ATOW(wszClass, pszClass, OLEUI_CCHKEYMAX);
+ if (FAILED(CLSIDFromProgID(wszClass, &clsid)))
+ continue;
+ LPOLESTR wszID;
+ if (FAILED(StringFromCLSID(clsid, &wszID)))
+ continue;
+ UINT uLen = WTOALEN(wszID);
+ pszID = (LPTSTR) OleStdMalloc(uLen);
+ WTOA(pszID, wszID, uLen);
+#else
+ if (FAILED(CLSIDFromProgID(pszClass, &clsid)))
+ continue;
+ if (FAILED(StringFromCLSID(clsid, &pszID)))
+ continue;
+#endif
+ }
+ else
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszID[OLEUI_CCHKEYMAX];
+ ATOW(wszID, pszID, OLEUI_CCHKEYMAX);
+ if (FAILED(CLSIDFromString(wszID, &clsid)))
+ continue;
+#else
+ if (FAILED(CLSIDFromString(pszID, &clsid)))
+ continue;
+#endif
+ }
+
+ // Note: 'continue' after this point would leak memory so we don't use them!
+
+ // check if this CLSID is in the exclusion list.
+ BOOL fExclude = FALSE;
+ for (UINT i=0; i < cIDEx; i++)
+ {
+ if (IsEqualCLSID(clsid, lpIDEx[i]))
+ {
+ fExclude=TRUE;
+ break;
+ }
+ }
+
+ // don't add objects without names
+ if (lstrlen(pszKey) > 0 && !fExclude)
+ {
+ // We got through all the conditions, add the string.
+ if (LB_ERR == SendMessage(hList, LB_FINDSTRING, 0, (LPARAM)pszKey))
+ {
+ pszKey[cch = lstrlen(pszKey)] = '\t';
+ lstrcpy(pszKey+cch+1, pszID);
+ SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)pszKey);
+ }
+ }
+
+ if (!bHaveCLSID)
+ OleStdFree((LPVOID)pszID);
+ }
+
+ // Select the first item by default
+ SendMessage(hList, LB_SETCURSEL, 0, 0L);
+ RegCloseKey(hKey);
+ OleStdFree((LPVOID)pszExec);
+
+ return cStrings;
+}
+
+/*
+ * FToggleObjectSource
+ *
+ * Purpose:
+ * Handles enabling, disabling, showing, and flag manipulation when the
+ * user changes between Create New, Insert File, and Link File in the
+ * Insert Object dialog.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpIO LPINSERTOBJECT pointing to the dialog structure
+ * dwOption DWORD flag indicating the option just selected:
+ * IOF_SELECTCREATENEW or IOF_SELECTCREATEFROMFILE
+ *
+ * Return Value:
+ * BOOL TRUE if the option was already selected, FALSE otherwise.
+ */
+
+BOOL FToggleObjectSource(HWND hDlg, LPINSERTOBJECT lpIO, DWORD dwOption)
+{
+ // Skip all of this if we're already selected.
+ if (lpIO->dwFlags & dwOption)
+ return TRUE;
+
+ // if we're switching from "from file" to "create new" and we've got
+ // an icon for "from file", then we need to save it so that we can
+ // show it if the user reselects "from file".
+
+ if ((IOF_SELECTCREATENEW == dwOption) &&
+ (lpIO->dwFlags & IOF_CHECKDISPLAYASICON))
+ {
+ lpIO->hMetaPictFile = (HGLOBAL)SendDlgItemMessage(hDlg,
+ IDC_IO_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ }
+
+ /*
+ * 1. Change the Display As Icon checked state to reflect the
+ * selection for this option, stored in the fAsIcon* flags.
+ */
+ BOOL fTemp;
+ if (IOF_SELECTCREATENEW == dwOption)
+ fTemp = lpIO->fAsIconNew;
+ else if (IOF_SELECTCREATEFROMFILE == dwOption)
+ fTemp = lpIO->fAsIconFile;
+ else
+ fTemp = FALSE;
+
+ if (fTemp)
+ lpIO->dwFlags |= IOF_CHECKDISPLAYASICON;
+ else
+ lpIO->dwFlags &= ~IOF_CHECKDISPLAYASICON;
+
+ CheckDlgButton(hDlg, IDC_IO_DISPLAYASICON,
+ (BOOL)(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)));
+
+ StandardEnableDlgItem(hDlg, IDC_IO_CHANGEICON, fTemp);
+
+ /*
+ * Display Icon: Enabled on Create New or on Create from File if
+ * there is a selected file.
+ */
+ if (IOF_SELECTCREATENEW == dwOption)
+ fTemp = TRUE;
+ else if (IOF_SELECTCREATEFROMFILE == dwOption)
+ fTemp = lpIO->fFileSelected;
+ else
+ fTemp = FALSE;
+
+ if (IOF_SELECTCREATECONTROL == dwOption)
+ StandardShowDlgItem(hDlg, IDC_IO_DISPLAYASICON, SW_HIDE);
+ else if (!(lpIO->dwFlags & IOF_DISABLEDISPLAYASICON))
+ StandardShowDlgItem(hDlg, IDC_IO_DISPLAYASICON, SW_SHOW);
+
+ StandardEnableDlgItem(hDlg, IDC_IO_DISPLAYASICON, fTemp);
+
+ // OK and Link follow the same enabling as Display As Icon.
+ StandardEnableDlgItem(hDlg, IDOK,
+ fTemp || IOF_SELECTCREATECONTROL == dwOption);
+ StandardEnableDlgItem(hDlg, IDC_IO_LINKFILE, fTemp);
+
+ // Enable Browse... when Create from File is selected.
+ fTemp = (IOF_SELECTCREATEFROMFILE != dwOption);
+ StandardEnableDlgItem(hDlg, IDC_IO_FILE, !fTemp);
+ StandardEnableDlgItem(hDlg, IDC_IO_FILEDISPLAY, !fTemp);
+
+ // Switch Object Type & Control Type listboxes if necessary
+ HWND hWnd1 = NULL, hWnd2 = NULL;
+ if (lpIO->bControlListActive && IOF_SELECTCREATENEW == dwOption)
+ {
+ hWnd1 = GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST);
+ hWnd2 = GetDlgItem(hDlg, IDC_IO_CONTROLTYPELIST);
+ SetWindowLong(hWnd1, GWL_ID, IDC_IO_CONTROLTYPELIST);
+ SetWindowLong(hWnd2, GWL_ID, IDC_IO_OBJECTTYPELIST);
+ lpIO->bControlListActive = FALSE;
+ }
+ else if (!lpIO->bControlListActive && IOF_SELECTCREATECONTROL == dwOption)
+ {
+ hWnd1 = GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST);
+ hWnd2 = GetDlgItem(hDlg, IDC_IO_CONTROLTYPELIST);
+ SetWindowLong(hWnd1, GWL_ID, IDC_IO_CONTROLTYPELIST);
+ SetWindowLong(hWnd2, GWL_ID, IDC_IO_OBJECTTYPELIST);
+ lpIO->bControlListActive = TRUE;
+ }
+
+ // Clear out any existing selection flags and set the new one
+ DWORD dwTemp = IOF_SELECTCREATENEW | IOF_SELECTCREATEFROMFILE |
+ IOF_SELECTCREATECONTROL;
+ lpIO->dwFlags = (lpIO->dwFlags & ~dwTemp) | dwOption;
+
+ if (dwOption & (IOF_SELECTCREATENEW|IOF_SELECTCREATECONTROL))
+ {
+ // refill class list box if necessary
+ if ((lpIO->bControlListActive && !lpIO->bControlListFilled) ||
+ (!lpIO->bControlListActive && !lpIO->bObjectListFilled))
+ {
+ URefillClassList(hDlg, lpIO);
+ }
+ }
+
+ if (hWnd1 != NULL && hWnd2 != NULL)
+ {
+ ShowWindow(hWnd1, SW_HIDE);
+ ShowWindow(hWnd2, SW_SHOW);
+ }
+
+ /*
+ * Switch between Object Type listbox on Create New and
+ * file buttons on others.
+ */
+ UINT uTemp = (fTemp) ? SW_SHOWNORMAL : SW_HIDE;
+ StandardShowDlgItem(hDlg, IDC_IO_OBJECTTYPELIST, uTemp);
+ StandardShowDlgItem(hDlg, IDC_IO_OBJECTTYPETEXT, uTemp);
+
+ uTemp = (fTemp) ? SW_HIDE : SW_SHOWNORMAL;
+ StandardShowDlgItem(hDlg, IDC_IO_FILETEXT, uTemp);
+ StandardShowDlgItem(hDlg, IDC_IO_FILETYPE, uTemp);
+ StandardShowDlgItem(hDlg, IDC_IO_FILEDISPLAY, uTemp);
+ StandardShowDlgItem(hDlg, IDC_IO_FILE, uTemp);
+
+ // Link is always hidden if IOF_DISABLELINK is set.
+ if (IOF_DISABLELINK & lpIO->dwFlags)
+ uTemp = SW_HIDE;
+
+ StandardShowDlgItem(hDlg, IDC_IO_LINKFILE, uTemp); //last use of uTemp
+
+ // Remove add button when not in Insert control mode
+ uTemp = (IOF_SELECTCREATECONTROL == dwOption) ? SW_SHOW : SW_HIDE;
+ StandardShowDlgItem(hDlg, IDC_IO_ADDCONTROL, uTemp);
+
+ /*
+ * Show or hide controls as appropriate. Do the icon
+ * display last because it will take some time to repaint.
+ * If we do it first then the dialog looks too sluggish.
+ */
+
+ int i = (lpIO->dwFlags & IOF_CHECKDISPLAYASICON) ? SW_SHOWNORMAL : SW_HIDE;
+ StandardShowDlgItem(hDlg, IDC_IO_CHANGEICON, i);
+ StandardShowDlgItem(hDlg, IDC_IO_ICONDISPLAY, i);
+
+ // Change result display
+ SetInsertObjectResults(hDlg, lpIO);
+
+ /*
+ * For Create New, twiddle the listbox to think we selected it
+ * so it updates the icon from the object type. set the focus
+ * to the list box.
+ *
+ * For Insert or Link file, set the focus to the filename button
+ * and update the icon if necessary.
+ */
+ if (fTemp)
+ {
+ UpdateClassIcon(hDlg, lpIO, GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST));
+ SetFocus(GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST));
+ }
+ else
+ {
+ if (lpIO->fAsIconFile && (NULL != lpIO->hMetaPictFile) )
+ {
+ SendDlgItemMessage(hDlg, IDC_IO_ICONDISPLAY, IBXM_IMAGESET, 0,
+ (LPARAM)lpIO->hMetaPictFile);
+ lpIO->hMetaPictFile = 0;
+ }
+ else
+ {
+ UpdateClassIcon(hDlg, lpIO, NULL);
+ }
+ SetFocus(GetDlgItem(hDlg, IDC_IO_FILE));
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * UpdateClassType
+ *
+ * Purpose:
+ * Updates static text control to reflect current file type. Assumes
+ * a valid filename.
+ *
+ * Parameters
+ * hDlg HWND of the dialog box.
+ * lpIO LPINSERTOBJECT pointing to the dialog structure
+ * fSet TRUE to set the text, FALSE to explicitly clear it
+ *
+ * Return Value:
+ * None
+ */
+
+void UpdateClassType(HWND hDlg, LPINSERTOBJECT lpIO, BOOL fSet)
+{
+ LPTSTR lpszFileType = NULL;
+ if (fSet)
+ {
+ TCHAR szFileName[MAX_PATH];
+ GetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, szFileName, MAX_PATH);
+
+ CLSID clsid;
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszFileName[MAX_PATH];
+ LPOLESTR wszFileType = NULL;
+ ATOW(wszFileName, szFileName, MAX_PATH);
+ if (NOERROR == GetClassFile(wszFileName, &clsid))
+ OleRegGetUserType(clsid, USERCLASSTYPE_FULL, &wszFileType);
+ if (NULL != wszFileType)
+ {
+ UINT uLen = WTOALEN(wszFileType);
+ lpszFileType = (LPTSTR)OleStdMalloc(uLen);
+ if (NULL != lpszFileType)
+ {
+ WTOA(lpszFileType, wszFileType, uLen);
+ }
+ OleStdFree(wszFileType);
+ }
+#else
+ if (NOERROR == GetClassFile(szFileName, &clsid))
+ OleRegGetUserType(clsid, USERCLASSTYPE_FULL, &lpszFileType);
+#endif
+ }
+ SetDlgItemText(hDlg, IDC_IO_FILETYPE, lpszFileType);
+ OleStdFree(lpszFileType);
+}
+
+
+/*
+ * UpdateClassIcon
+ *
+ * Purpose:
+ * Handles LBN_SELCHANGE for the Object Type listbox. On a selection
+ * change, we extract an icon from the server handling the currently
+ * selected object type using the utility function HIconFromClass.
+ * Note that we depend on the behavior of FillClassList to stuff the
+ * object class after a tab in the listbox string that we hide from
+ * view (see WM_INITDIALOG).
+ *
+ * Parameters
+ * hDlg HWND of the dialog box.
+ * lpIO LPINSERTOBJECT pointing to the dialog structure
+ * hList HWND of the Object Type listbox.
+ *
+ * Return Value:
+ * None
+ */
+
+static void UpdateClassIcon(HWND hDlg, LPINSERTOBJECT lpIO, HWND hList)
+{
+ // If Display as Icon is not selected, exit
+ if (!(lpIO->dwFlags & IOF_CHECKDISPLAYASICON))
+ return;
+
+ /*
+ * When we change object type selection, get the new icon for that
+ * type into our structure and update it in the display. We use the
+ * class in the listbox when Create New is selected or the association
+ * with the extension in Create From File.
+ */
+
+ DWORD cb = MAX_PATH;
+ UINT iSel;
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ {
+ iSel = (UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
+
+ if (LB_ERR==(int)iSel)
+ return;
+
+ // Check to see if we've already got the hMetaPict for this item
+ DWORD dwRet = SendMessage(hList, LB_GETITEMDATA, (WPARAM)iSel, 0L);
+
+ HGLOBAL hMetaPict=(HGLOBAL)(UINT)dwRet;
+ if (hMetaPict)
+ {
+ // Yep, we've already got it, so just display it and return.
+ SendDlgItemMessage(hDlg, IDC_IO_ICONDISPLAY, IBXM_IMAGESET,
+ 0, (LPARAM)hMetaPict);
+ return;
+ }
+ iSel = (UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
+ if (LB_ERR==(int)iSel)
+ return;
+
+ // Allocate a string to hold the entire listbox string
+ cb = SendMessage(hList, LB_GETTEXTLEN, iSel, 0L);
+ }
+
+ LPTSTR pszName = (LPTSTR)OleStdMalloc((cb+1)*sizeof(TCHAR));
+ if (NULL == pszName)
+ return;
+ *pszName = 0;
+
+ // Get the clsid we want.
+ HGLOBAL hMetaPict;
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ {
+ // Grab the classname string from the list
+ SendMessage(hList, LB_GETTEXT, iSel, (LONG)pszName);
+
+ // Set pointer to CLSID (string)
+ LPTSTR pszCLSID = PointerToNthField(pszName, 2, '\t');
+
+ // Get CLSID from the string and then accociated icon
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszCLSID[OLEUI_CCHKEYMAX];
+ ATOW(wszCLSID, pszCLSID, OLEUI_CCHKEYMAX);
+ CLSIDFromString(wszCLSID, &lpIO->clsid);
+#else
+ CLSIDFromString(pszCLSID, &lpIO->clsid);
+#endif
+ hMetaPict = OleGetIconOfClass(lpIO->clsid, NULL, TRUE);
+ }
+
+ else
+ {
+ // Get the class from the filename
+ GetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, pszName, MAX_PATH);
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszName[MAX_PATH];
+ ATOW(wszName, pszName, MAX_PATH);
+ hMetaPict = OleGetIconOfFile(wszName,
+ lpIO->dwFlags & IOF_CHECKLINK ? TRUE : FALSE);
+#else
+ hMetaPict = OleGetIconOfFile(pszName,
+ lpIO->dwFlags & IOF_CHECKLINK ? TRUE : FALSE);
+#endif
+ }
+
+ // Replace the current display with this new one.
+ SendDlgItemMessage(hDlg, IDC_IO_ICONDISPLAY, IBXM_IMAGESET,
+ 0, (LPARAM)hMetaPict);
+
+ // Enable or disable "Change Icon" button depending on whether
+ // we've got a valid filename or not.
+ StandardEnableDlgItem(hDlg, IDC_IO_CHANGEICON, hMetaPict ? TRUE : FALSE);
+
+ // Save the hMetaPict so that we won't have to re-create
+ if (lpIO->dwFlags & IOF_SELECTCREATENEW)
+ SendMessage(hList, LB_SETITEMDATA, (WPARAM)iSel, (LPARAM)hMetaPict);
+
+ OleStdFree(pszName);
+}
+
+
+/*
+ * SetInsertObjectResults
+ *
+ * Purpose:
+ * Centralizes setting of the Result and icon displays in the Insert Object
+ * dialog. Handles loading the appropriate string from the module's
+ * resources and setting the text, displaying the proper result picture,
+ * and showing the proper icon.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog box so we can access controls.
+ * lpIO LPINSERTOBJECT in which we assume that the
+ * current radiobutton and Display as Icon selections
+ * are set. We use the state of those variables to
+ * determine which string we use.
+ *
+ * Return Value:
+ * None
+ */
+
+void SetInsertObjectResults(HWND hDlg, LPINSERTOBJECT lpIO)
+{
+ /*
+ * We need scratch memory for loading the stringtable string, loading
+ * the object type from the listbox, and constructing the final string.
+ * We therefore allocate three buffers as large as the maximum message
+ * length (512) plus the object type, guaranteeing that we have enough
+ * in all cases.
+ */
+ UINT i = (UINT)SendDlgItemMessage(hDlg, IDC_IO_OBJECTTYPELIST, LB_GETCURSEL, 0, 0L);
+
+ UINT cch = 512;
+
+ if (i != LB_ERR)
+ {
+ cch += (UINT)SendDlgItemMessage(hDlg, IDC_IO_OBJECTTYPELIST, LB_GETTEXTLEN, i, 0L);
+ }
+
+ LPTSTR pszTemp= (LPTSTR)OleStdMalloc((DWORD)(4*cch)*sizeof(TCHAR));
+ if (NULL == pszTemp)
+ return;
+
+ LPTSTR psz1 = pszTemp;
+ LPTSTR psz2 = psz1+cch;
+ LPTSTR psz3 = psz2+cch;
+ LPTSTR psz4 = psz3+cch;
+
+ BOOL fAsIcon = (0L != (lpIO->dwFlags & IOF_CHECKDISPLAYASICON));
+ UINT iImage, iString1, iString2;
+
+ if (lpIO->dwFlags & (IOF_SELECTCREATENEW|IOF_SELECTCREATECONTROL))
+ {
+ iString1 = fAsIcon ? IDS_IORESULTNEWICON : IDS_IORESULTNEW;
+ iString2 = 0;
+ iImage = fAsIcon ? RESULTIMAGE_EMBEDICON : RESULTIMAGE_EMBED;
+ }
+
+ if (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE)
+ {
+ // Pay attention to Link checkbox
+ if (lpIO->dwFlags & IOF_CHECKLINK)
+ {
+ iString1 = fAsIcon ? IDS_IORESULTLINKFILEICON1 : IDS_IORESULTLINKFILE1;
+ iString2 = fAsIcon ? IDS_IORESULTLINKFILEICON2 : IDS_IORESULTLINKFILE2;
+ iImage =fAsIcon ? RESULTIMAGE_LINKICON : RESULTIMAGE_LINK;
+ }
+ else
+ {
+ iString1 = IDS_IORESULTFROMFILE1;
+ iString2 = fAsIcon ? IDS_IORESULTFROMFILEICON2 : IDS_IORESULTFROMFILE2;
+ iImage =fAsIcon ? RESULTIMAGE_EMBEDICON : RESULTIMAGE_EMBED;
+ }
+ }
+
+ // Default is an empty string.
+ *psz1=0;
+
+ if (0 != LoadString(_g_hOleStdResInst, iString1, psz1, cch))
+ {
+ // Load second string, if necessary
+ if (0 != iString2 &&
+ 0 != LoadString(_g_hOleStdResInst, iString2, psz4, cch))
+ {
+ lstrcat(psz1, psz4); // concatenate strings together.
+ }
+
+ // In Create New, do the extra step of inserting the object type string
+ if (lpIO->dwFlags & (IOF_SELECTCREATENEW|IOF_SELECTCREATECONTROL))
+ {
+ if (i == LB_ERR)
+ {
+ SetDlgItemText(hDlg, IDC_IO_RESULTTEXT, NULL);
+
+ // Change the image.
+ SendDlgItemMessage(hDlg, IDC_IO_RESULTIMAGE, RIM_IMAGESET, RESULTIMAGE_NONE, 0L);
+
+ OleStdFree((LPVOID)pszTemp);
+ return;
+ }
+
+ SendDlgItemMessage(hDlg, IDC_IO_OBJECTTYPELIST, LB_GETTEXT, i, (LONG)psz2);
+
+ // Null terminate at any tab (before the classname)
+ LPTSTR pszT = psz2;
+ while ('\t' != *pszT && 0 != *pszT)
+ pszT++;
+ *pszT=0;
+
+ // Build the string and point psz1 to it.
+ wsprintf(psz3, psz1, psz2);
+ psz1 = psz3;
+ }
+ }
+
+ // If LoadString failed, we simply clear out the results (*psz1=0 above)
+ SetDlgItemText(hDlg, IDC_IO_RESULTTEXT, psz1);
+
+ // Go change the image and Presto! There you have it.
+ SendDlgItemMessage(hDlg, IDC_IO_RESULTIMAGE, RIM_IMAGESET, iImage, 0L);
+
+ OleStdFree((LPVOID)pszTemp);
+}
+
+/*
+ * FValidateInsertFile
+ *
+ * Purpose:
+ * Given a possibly partial pathname from the file edit control,
+ * attempt to locate the file and if found, store the full path
+ * in the edit control IDC_IO_FILEDISPLAY.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog box.
+ * fTellUser BOOL TRUE if function should tell user, FALSE if
+ * function should validate silently.
+ *
+ * Return Value:
+ * BOOL TRUE if the file is acceptable, FALSE otherwise.
+ */
+
+BOOL FValidateInsertFile(HWND hDlg, BOOL fTellUser, UINT FAR* lpnErrCode)
+{
+ *lpnErrCode = 0;
+
+ /*
+ * To validate we attempt OpenFile on the string. If OpenFile
+ * fails then we display an error. If not, OpenFile will store
+ * the complete path to that file in the OFSTRUCT which we can
+ * then stuff in the edit control.
+ */
+ TCHAR szFile[MAX_PATH];
+ if (0 == GetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, szFile, MAX_PATH))
+ return FALSE; // #4569 : return FALSE when there is no text in ctl
+
+ // if file is currently open (ie. sharing violation) OleCreateFromFile
+ // and OleCreateLinkToFile can still succeed; do not consider it an
+ // error.
+ if (!DoesFileExist(szFile, MAX_PATH))
+ {
+ *lpnErrCode = ERROR_FILE_NOT_FOUND;
+ if (fTellUser)
+ OpenFileError(hDlg, ERROR_FILE_NOT_FOUND, szFile);
+ return FALSE;
+ }
+
+ // get full pathname, since the file exists
+ TCHAR szPath[MAX_PATH];
+ LPTSTR lpszDummy;
+ GetFullPathName(szFile, sizeof(szPath)/sizeof(TCHAR), szPath, &lpszDummy);
+ SetDlgItemText(hDlg, IDC_IO_FILEDISPLAY, szPath);
+
+ return TRUE;
+}
+
+
+/*
+ * InsertObjectCleanup
+ *
+ * Purpose:
+ * Clears cached icon metafiles from those stored in the listbox.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog.
+ *
+ * Return Value:
+ * None
+ */
+
+void InsertObjectCleanup(HWND hDlg)
+{
+ HWND hList = GetDlgItem(hDlg, IDC_IO_OBJECTTYPELIST);
+ UINT iItems= (UINT)SendMessage(hList, LB_GETCOUNT, 0, 0L);
+ for (UINT i = 0; i < iItems; i++)
+ {
+ LRESULT dwRet = SendMessage(hList, LB_GETITEMDATA, (WPARAM)i, 0L);
+ HGLOBAL hMetaPict=(HGLOBAL)(UINT)dwRet;
+ if (hMetaPict)
+ OleUIMetafilePictIconFree(hMetaPict);
+ }
+}
diff --git a/private/ole2ui32/links.cpp b/private/ole2ui32/links.cpp
new file mode 100644
index 000000000..68b160020
--- /dev/null
+++ b/private/ole2ui32/links.cpp
@@ -0,0 +1,1537 @@
+/*
+ * links.c
+ *
+ * Implements the OleUIEditLinks function which invokes the complete
+ * Edit Links dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+#include <commdlg.h>
+#include <dlgs.h>
+#include <stdlib.h>
+
+OLEDBGDATA
+
+// INTERNAL INFORMATION STARTS HERE
+#define OLEUI_SZMAX 255
+#define LINKTYPELEN 30 // was 9, now I've more than tripled it
+#define szNULL TEXT("\0")
+
+typedef UINT (CALLBACK* COMMDLGHOOKPROC)(HWND, UINT, WPARAM, LPARAM);
+
+// Internally used structure
+
+typedef struct tagLINKINFO
+{
+ DWORD dwLink; // app specific identifier of a link
+ LPTSTR lpszDisplayName; // file based part of name
+ LPTSTR lpszItemName; // object part of name
+ LPTSTR lpszShortFileName; // filename without path
+ LPTSTR lpszShortLinkType; // Short link type - progID
+ LPTSTR lpszFullLinkType; // Full link type - user friendly name
+ LPTSTR lpszAMX; // Is the link auto (A) man (M) or dead (X)
+ ULONG clenFileName; // count of file part of mon.
+ BOOL fSourceAvailable; // bound or not - on boot assume yes??
+ BOOL fIsAuto; // 1 =automatic, 0=manual update
+ BOOL fIsMarked; // 1 = marked, 0 = not
+ BOOL fDontFree; // Don't free this data since it's being reused
+ BOOL fIsSelected; // item selected or to be selected
+} LINKINFO, FAR* LPLINKINFO;
+
+typedef struct tagEDITLINKS
+{
+ // Keep this item first as the Standard* functions depend on it here.
+ LPOLEUIEDITLINKS lpOEL; // Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ BOOL fClose; // Does the button read cancel (0) or
+ // close (1)?
+ BOOL fItemsExist; // TRUE, items in lbox, FALSE, none
+ UINT nChgSrcHelpID; // ID for Help callback from ChangeSrc dlg
+ TCHAR szClose[50]; // Text for Close button
+ // (when Cancel button gets renamed)
+ int nColPos[3]; // tab positions for list box
+ int nHeightLine; // height of each line in owner draw listbox
+ int nMaxCharWidth; // maximim width of text in owner draw listbox
+
+} EDITLINKS, *PEDITLINKS, FAR *LPEDITLINKS;
+
+// Internal function prototypes
+// LINKS.CPP
+
+BOOL CALLBACK EditLinksDialogProc(HWND, UINT, WPARAM, LPARAM);
+BOOL FEditLinksInit(HWND, WPARAM, LPARAM);
+BOOL Container_ChangeSource(HWND, LPEDITLINKS);
+HRESULT Container_AutomaticManual(HWND, BOOL, LPEDITLINKS);
+HRESULT CancelLink(HWND, LPEDITLINKS);
+HRESULT Container_UpdateNow(HWND, LPEDITLINKS);
+HRESULT Container_OpenSource(HWND, LPEDITLINKS);
+int AddLinkLBItem(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPLINKINFO lpLI,
+ BOOL fGetSelected);
+VOID BreakString(LPLINKINFO);
+int GetSelectedItems(HWND, int FAR* FAR*);
+VOID InitControls(HWND hDlg, LPEDITLINKS lpEL);
+VOID UpdateLinkLBItem(HWND hListBox, int nIndex, LPEDITLINKS lpEL, BOOL bSelect);
+VOID ChangeAllLinks(HWND hLIstBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPTSTR lpszFrom, LPTSTR lpszTo);
+int LoadLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr);
+VOID RefreshLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr);
+
+
+/*
+* OleUIEditLinks
+*
+* Purpose:
+* Invokes the standard OLE Edit Links dialog box allowing the user
+* to manipulate ole links (delete, update, change source, etc).
+*
+* Parameters:
+* lpEL LPOLEUIEditLinks pointing to the in-out structure
+* for this dialog.
+*
+* Return Value:
+* UINT One of the following codes, indicating success or error:
+* OLEUI_SUCCESS Success
+* OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
+*/
+STDAPI_(UINT) OleUIEditLinks(LPOLEUIEDITLINKS lpEL)
+{
+ HGLOBAL hMemDlg = NULL;
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)lpEL, sizeof(OLEUIEDITLINKS),
+ &hMemDlg);
+
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+ // Validate interface.
+ if (NULL == lpEL->lpOleUILinkContainer)
+ {
+ uRet = OLEUI_ELERR_LINKCNTRNULL;
+ }
+ else if(IsBadReadPtr(lpEL->lpOleUILinkContainer, sizeof(IOleUILinkContainer)))
+ {
+ uRet = OLEUI_ELERR_LINKCNTRINVALID;
+ }
+
+ if (OLEUI_SUCCESS != uRet)
+ {
+ return(uRet);
+ }
+
+ UINT nIDD = bWin4 ? IDD_EDITLINKS4 : IDD_EDITLINKS;
+
+ // Now that we've validated everything, we can invoke the dialog.
+ uRet = UStandardInvocation(EditLinksDialogProc, (LPOLEUISTANDARD)lpEL,
+ hMemDlg, MAKEINTRESOURCE(nIDD));
+ return uRet;
+}
+
+/*
+* EditLinksDialogProc
+*
+* Purpose:
+* Implements the OLE Edit Links dialog as invoked through the
+* OleUIEditLinks function.
+*
+* Parameters:
+* Standard
+*
+* Return Value:
+* Standard
+*/
+BOOL CALLBACK EditLinksDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uRet = 0;
+ LPEDITLINKS lpEL = (LPEDITLINKS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
+
+ // If the hook processed the message, we're done.
+ if (0 != uRet)
+ return (BOOL)uRet;
+
+ //Process help message from secondary dialog
+ if (iMsg == uMsgHelp)
+ {
+ PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp, wParam, lParam);
+ return FALSE;
+ }
+
+ // Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ switch (iMsg)
+ {
+ case WM_DESTROY:
+ if (lpEL)
+ {
+ StandardCleanup(lpEL, hDlg);
+ }
+ break;
+ case WM_INITDIALOG:
+ return FEditLinksInit(hDlg, wParam, lParam);
+
+ case WM_MEASUREITEM:
+ {
+ LPMEASUREITEMSTRUCT lpMIS = (LPMEASUREITEMSTRUCT)lParam;
+ int nHeightLine;
+
+ if (lpEL && lpEL->nHeightLine != -1)
+ {
+ // use cached height
+ nHeightLine = lpEL->nHeightLine;
+ }
+ else
+ {
+ HFONT hFont;
+ HDC hDC;
+ TEXTMETRIC tm;
+
+ hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
+
+ if (hFont == NULL)
+ hFont = (HFONT)GetStockObject(SYSTEM_FONT);
+
+ hDC = GetDC(hDlg);
+ hFont = (HFONT)SelectObject(hDC, hFont);
+
+ GetTextMetrics(hDC, &tm);
+ nHeightLine = tm.tmHeight;
+
+ if (lpEL)
+ {
+ lpEL->nHeightLine = nHeightLine;
+ lpEL->nMaxCharWidth = tm.tmMaxCharWidth;
+ }
+ ReleaseDC(hDlg, hDC);
+ }
+ lpMIS->itemHeight = nHeightLine;
+ }
+ break;
+
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
+ LPLINKINFO lpLI = (LPLINKINFO)lpDIS->itemData;
+
+ if ((int)lpDIS->itemID < 0)
+ break;
+
+ if ((ODA_DRAWENTIRE | ODA_SELECT) & lpDIS->itemAction)
+ {
+ HBRUSH hbr;
+ COLORREF crText;
+ if (ODS_SELECTED & lpDIS->itemState)
+ {
+ /*Get proper txt colors */
+ crText = SetTextColor(lpDIS->hDC,
+ GetSysColor(COLOR_HIGHLIGHTTEXT));
+ hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
+ lpLI->fIsSelected = TRUE;
+ }
+ else
+ {
+ hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
+ lpLI->fIsSelected = FALSE;
+ }
+
+ FillRect(lpDIS->hDC, &lpDIS->rcItem, hbr);
+ DeleteObject(hbr);
+
+ int nOldBkMode = SetBkMode(lpDIS->hDC, TRANSPARENT);
+
+ RECT rcClip;
+ if (lpLI->lpszDisplayName)
+ {
+ TCHAR szTemp[MAX_PATH];
+ lstrcpy(szTemp, lpLI->lpszDisplayName);
+ LPTSTR lpsz = ChopText(
+ lpDIS->hwndItem,
+ lpEL->nColPos[1] - lpEL->nColPos[0]
+ - (lpEL->nMaxCharWidth > 0 ?
+ lpEL->nMaxCharWidth : 5),
+ szTemp, 0
+ );
+ rcClip.left = lpDIS->rcItem.left + lpEL->nColPos[0];
+ rcClip.top = lpDIS->rcItem.top;
+ rcClip.right = lpDIS->rcItem.left + lpEL->nColPos[1]
+ - (lpEL->nMaxCharWidth > 0 ?
+ lpEL->nMaxCharWidth : 5);
+ rcClip.bottom = lpDIS->rcItem.bottom;
+ ExtTextOut(
+ lpDIS->hDC,
+ rcClip.left,
+ rcClip.top,
+ ETO_CLIPPED,
+ (LPRECT)&rcClip,
+ lpsz,
+ lstrlen(lpsz),
+ NULL
+ );
+ }
+ if (lpLI->lpszShortLinkType)
+ {
+ rcClip.left = lpDIS->rcItem.left + lpEL->nColPos[1];
+ rcClip.top = lpDIS->rcItem.top;
+ rcClip.right = lpDIS->rcItem.left + lpEL->nColPos[2]
+ - (lpEL->nMaxCharWidth > 0 ?
+ lpEL->nMaxCharWidth : 5);
+ rcClip.bottom = lpDIS->rcItem.bottom;
+ ExtTextOut(
+ lpDIS->hDC,
+ rcClip.left,
+ rcClip.top,
+ ETO_CLIPPED,
+ (LPRECT)&rcClip,
+ lpLI->lpszShortLinkType,
+ lstrlen(lpLI->lpszShortLinkType),
+ NULL
+ );
+ }
+ if (lpLI->lpszAMX)
+ {
+ rcClip.left = lpDIS->rcItem.left + lpEL->nColPos[2];
+ rcClip.top = lpDIS->rcItem.top;
+ rcClip.right = lpDIS->rcItem.right;
+ rcClip.bottom = lpDIS->rcItem.bottom;
+ ExtTextOut(
+ lpDIS->hDC,
+ rcClip.left,
+ rcClip.top,
+ ETO_CLIPPED,
+ (LPRECT)&rcClip,
+ lpLI->lpszAMX,
+ lstrlen(lpLI->lpszAMX),
+ NULL
+ );
+ }
+
+ SetBkMode(lpDIS->hDC, nOldBkMode);
+
+ // restore orig colors if we changed them
+ if (ODS_SELECTED & lpDIS->itemState)
+ SetTextColor(lpDIS->hDC, crText);
+
+ }
+ if (ODA_FOCUS & lpDIS->itemAction)
+ DrawFocusRect(lpDIS->hDC, &lpDIS->rcItem);
+ }
+ return TRUE;
+
+ case WM_DELETEITEM:
+ {
+ LPDELETEITEMSTRUCT lpDIS = (LPDELETEITEMSTRUCT)lParam;
+ UINT idCtl = wParam;
+ LPLINKINFO lpLI = (LPLINKINFO)lpDIS->itemData;
+
+ if (lpLI->lpszDisplayName)
+ OleStdFree((LPVOID)lpLI->lpszDisplayName);
+ if (lpLI->lpszShortLinkType)
+ OleStdFree((LPVOID)lpLI->lpszShortLinkType);
+ if (lpLI->lpszFullLinkType)
+ OleStdFree((LPVOID)lpLI->lpszFullLinkType);
+
+ /* The ChangeSource processing reuses allocated space for
+ ** links that have been modified.
+ */
+ // Don't free the LINKINFO for the changed links
+ if (lpLI->fDontFree)
+ lpLI->fDontFree = FALSE;
+ else
+ {
+ if (lpLI->lpszAMX)
+ OleStdFree((LPVOID)lpLI->lpszAMX);
+ OleStdFree((LPVOID)lpLI);
+ }
+ }
+ return TRUE;
+
+ case WM_COMPAREITEM:
+ {
+ LPCOMPAREITEMSTRUCT lpCIS = (LPCOMPAREITEMSTRUCT)lParam;
+ LPLINKINFO lpLI1 = (LPLINKINFO)lpCIS->itemData1;
+ LPLINKINFO lpLI2 = (LPLINKINFO)lpCIS->itemData2;
+
+ // Sort list entries by DisplayName
+ return lstrcmp(lpLI1->lpszDisplayName, lpLI2->lpszDisplayName);
+ }
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_EL_CHANGESOURCE:
+ {
+ BOOL fRet = Container_ChangeSource(hDlg, lpEL);
+ if (!fRet)
+ PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
+ MB_ICONEXCLAMATION | MB_OK);
+ InitControls(hDlg, lpEL);
+ }
+ break;
+
+ case IDC_EL_AUTOMATIC:
+ {
+ CheckDlgButton(hDlg, IDC_EL_AUTOMATIC, 1);
+ CheckDlgButton(hDlg, IDC_EL_MANUAL, 0);
+
+ HRESULT hErr = Container_AutomaticManual(hDlg, TRUE, lpEL);
+ if (hErr != NOERROR)
+ PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
+ MB_ICONEXCLAMATION | MB_OK);
+
+ InitControls(hDlg, lpEL);
+ }
+ break;
+
+ case IDC_EL_MANUAL:
+ {
+ CheckDlgButton(hDlg, IDC_EL_MANUAL, 1);
+ CheckDlgButton(hDlg, IDC_EL_AUTOMATIC, 0);
+
+ HRESULT hErr = Container_AutomaticManual(hDlg, FALSE, lpEL);
+ if (hErr != NOERROR)
+ PopupMessage(hDlg, IDS_LINKS, IDS_FAILED,
+ MB_ICONEXCLAMATION | MB_OK);
+
+ InitControls(hDlg, lpEL);
+ }
+ break;
+
+ case IDC_EL_CANCELLINK:
+ CancelLink(hDlg,lpEL);
+ InitControls(hDlg, lpEL);
+ break;
+
+ case IDC_EL_UPDATENOW:
+ Container_UpdateNow(hDlg, lpEL);
+ InitControls(hDlg, lpEL);
+ break;
+
+ case IDC_EL_OPENSOURCE:
+ {
+ HRESULT hErr = Container_OpenSource(hDlg, lpEL);
+ if (hErr != NOERROR)
+ {
+ InitControls(hDlg, lpEL);
+ // Don't close dialog
+ break;
+ }
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ } // fall through
+
+ case IDC_EL_LINKSLISTBOX:
+ if (wCode == LBN_SELCHANGE)
+ InitControls(hDlg, lpEL);
+ break;
+
+ case IDCANCEL:
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
+ break;
+
+ case IDC_OLEUIHELP:
+ PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_EDITLINKS, 0));
+ break;
+ }
+ break;
+
+ default:
+ if (lpEL != NULL && iMsg == lpEL->nChgSrcHelpID)
+ {
+ PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_CHANGESOURCE, 0));
+ }
+ if (iMsg == uMsgBrowseOFN &&
+ lpEL != NULL && lpEL->lpOEL && lpEL->lpOEL->hWndOwner)
+ {
+ SendMessage(lpEL->lpOEL->hWndOwner, uMsgBrowseOFN, wParam, lParam);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * FEditLinksInit
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the Edit Links dialog box.
+ *
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+BOOL FEditLinksInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ HFONT hFont;
+ LPEDITLINKS lpEL = (LPEDITLINKS)LpvStandardInit(hDlg, sizeof(EDITLINKS), &hFont);
+
+ // PvStandardInit send a termination to us already.
+ if (NULL == lpEL)
+ return FALSE;
+
+ LPOLEUIEDITLINKS lpOEL = (LPOLEUIEDITLINKS)lParam;
+ lpEL->lpOEL = lpOEL;
+ lpEL->nIDD = IDD_EDITLINKS;
+
+ // metrics unknown so far
+ lpEL->nHeightLine = -1;
+ lpEL->nMaxCharWidth = -1;
+
+ /* calculate the column positions relative to the listbox */
+ HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
+ RECT rc;
+ GetWindowRect(hListBox, (LPRECT)&rc);
+ int nStart = rc.left;
+ GetWindowRect(GetDlgItem(hDlg, IDC_EL_COL1), (LPRECT)&rc);
+ lpEL->nColPos[0] = rc.left - nStart;
+ GetWindowRect(GetDlgItem(hDlg, IDC_EL_COL2), (LPRECT)&rc);
+ lpEL->nColPos[1] = rc.left - nStart;
+ GetWindowRect(GetDlgItem(hDlg, IDC_EL_COL3), (LPRECT)&rc);
+ lpEL->nColPos[2] = rc.left - nStart;
+
+ LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
+
+ ULONG cLinks = LoadLinkLB(hListBox, lpOleUILinkCntr);
+ if (cLinks < 0)
+ return FALSE;
+
+ BOOL fDlgItem = (BOOL)cLinks;
+ lpEL->fItemsExist = (BOOL)cLinks;
+
+ InitControls(hDlg, lpEL);
+
+ // Copy other information from lpOEL that we might modify.
+
+ // If we got a font, send it to the necessary controls.
+ if (NULL != hFont)
+ {
+ // Do this for as many controls as you need it for.
+ // SendDlgItemMessage(hDlg, ID_<UFILL>, WM_SETFONT, (WPARAM)hFont, 0L);
+ }
+
+ // Show or hide the help button
+ if (!(lpEL->lpOEL->dwFlags & ELF_SHOWHELP))
+ StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
+
+ /*
+ * PERFORM OTHER INITIALIZATION HERE. ON ANY LoadString
+ * FAILURE POST OLEUI_MSG_ENDDIALOG WITH OLEUI_ERR_LOADSTRING.
+ */
+
+ // If requested disable UpdateNow button
+ if ((lpEL->lpOEL->dwFlags & ELF_DISABLEUPDATENOW))
+ StandardShowDlgItem(hDlg, IDC_EL_UPDATENOW, SW_HIDE);
+
+ // If requested disable OpenSource button
+ if ((lpEL->lpOEL->dwFlags & ELF_DISABLEOPENSOURCE))
+ StandardShowDlgItem(hDlg, IDC_EL_OPENSOURCE, SW_HIDE);
+
+ // If requested disable UpdateNow button
+ if ((lpEL->lpOEL->dwFlags & ELF_DISABLECHANGESOURCE))
+ StandardShowDlgItem(hDlg, IDC_EL_CHANGESOURCE, SW_HIDE);
+
+ // If requested disable CancelLink button
+ if ((lpEL->lpOEL->dwFlags & ELF_DISABLECANCELLINK))
+ StandardShowDlgItem(hDlg, IDC_EL_CANCELLINK, SW_HIDE);
+
+ // Change the caption
+ if (NULL!=lpOEL->lpszCaption)
+ SetWindowText(hDlg, lpOEL->lpszCaption);
+
+ // Load 'Close' string used to rename Cancel button
+ int n = LoadString(_g_hOleStdResInst, IDS_CLOSE, lpEL->szClose, sizeof(lpEL->szClose)/sizeof(TCHAR));
+ if (!n)
+ {
+ PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L);
+ return FALSE;
+ }
+
+ if (cLinks > 0)
+ SetFocus(hListBox);
+ else
+ SetFocus(GetDlgItem(hDlg, IDCANCEL));
+
+ lpEL->nChgSrcHelpID = RegisterWindowMessage(HELPMSGSTRING);
+
+ // Call the hook with lCustData in lParam
+ UStandardHook(lpEL, hDlg, WM_INITDIALOG, wParam, lpOEL->lCustData);
+
+ return FALSE;
+}
+
+/*
+* Container_ChangeSource
+*
+* Purpose:
+* Tunnel to File Open type dlg and allow user to select new file
+* for file based monikers, OR to change the whole moniker to what
+* the user types into the editable field.
+*
+* Parameters:
+* hDlg HWND of the dialog
+* LPEDITLINKS Pointer to EditLinks structure (contains all nec.
+* info)
+*
+* Return Value:
+* BOOL for now, because we are not using any ole functions
+* to return an HRESULT.
+* HRESULT HRESULT value indicating success or failure of
+* changing the moniker value
+*/
+
+BOOL Container_ChangeSource(HWND hDlg, LPEDITLINKS lpEL)
+{
+ HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
+ int FAR* rgIndex;
+ int cSelItems = GetSelectedItems(hListBox, &rgIndex);
+
+ if (cSelItems < 0)
+ return FALSE;
+
+ if (!cSelItems)
+ return TRUE;
+
+ OLEUICHANGESOURCE cs; memset(&cs, 0, sizeof(cs));
+ cs.cbStruct = sizeof(cs);
+ cs.hWndOwner = hDlg;
+ if (lpEL->lpOEL->dwFlags & ELF_SHOWHELP)
+ cs.dwFlags |= CSF_SHOWHELP;
+
+ LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
+ cs.lpOleUILinkContainer = lpOleUILinkCntr;
+
+ for (int i = cSelItems-1; i >= 0; i--)
+ {
+ // allow caller to customize the change source dialog
+ LPLINKINFO lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
+ cs.lpszDisplayName = lpLI->lpszDisplayName;
+ cs.dwLink = lpLI->dwLink;
+ cs.nFileLength = lpLI->clenFileName;
+
+ UINT uRet = UStandardHook(lpEL, hDlg, uMsgChangeSource, 0, (LPARAM)&cs);
+ if (!uRet)
+ uRet = (OLEUI_OK == OleUIChangeSource(&cs));
+ if (!uRet)
+ break; // dialog canceled (cancel for all)
+
+ if (!lpEL->fClose)
+ {
+ SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
+ lpEL->fClose = TRUE;
+ }
+
+ // update the list box item for the new name
+ // (note: original lpszDisplayName already freed)
+ lpLI->fSourceAvailable = (cs.dwFlags & CSF_VALIDSOURCE);
+ lpLI->lpszDisplayName = cs.lpszDisplayName;
+ UpdateLinkLBItem(hListBox, rgIndex[i], lpEL, TRUE);
+
+ // if differed only in file name, allow user to change all links
+ if (cs.lpszFrom != NULL && cs.lpszTo != NULL)
+ ChangeAllLinks(hListBox, lpOleUILinkCntr, cs.lpszFrom, cs.lpszTo);
+
+ // must free and NULL out the lpszFrom and lpszTo OUT fields
+ OleStdFree(cs.lpszFrom);
+ cs.lpszFrom = NULL;
+ OleStdFree(cs.lpszTo);
+ cs.lpszTo = NULL;
+ }
+
+ if (rgIndex != NULL)
+ OleStdFree(rgIndex);
+
+ return TRUE;
+}
+
+/*
+* Container_AutomaticManual
+*
+* Purpose:
+* To change the selected moniker to manual or automatic update.
+*
+* Parameters:
+* hDlg HWND of the dialog
+* FAutoMan Flag indicating AUTO (TRUE/1) or MANUAL(FALSE/0)
+* LPEDITLINKS Pointer to EditLinks structure (contains all nec.
+* info)
+* * this may change - don't know how the linked list
+* * of multi-selected items will work.
+* Return Value:
+* HRESULT HRESULT value indicating success or failure of
+* changing the moniker value
+*/
+
+HRESULT Container_AutomaticManual(HWND hDlg, BOOL fAutoMan, LPEDITLINKS lpEL)
+{
+ HRESULT hErr = NOERROR;
+ int cSelItems;
+ int FAR* rgIndex;
+ int i = 0;
+ LPLINKINFO lpLI;
+ LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
+ HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
+ BOOL bUpdate = FALSE;
+
+ OleDbgAssert(lpOleUILinkCntr);
+
+ /* Change so looks at flag in structure. Only update those that
+ need to be updated. Make sure to change flag if status changes.
+ */
+
+ cSelItems = GetSelectedItems(hListBox, &rgIndex);
+
+ if (cSelItems < 0)
+ return ResultFromScode(E_FAIL);
+
+ if (!cSelItems)
+ return NOERROR;
+
+ HCURSOR hCursorOld = HourGlassOn();
+
+ if (!lpEL->fClose)
+ {
+ SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
+ lpEL->fClose = TRUE;
+ }
+
+ for (i = 0; i < cSelItems; i++)
+ {
+ lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
+ if (fAutoMan)
+ {
+ // If switching to AUTOMATIC
+ if (!lpLI->fIsAuto) // Only change MANUAL links
+ {
+ OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::SetLinkUpdateOptions called\r\n"));
+ hErr=lpOleUILinkCntr->SetLinkUpdateOptions(
+ lpLI->dwLink,
+ OLEUPDATE_ALWAYS
+ );
+ OLEDBG_END2
+
+ lpLI->fIsAuto=TRUE;
+ lpLI->fIsMarked = TRUE;
+ bUpdate = TRUE;
+ }
+ }
+ else // If switching to MANUAL
+ {
+ if (lpLI->fIsAuto) // Only do AUTOMATIC Links
+ {
+ OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::SetLinkUpdateOptions called\r\n"));
+ hErr=lpOleUILinkCntr->SetLinkUpdateOptions(
+ lpLI->dwLink,
+ OLEUPDATE_ONCALL
+ );
+ OLEDBG_END2
+
+ lpLI->fIsAuto = FALSE;
+ lpLI->fIsMarked = TRUE;
+ bUpdate = TRUE;
+ }
+ }
+
+ if (hErr != NOERROR)
+ {
+ OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::SetLinkUpdateOptions returned"),hErr);
+ break;
+ }
+ }
+
+ if (bUpdate)
+ RefreshLinkLB(hListBox, lpOleUILinkCntr);
+
+ if (rgIndex)
+ OleStdFree((LPVOID)rgIndex);
+
+ HourGlassOff(hCursorOld);
+
+ return hErr;
+}
+
+HRESULT CancelLink(HWND hDlg, LPEDITLINKS lpEL)
+{
+ HRESULT hErr;
+ LPMONIKER lpmk;
+ int cSelItems;
+ int FAR* rgIndex;
+ int i = 0;
+ LPLINKINFO lpLI;
+ LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
+ HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
+ BOOL bUpdate = FALSE;
+
+ OleDbgAssert(lpOleUILinkCntr);
+
+ lpmk = NULL;
+
+ cSelItems = GetSelectedItems(hListBox, &rgIndex);
+
+ if (cSelItems < 0)
+ return ResultFromScode(E_FAIL);
+
+ if (!cSelItems)
+ return NOERROR;
+
+ HCURSOR hCursorOld = HourGlassOn();
+
+ for (i = 0; i < cSelItems; i++)
+ {
+ lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
+
+ UINT uRet = PopupMessage(hDlg, IDS_LINKS,
+ IDS_CONFIRMBREAKLINK, MB_YESNO|MB_ICONQUESTION);
+ if (uRet == IDNO)
+ break;
+
+ OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::CancelLink called\r\n"));
+ hErr = lpOleUILinkCntr->CancelLink(lpLI->dwLink);
+ OLEDBG_END2
+
+ if (!lpEL->fClose)
+ {
+ SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
+ lpEL->fClose = TRUE;
+ }
+
+ if (hErr != NOERROR)
+ {
+ OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::CancelLink returned"),hErr);
+ lpLI->fIsMarked = TRUE;
+ bUpdate = TRUE;
+ }
+ else
+ {
+ // Delete links that we make null from listbox
+ SendMessage(hListBox, LB_DELETESTRING, (WPARAM) rgIndex[i], 0L);
+ int i2;
+ for (i2 = i + 1; i2 < cSelItems; i2++)
+ {
+ if (rgIndex[i2] > rgIndex[i])
+ rgIndex[i2]--;
+ }
+ }
+ }
+
+ if (bUpdate)
+ RefreshLinkLB(hListBox, lpOleUILinkCntr);
+
+ if (rgIndex)
+ OleStdFree((LPVOID)rgIndex);
+
+ HourGlassOff(hCursorOld);
+
+ return hErr;
+}
+
+/*
+ * Container_UpdateNow
+ *
+ * Purpose:
+ * Immediately force an update for all (manual) links
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * LPEDITLINKS Pointer to EditLinks structure (contains all nec. info)
+ * * this may change - don't know how the linked list
+ * * of multi-selected items will work.
+ * Return Value:
+ * HRESULT HRESULT value indicating success or failure of
+ * changing the moniker value
+ */
+HRESULT Container_UpdateNow(HWND hDlg, LPEDITLINKS lpEL)
+{
+ HRESULT hErr;
+ LPLINKINFO lpLI;
+ int cSelItems;
+ int FAR* rgIndex;
+ int i = 0;
+ LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
+ HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
+ BOOL bUpdate = FALSE;
+
+ OleDbgAssert(lpOleUILinkCntr);
+
+ cSelItems = GetSelectedItems(hListBox, &rgIndex);
+
+ if (cSelItems < 0)
+ return ResultFromScode(E_FAIL);
+
+ if (!cSelItems)
+ return NOERROR;
+
+ HCURSOR hCursorOld = HourGlassOn();
+
+ if (!lpEL->fClose)
+ {
+ SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
+ lpEL->fClose = TRUE;
+ }
+
+ for (i = 0; i < cSelItems; i++)
+ {
+ lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[i], 0);
+
+ OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::UpdateLink called\r\n"));
+ hErr = lpOleUILinkCntr->UpdateLink(
+ lpLI->dwLink,
+ TRUE,
+ FALSE
+ );
+ OLEDBG_END2
+ bUpdate = TRUE;
+ lpLI->fIsMarked = TRUE;
+
+ if (hErr != NOERROR)
+ {
+ OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::UpdateLink returned"),hErr);
+ break;
+ }
+ }
+
+ if (bUpdate)
+ RefreshLinkLB(hListBox, lpOleUILinkCntr);
+
+ if (rgIndex)
+ OleStdFree((LPVOID)rgIndex);
+
+ HourGlassOff(hCursorOld);
+
+ return hErr;
+
+}
+
+/*
+ * Container_OpenSource
+ *
+ * Purpose:
+ * Immediately force an update for all (manual) links
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * LPEDITLINKS Pointer to EditLinks structure (contains all nec.
+ * info)
+ *
+ * Return Value:
+ * HRESULT HRESULT value indicating success or failure of
+ * changing the moniker value
+ */
+
+HRESULT Container_OpenSource(HWND hDlg, LPEDITLINKS lpEL)
+{
+ HRESULT hErr;
+ int cSelItems;
+ int FAR* rgIndex;
+ LPLINKINFO lpLI;
+ RECT rcPosRect;
+ LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
+ HWND hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
+
+ OleDbgAssert(lpOleUILinkCntr);
+
+ rcPosRect.top = 0;
+ rcPosRect.left = 0;
+ rcPosRect.right = 0;
+ rcPosRect.bottom = 0;
+
+ cSelItems = GetSelectedItems(hListBox, &rgIndex);
+
+ if (cSelItems < 0)
+ return ResultFromScode(E_FAIL);
+
+ if (cSelItems != 1) // can't open source for multiple items
+ return NOERROR;
+
+ HCURSOR hCursorOld = HourGlassOn();
+
+ if (!lpEL->fClose)
+ {
+ SetDlgItemText(hDlg, IDCANCEL, lpEL->szClose);
+ lpEL->fClose = TRUE;
+ }
+
+ lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, rgIndex[0], 0);
+
+ OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::OpenLinkSource called\r\n"));
+ hErr = lpOleUILinkCntr->OpenLinkSource(
+ lpLI->dwLink
+ );
+ OLEDBG_END2
+
+ UpdateLinkLBItem(hListBox, rgIndex[0], lpEL, TRUE);
+ if (hErr != NOERROR)
+ OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::OpenLinkSource returned"),hErr);
+
+ if (rgIndex)
+ OleStdFree((LPVOID)rgIndex);
+
+ HourGlassOff(hCursorOld);
+
+ return hErr;
+}
+
+/* AddLinkLBItem
+** -------------
+**
+** Add the item pointed to by lpLI to the Link ListBox and return
+** the index of it in the ListBox
+*/
+int AddLinkLBItem(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPLINKINFO lpLI, BOOL fGetSelected)
+{
+ HRESULT hErr;
+ DWORD dwUpdateOpt;
+ int nIndex;
+
+ OleDbgAssert(lpOleUILinkCntr && hListBox && lpLI);
+
+ lpLI->fDontFree = FALSE;
+
+ OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::GetLinkSource called\r\n"));
+ hErr = lpOleUILinkCntr->GetLinkSource(
+ lpLI->dwLink,
+ (LPTSTR FAR*)&lpLI->lpszDisplayName,
+ (ULONG FAR*)&lpLI->clenFileName,
+ (LPTSTR FAR*)&lpLI->lpszFullLinkType,
+ (LPTSTR FAR*)&lpLI->lpszShortLinkType,
+ (BOOL FAR*)&lpLI->fSourceAvailable,
+ fGetSelected ? (BOOL FAR*)&lpLI->fIsSelected : NULL
+ );
+ OLEDBG_END2
+
+ if (hErr != NOERROR)
+ {
+ OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::GetLinkSource returned"),hErr);
+ PopupMessage(hListBox, IDS_LINKS, IDS_ERR_GETLINKSOURCE,
+ MB_ICONEXCLAMATION | MB_OK);
+ goto cleanup;
+ }
+
+ OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::GetLinkUpdateOptions called\r\n"));
+ hErr=lpOleUILinkCntr->GetLinkUpdateOptions(
+ lpLI->dwLink,
+ (LPDWORD)&dwUpdateOpt
+ );
+ OLEDBG_END2
+
+ if (hErr != NOERROR)
+ {
+ OleDbgOutHResult(TEXT("WARNING: IOleUILinkContainer::GetLinkUpdateOptions returned"),hErr);
+ PopupMessage(hListBox, IDS_LINKS, IDS_ERR_GETLINKUPDATEOPTIONS,
+ MB_ICONEXCLAMATION | MB_OK);
+
+ goto cleanup;
+ }
+
+ if (lpLI->fSourceAvailable)
+ {
+ if (dwUpdateOpt == OLEUPDATE_ALWAYS)
+ {
+ lpLI->fIsAuto = TRUE;
+ LoadString(_g_hOleStdResInst, IDS_LINK_AUTO, lpLI->lpszAMX,
+ (int)OleStdGetSize((LPVOID)lpLI->lpszAMX) / sizeof (TCHAR));
+ }
+ else
+ {
+ lpLI->fIsAuto = FALSE;
+ LoadString(_g_hOleStdResInst, IDS_LINK_MANUAL, lpLI->lpszAMX,
+ (int)OleStdGetSize((LPVOID)lpLI->lpszAMX) / sizeof (TCHAR));
+ }
+ }
+ else
+ LoadString(_g_hOleStdResInst, IDS_LINK_UNKNOWN, lpLI->lpszAMX,
+ (int)OleStdGetSize((LPVOID)lpLI->lpszAMX) / sizeof (TCHAR));
+
+ BreakString(lpLI);
+
+ nIndex = (int)SendMessage(hListBox, LB_ADDSTRING, (WPARAM)0,
+ (LPARAM)(DWORD)lpLI);
+
+ if (nIndex == LB_ERR)
+ {
+ PopupMessage(hListBox, IDS_LINKS, IDS_ERR_ADDSTRING,
+ MB_ICONEXCLAMATION | MB_OK);
+ goto cleanup;
+ }
+ return nIndex;
+
+cleanup:
+ if (lpLI->lpszDisplayName)
+ OleStdFree((LPVOID)lpLI->lpszDisplayName);
+
+ if (lpLI->lpszShortLinkType)
+ OleStdFree((LPVOID)lpLI->lpszShortLinkType);
+
+ if (lpLI->lpszFullLinkType)
+ OleStdFree((LPVOID)lpLI->lpszFullLinkType);
+
+ return -1;
+}
+
+/* BreakString
+ * -----------
+ *
+ * Purpose:
+ * Break the lpszDisplayName into various parts
+ *
+ * Parameters:
+ * lpLI pointer to LINKINFO structure
+ *
+ * Returns:
+ *
+ */
+VOID BreakString(LPLINKINFO lpLI)
+{
+ LPTSTR lpsz;
+
+ if (!lpLI->clenFileName ||
+ (lstrlen(lpLI->lpszDisplayName)==(int)lpLI->clenFileName))
+ {
+ lpLI->lpszItemName = NULL;
+ }
+ else
+ {
+ lpLI->lpszItemName = lpLI->lpszDisplayName + lpLI->clenFileName;
+ }
+
+ // search from last character of filename
+ lpsz = lpLI->lpszDisplayName + lstrlen(lpLI->lpszDisplayName);
+ while (lpsz > lpLI->lpszDisplayName)
+ {
+ lpsz = CharPrev(lpLI->lpszDisplayName, lpsz);
+ if ((*lpsz == '\\') || (*lpsz == '/') || (*lpsz == ':'))
+ break;
+ }
+
+ if (lpsz == lpLI->lpszDisplayName)
+ lpLI->lpszShortFileName = lpsz;
+ else
+ lpLI->lpszShortFileName = CharNext(lpsz);
+}
+
+/* GetSelectedItems
+ * ----------------
+ *
+ * Purpose:
+ * Retrieve the indices of the selected items in the listbox
+ * Note that *lprgIndex needed to be free after using the function
+ *
+ * Parameters:
+ * hListBox window handle of listbox
+ * lprgIndex pointer to an integer array to receive the indices
+ * must be freed afterwards
+ *
+ * Returns:
+ * number of indices retrieved, -1 if error
+ */
+int GetSelectedItems(HWND hListBox, int FAR* FAR* lprgIndex)
+{
+ DWORD cSelItems;
+ DWORD cCheckItems;
+
+ *lprgIndex = NULL;
+
+ cSelItems = SendMessage(hListBox, LB_GETSELCOUNT, 0, 0L);
+ if (cSelItems < 0) // error
+ return (int)cSelItems;
+
+ if (!cSelItems)
+ return 0;
+
+ *lprgIndex = (int FAR*)OleStdMalloc((int)cSelItems * sizeof(int));
+
+ cCheckItems = SendMessage(hListBox, LB_GETSELITEMS,
+ (WPARAM) cSelItems, (LPARAM) (int FAR*) *lprgIndex);
+
+ if (cCheckItems == cSelItems)
+ return (int)cSelItems;
+ else
+ {
+ if (*lprgIndex)
+ OleStdFree((LPVOID)*lprgIndex);
+ *lprgIndex = NULL;
+ return 0;
+ }
+}
+
+/* InitControls
+ * ------------
+ *
+ * Purpose:
+ * Initialize the state of the Auto/Manual button, Link source/type
+ * static field, etc in the dialogs according to the selection in the
+ * listbox
+ *
+ * Parameters:
+ * hDlg handle to the dialog window
+ */
+VOID InitControls(HWND hDlg, LPEDITLINKS lpEL)
+{
+ int cSelItems;
+ HWND hListBox;
+ int i;
+ int FAR* rgIndex;
+ LPLINKINFO lpLI;
+ LPTSTR lpszType = NULL;
+ LPTSTR lpszSource = NULL;
+ int cAuto = 0;
+ int cManual = 0;
+ BOOL bSameType = TRUE;
+ BOOL bSameSource = TRUE;
+ TCHAR tsz[MAX_PATH];
+ LPTSTR lpsz;
+
+ hListBox = GetDlgItem(hDlg, IDC_EL_LINKSLISTBOX);
+
+ cSelItems = GetSelectedItems(hListBox, &rgIndex);
+ if (cSelItems < 0)
+ return;
+
+ StandardEnableDlgItem(hDlg, IDC_EL_AUTOMATIC, (BOOL)cSelItems);
+ StandardEnableDlgItem(hDlg, IDC_EL_MANUAL, (BOOL)cSelItems);
+ if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLECANCELLINK))
+ StandardEnableDlgItem(hDlg, IDC_EL_CANCELLINK, (BOOL)cSelItems);
+ if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLEOPENSOURCE))
+ StandardEnableDlgItem(hDlg, IDC_EL_OPENSOURCE, cSelItems == 1);
+ if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLECHANGESOURCE))
+ StandardEnableDlgItem(hDlg, IDC_EL_CHANGESOURCE, cSelItems == 1);
+ if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLEUPDATENOW))
+ StandardEnableDlgItem(hDlg, IDC_EL_UPDATENOW, (BOOL)cSelItems);
+
+ for (i = 0; i < cSelItems; i++)
+ {
+ lpLI = (LPLINKINFO)SendDlgItemMessage(hDlg, IDC_EL_LINKSLISTBOX,
+ LB_GETITEMDATA, rgIndex[i], 0);
+
+ if (lpszSource && lpLI->lpszDisplayName)
+ {
+ if (bSameSource && lstrcmp(lpszSource, lpLI->lpszDisplayName))
+ bSameSource = FALSE;
+ }
+ else
+ lpszSource = lpLI->lpszDisplayName;
+
+ if (lpszType && lpLI->lpszFullLinkType)
+ {
+ if (bSameType && lstrcmp(lpszType, lpLI->lpszFullLinkType))
+ bSameType = FALSE;
+ }
+ else
+ lpszType = lpLI->lpszFullLinkType;
+
+ if (lpLI->fIsAuto)
+ cAuto++;
+ else
+ cManual++;
+ }
+
+ CheckDlgButton(hDlg, IDC_EL_AUTOMATIC, cAuto && !cManual);
+ CheckDlgButton(hDlg, IDC_EL_MANUAL, !cAuto && cManual);
+
+ /* fill full source in static text box
+ ** below list
+ */
+ if (!bSameSource || !lpszSource)
+ lpszSource = szNULL;
+ lstrcpy(tsz, lpszSource);
+ lpsz = ChopText(GetDlgItem(hDlg, IDC_EL_LINKSOURCE), 0, tsz, 0);
+ SetDlgItemText(hDlg, IDC_EL_LINKSOURCE, lpsz);
+
+ /* fill full link type name in static
+ ** "type" text box
+ */
+ if (!bSameType || !lpszType)
+ lpszType = szNULL;
+ SetDlgItemText(hDlg, IDC_EL_LINKTYPE, lpszType);
+
+ if (rgIndex)
+ OleStdFree((LPVOID)rgIndex);
+}
+
+
+/* UpdateLinkLBItem
+ * -----------------
+ *
+ * Purpose:
+ * Update the linkinfo struct in the listbox to reflect the changes
+ * made by the last operation. It is done simply by removing the item
+ * from the listbox and add it back.
+ *
+ * Parameters:
+ * hListBox handle of listbox
+ * nIndex index of listbox item
+ * lpEL pointer to editlinks structure
+ * bSelect select the item or not after update
+ */
+VOID UpdateLinkLBItem(HWND hListBox, int nIndex, LPEDITLINKS lpEL, BOOL bSelect)
+{
+ LPLINKINFO lpLI;
+ LPOLEUILINKCONTAINER lpOleUILinkCntr;
+
+ if (!hListBox || (nIndex < 0) || !lpEL)
+ return;
+
+ lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer;
+
+ lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, nIndex, 0);
+
+ if (lpLI == NULL)
+ return;
+
+ /* Don't free the data associated with this listbox item
+ ** because we are going to reuse the allocated space for
+ ** the modified link. WM_DELETEITEM processing in the
+ ** dialog checks this flag before deleting data
+ ** associcated with list item.
+ */
+ lpLI->fDontFree = TRUE;
+ SendMessage(hListBox, LB_DELETESTRING, nIndex, 0L);
+
+ nIndex = AddLinkLBItem(hListBox, lpOleUILinkCntr, lpLI, FALSE);
+ if (bSelect)
+ {
+ SendMessage(hListBox, LB_SETSEL, TRUE, MAKELPARAM(nIndex, 0));
+ SendMessage(hListBox, LB_SETCARETINDEX, nIndex, MAKELPARAM(TRUE, 0));
+ }
+}
+
+
+
+/* ChangeAllLinks
+ * --------------
+ *
+ * Purpose:
+ * Enumerate all the links in the listbox and change those starting
+ * with lpszFrom to lpszTo.
+ *
+ * Parameters:
+ * hListBox window handle of
+ * lpOleUILinkCntr pointer to OleUI Link Container
+ * lpszFrom prefix for matching
+ * lpszTo prefix to substitution
+ *
+ * Returns:
+ */
+VOID ChangeAllLinks(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPTSTR lpszFrom, LPTSTR lpszTo)
+{
+ int cItems;
+ int nIndex;
+ int cFrom;
+ LPLINKINFO lpLI;
+ TCHAR szTmp[MAX_PATH];
+ BOOL bFound;
+
+ cFrom = lstrlen(lpszFrom);
+
+ cItems = (int)SendMessage(hListBox, LB_GETCOUNT, 0, 0L);
+ OleDbgAssert(cItems >= 0);
+
+ bFound = FALSE;
+
+#ifdef _DEBUG
+ OleDbgPrint(3, TEXT("From : "), lpszFrom, 0);
+ OleDbgPrint(3, TEXT(""), TEXT("\r\n"), 0);
+ OleDbgPrint(3, TEXT("To : "), lpszTo, 0);
+ OleDbgPrint(3, TEXT(""), TEXT("\r\n"), 0);
+#endif
+
+ for (nIndex = 0; nIndex < cItems; nIndex++)
+ {
+ lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, nIndex, 0);
+
+ // unmark the item
+ lpLI->fIsMarked = FALSE;
+
+ /* if the corresponding position for the end of lpszFrom in the
+ ** display name is not a separator. We stop comparing this
+ ** link.
+ */
+ if (!*(lpLI->lpszDisplayName + cFrom) ||
+ (*(lpLI->lpszDisplayName + cFrom) == '\\') ||
+ (*(lpLI->lpszDisplayName + cFrom) == '!'))
+ {
+ lstrcpyn(szTmp, lpLI->lpszDisplayName, cFrom + 1);
+ if (!lstrcmp(szTmp, lpszFrom))
+ {
+ HRESULT hErr;
+ int nFileLength;
+ ULONG ulDummy;
+
+ if (!bFound)
+ {
+ TCHAR szTitle[256];
+ TCHAR szMsg[256];
+ TCHAR szBuf[256];
+ int uRet;
+
+ LoadString(_g_hOleStdResInst, IDS_CHANGESOURCE, szTitle,
+ sizeof(szTitle)/sizeof(TCHAR));
+ LoadString(_g_hOleStdResInst, IDS_CHANGEADDITIONALLINKS,
+ szMsg, sizeof(szMsg)/sizeof(TCHAR));
+ wsprintf(szBuf, szMsg, lpszFrom);
+ uRet = MessageBox(hListBox, szBuf, szTitle,
+ MB_ICONQUESTION | MB_YESNO);
+ if (uRet == IDYES)
+ bFound = TRUE;
+ else
+ return;
+ }
+
+ lstrcpy(szTmp, lpszTo);
+ lstrcat(szTmp, lpLI->lpszDisplayName + cFrom);
+ nFileLength = lstrlen(szTmp) -
+ (lpLI->lpszItemName ? lstrlen(lpLI->lpszItemName) : 0);
+
+ hErr = lpOleUILinkCntr->SetLinkSource(
+ lpLI->dwLink,
+ szTmp,
+ (ULONG)nFileLength,
+ (ULONG FAR*)&ulDummy,
+ TRUE
+ );
+ if (hErr != NOERROR)
+ {
+ lpOleUILinkCntr->SetLinkSource(
+ lpLI->dwLink,
+ szTmp,
+ (ULONG)nFileLength,
+ (ULONG FAR*)&ulDummy,
+ FALSE);
+ }
+ lpLI->fIsMarked = TRUE;
+ }
+ }
+ }
+
+ /* have to do the refreshing after processing all links, otherwise
+ ** the item positions will change during the process as the
+ ** listbox stores items in order
+ */
+ if (bFound)
+ RefreshLinkLB(hListBox, lpOleUILinkCntr);
+}
+
+
+
+/* LoadLinkLB
+ * ----------
+ *
+ * Purpose:
+ * Enumerate all links from the Link Container and build up the Link
+ * ListBox
+ *
+ * Parameters:
+ * hListBox window handle of
+ * lpOleUILinkCntr pointer to OleUI Link Container
+ * lpszFrom prefix for matching
+ * lpszTo prefix to substitution
+ *
+ * Returns:
+ * number of link items loaded, -1 if error
+ */
+int LoadLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr)
+{
+ DWORD dwLink = 0;
+ LPLINKINFO lpLI;
+ int nIndex;
+ int cLinks;
+
+ cLinks = 0;
+
+ while ((dwLink = lpOleUILinkCntr->GetNextLink(dwLink)) != 0)
+ {
+ lpLI = (LPLINKINFO)OleStdMalloc(sizeof(LINKINFO));
+ if (NULL == lpLI)
+ return -1;
+
+ lpLI->fIsMarked = FALSE;
+ lpLI->fIsSelected = FALSE;
+ lpLI->fDontFree = FALSE;
+
+ lpLI->lpszAMX = (LPTSTR)OleStdMalloc((LINKTYPELEN+1)*sizeof(TCHAR));
+
+ lpLI->dwLink = dwLink;
+ cLinks++;
+ if ((nIndex = AddLinkLBItem(hListBox,lpOleUILinkCntr,lpLI,TRUE)) < 0)
+ // can't load list box
+ return -1;
+
+ if (lpLI->fIsSelected)
+ SendMessage(hListBox, LB_SETSEL, TRUE, MAKELPARAM(nIndex, 0));
+ }
+ if (SendMessage(hListBox,LB_GETSELITEMS,(WPARAM)1,(LPARAM)(int FAR*)&nIndex))
+ SendMessage(hListBox, LB_SETCARETINDEX, (WPARAM)nIndex, MAKELPARAM(TRUE, 0));
+
+ return cLinks;
+}
+
+/* RefreshLinkLB
+ * -------------
+ *
+ * Purpose:
+ * Enumerate all items in the links listbox and update those with
+ * fIsMarked set.
+ * Note that this is a time consuming routine as it keeps iterating
+ * all items in the listbox until all of them are unmarked.
+ *
+ * Parameters:
+ * hListBox window handle of listbox
+ * lpOleUILinkCntr pointer to OleUI Link Container
+ *
+ * Returns:
+ *
+ */
+VOID RefreshLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr)
+{
+ int cItems;
+ int nIndex;
+ LPLINKINFO lpLI;
+ BOOL bStop;
+
+ OleDbgAssert(hListBox);
+
+ cItems = (int)SendMessage(hListBox, LB_GETCOUNT, 0, 0L);
+ OleDbgAssert(cItems >= 0);
+
+ do
+ {
+ bStop = TRUE;
+ for (nIndex = 0; nIndex < cItems; nIndex++)
+ {
+ lpLI = (LPLINKINFO)SendMessage(hListBox, LB_GETITEMDATA, nIndex, 0);
+ if (lpLI->fIsMarked)
+ {
+ lpLI->fIsMarked = FALSE;
+ lpLI->fDontFree = TRUE;
+
+ SendMessage(hListBox, LB_DELETESTRING, nIndex, 0L);
+ nIndex=AddLinkLBItem(hListBox, lpOleUILinkCntr, lpLI, FALSE);
+ if (lpLI->fIsSelected)
+ {
+ SendMessage(hListBox, LB_SETSEL, (WPARAM)TRUE,
+ MAKELPARAM(nIndex, 0));
+ SendMessage(hListBox, LB_SETCARETINDEX, (WPARAM)nIndex,
+ MAKELPARAM(TRUE, 0));
+ }
+ bStop = FALSE;
+ break;
+ }
+ }
+ } while (!bStop);
+}
diff --git a/private/ole2ui32/mfcui/dirs b/private/ole2ui32/mfcui/dirs
new file mode 100644
index 000000000..06cd74c21
--- /dev/null
+++ b/private/ole2ui32/mfcui/dirs
@@ -0,0 +1,37 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ dirs.
+
+Abstract:
+
+ This file specifies the subdirectories of the current directory that
+ contain component makefiles.
+
+
+Author:
+
+ Drew Bliss (DrewB) 21-Dec-1993
+
+!ENDIF
+
+#
+# This is a list of all subdirectories that build required components.
+# Each subdirectory name should appear on a line by itself. The build
+# follows the order in which the subdirectories are specified.
+#
+
+DIRS= \
+ mfcuia32 \
+ mfcuiw32
+
+#
+# This is a list of all subdirectories that build optional components.
+# Each subdirectory name should appear on a line by itself. The build
+# follows the order in which the subdirectories are specified.
+#
+
+OPTIONAL_DIRS=
diff --git a/private/ole2ui32/mfcui/mfcui.cpp b/private/ole2ui32/mfcui/mfcui.cpp
new file mode 100644
index 000000000..c6043582d
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcui.cpp
@@ -0,0 +1,223 @@
+// ===========================================================================
+// File: M F C U I . C P P
+//
+// Copyright 1995 Microsoft Corporation. All Rights Reserved.
+// Microsoft Confidential
+// ===========================================================================
+#ifndef UNICODE
+
+// %%Includes: ---------------------------------------------------------------
+#include <windows.h>
+#include <ole2.h>
+#include <oledlg.h>
+
+// %%Prototypes: -------------------------------------------------------------
+STDAPI Ole2AnsiWFromA(REFIID riid, LPUNKNOWN punkWrappeeA, LPUNKNOWN *ppunkWrapperW);
+STDAPI Ole2AnsiAFromW(REFIID riid, LPUNKNOWN punkWrappeeW, LPUNKNOWN *ppunkWrapperA);
+
+
+// ---------------------------------------------------------------------------
+// %%Function: OleUIAddVerbMenu %%Reviewed: 00/00/95
+//
+// Description:
+// Wraps OleUIAddVerbMenu to OLEDLG.DLL for MFC clients, which expect to be
+// able to pass Ansi IOleObject's.
+// ---------------------------------------------------------------------------
+#undef OleUIAddVerbMenu // overrides the Ansi/Unicode macros in OLEDLG.H
+ STDAPI_(BOOL)
+OleUIAddVerbMenu(LPOLEOBJECT lpOleObjA, LPCSTR lpszShortType,
+ HMENU hMenu, UINT uPos, UINT uIDVerbMin, UINT uIDVerbMax,
+ BOOL bAddConvert, UINT idConvert, HMENU FAR *lphMenu)
+{
+ LPOLEOBJECT lpOleObjW = NULL;
+ BOOL fResult = FALSE;
+
+ // allow NULL IOleObject (OleUIAddVerbMenuA handles this by making an empty menu), but
+ // otherwise wrap the Ansi IOleObject to Unicode.
+ if (lpOleObjA == NULL ||
+ SUCCEEDED(Ole2AnsiWFromA(IID_IOleObject, (LPUNKNOWN)lpOleObjA, (LPUNKNOWN *)&lpOleObjW)))
+ {
+ fResult = OleUIAddVerbMenuA(lpOleObjW, lpszShortType, hMenu, uPos, uIDVerbMin,
+ uIDVerbMax, bAddConvert, idConvert, lphMenu);
+
+ // release the Unicode IOleObject if it was created
+ if (lpOleObjW != NULL)
+ lpOleObjW->Release();
+ }
+
+ return fResult;
+} // OleUIAddVerbMenu
+
+// ---------------------------------------------------------------------------
+// %%Function: OleUIInsertObject %%Reviewed: 00/00/95
+//
+// Description:
+// Wraps OleUIInsertObject to OLEDLG.DLL for MFC clients, which expect to be
+// able to pass Ansi IOleClientSite and IStorage in and receive Ansi interfaces
+// out in ppvObj.
+// ---------------------------------------------------------------------------
+#undef OleUIInsertObject // overrides the Ansi/Unicode macros in OLEDLG.H
+ STDAPI_(UINT)
+OleUIInsertObject(LPOLEUIINSERTOBJECTA lpio)
+{
+ LPOLECLIENTSITE lpIOleClientSiteA = NULL;
+ LPSTORAGE lpIStorageA = NULL;
+ LPVOID FAR *ppvObjA;
+ LPUNKNOWN punkObjW = NULL;
+ BOOL fCreatingObject;
+ UINT wResult;
+ HRESULT hr = S_OK;
+
+ // validate the structure superficially: let the actual function do most of the validation
+ if (!lpio)
+ return OLEUI_ERR_STRUCTURENULL;
+ if (IsBadReadPtr(lpio, sizeof(LPOLEUIINSERTOBJECTA)) ||
+ IsBadWritePtr(lpio, sizeof(LPOLEUIINSERTOBJECTA)))
+ return OLEUI_ERR_STRUCTUREINVALID;
+ if (lpio->cbStruct < sizeof(LPOLEUIINSERTOBJECTA))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+
+ if (fCreatingObject = (lpio->dwFlags & (IOF_CREATENEWOBJECT | IOF_CREATEFILEOBJECT | IOF_CREATELINKOBJECT)))
+ {
+ // verify these parameters, otherwise cleanup becomes complicated
+ if (IsBadWritePtr(lpio->ppvObj, sizeof(LPUNKNOWN)))
+ return OLEUI_IOERR_PPVOBJINVALID;
+ if (lpio->lpIOleClientSite != NULL && IsBadReadPtr(lpio->lpIOleClientSite, sizeof(IOleClientSite)))
+ return OLEUI_IOERR_LPIOLECLIENTSITEINVALID;
+ if (lpio->lpIStorage != NULL && IsBadReadPtr(lpio->lpIStorage, sizeof(IStorage)))
+ return OLEUI_IOERR_LPISTORAGEINVALID;
+
+ // save away the Ansi IOleClientSite, stuff in our Unicode one.
+ // if it's NULL, OleUIInsertObjectA() will handle the error appropriately and we'll clean up correctly, below.
+ if (lpIOleClientSiteA = lpio->lpIOleClientSite)
+ {
+ hr = Ole2AnsiWFromA(IID_IOleClientSite, (LPUNKNOWN)lpIOleClientSiteA, (LPUNKNOWN *)&lpio->lpIOleClientSite);
+ if (FAILED(hr))
+ {
+ lpio->lpIOleClientSite = lpIOleClientSiteA;
+ lpio->sc = hr;
+ return OLEUI_IOERR_SCODEHASERROR;
+ }
+ }
+
+ // save away the Ansi IStorage, stuff in our Unicode one.
+ // if it's NULL, OleUIInsertObjectA() will handle the error appropriately and we'll clean up correctly, below.
+ if (lpIStorageA = lpio->lpIStorage)
+ {
+ hr = Ole2AnsiWFromA(IID_IStorage, (LPUNKNOWN)lpIStorageA, (LPUNKNOWN *)&lpio->lpIStorage);
+ if (FAILED(hr))
+ {
+ // make sure to free the Unicode IOleClientSite which we converted above.
+ if (lpio->lpIOleClientSite)
+ {
+ lpio->lpIOleClientSite->Release();
+ lpio->lpIOleClientSite = lpIOleClientSiteA;
+ }
+ lpio->lpIStorage = lpIStorageA;
+ lpio->sc = hr;
+ return OLEUI_IOERR_SCODEHASERROR;
+ }
+ }
+
+ // save the current Ansi ppvObj, stuff in our Unicode one
+ ppvObjA = lpio->ppvObj;
+ lpio->ppvObj = (LPVOID FAR *)&punkObjW;
+ }
+
+ wResult = OleUIInsertObjectA(lpio);
+
+ // regardless of success or failure of the above call, we have to clean up the wrapping we did
+ if (fCreatingObject)
+ {
+ // return the Ansi versions of the IOleClientSite and IStorage to
+ // the structure, and release the Unicode ones
+ if (lpio->lpIOleClientSite)
+ {
+ lpio->lpIOleClientSite->Release();
+ lpio->lpIOleClientSite = lpIOleClientSiteA;
+ }
+ if (lpio->lpIStorage)
+ {
+ lpio->lpIStorage->Release();
+ lpio->lpIStorage = lpIStorageA;
+ }
+
+ // return the Ansi object pointer to the structure
+ lpio->ppvObj = ppvObjA;
+
+ // convert
+ if (punkObjW != NULL)
+ {
+ HRESULT hr;
+ // if we were creating an object and we succeeded, punkObjW must be valid and contain an interface
+ // of type iid. if not, there is a problem in OleUIInsertObjectA(), not in this code. we could assert
+ // here if this code wanted to, but wouldn't be able to properly circumvent the error anyway.
+ if (FAILED(hr = Ole2AnsiAFromW(lpio->iid, (LPUNKNOWN)punkObjW, (LPUNKNOWN *)ppvObjA)))
+ {
+ lpio->sc = hr;
+ }
+ punkObjW->Release();
+ if (lpio->sc != S_OK)
+ return OLEUI_IOERR_SCODEHASERROR;
+ }
+ }
+
+ return wResult;
+} // OleUIInsertObject
+
+// ---------------------------------------------------------------------------
+// %%Function: OleUIPasteSpecial %%Reviewed: 00/00/95
+//
+// Description:
+// Wraps OleUIPasteSpecial to OLEDLG.DLL for MFC clients, which expect to be
+// able to pass in and get back Ansi IDataObject's.
+// ---------------------------------------------------------------------------
+#undef OleUIPasteSpecial // overrides the Ansi/Unicode macros in OLEDLG.H
+ STDAPI_(UINT)
+OleUIPasteSpecial(LPOLEUIPASTESPECIALA lpps)
+{
+ LPDATAOBJECT lpSrcDataObjA;
+ UINT wResult;
+
+ // validate the structure superficially: let the actual function do most of the validation
+ if (!lpps)
+ return OLEUI_ERR_STRUCTURENULL;
+ if (IsBadReadPtr(lpps, sizeof(LPOLEUIPASTESPECIALA)) ||
+ IsBadWritePtr(lpps, sizeof(LPOLEUIPASTESPECIALA)))
+ return OLEUI_ERR_STRUCTUREINVALID;
+ if (lpps->cbStruct < sizeof(LPOLEUIPASTESPECIALA))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+ if (NULL != lpps->lpSrcDataObj && IsBadReadPtr(lpps->lpSrcDataObj, sizeof(IDataObject)))
+ return OLEUI_IOERR_SRCDATAOBJECTINVALID;
+
+ if (!(lpSrcDataObjA = lpps->lpSrcDataObj) ||
+ SUCCEEDED(Ole2AnsiWFromA(IID_IDataObject, (LPUNKNOWN)lpSrcDataObjA, (LPUNKNOWN *)&lpps->lpSrcDataObj)))
+ {
+ wResult = OleUIPasteSpecialA(lpps);
+
+ // if we had an Ansi IDataObject on entry, put it back and release the Unicode wrapper.
+ if (lpSrcDataObjA != NULL)
+ {
+ lpps->lpSrcDataObj->Release();
+ lpps->lpSrcDataObj = lpSrcDataObjA;
+ }
+ // otherwise check to see if OleUIPasteSpecialA() placed a Unicode IDataObject into our structure.
+ // if it did, wrap it to make sure an Ansi one gets sent back out.
+ else if (lpps->lpSrcDataObj != NULL)
+ {
+ if (FAILED(Ole2AnsiAFromW(IID_IDataObject, (LPUNKNOWN)lpps->lpSrcDataObj, (LPUNKNOWN *)&lpSrcDataObjA)))
+ {
+ lpps->lpSrcDataObj->Release();
+ lpps->lpSrcDataObj = NULL;
+ return OLEUI_PSERR_GETCLIPBOARDFAILED; // well, that's pretty much what happened, after all
+ }
+ lpps->lpSrcDataObj->Release();
+ lpps->lpSrcDataObj = lpSrcDataObjA;
+ }
+ }
+
+ return wResult;
+} // OleUIPasteSpecial
+
+#endif // !UNICODE
+// EOF =======================================================================
diff --git a/private/ole2ui32/mfcui/mfcuia32/makefile b/private/ole2ui32/mfcui/mfcuia32/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuia32/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ole2ui32/mfcui/mfcuia32/mfcui.rc b/private/ole2ui32/mfcui/mfcuia32/mfcui.rc
new file mode 100644
index 000000000..e2f4e019c
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuia32/mfcui.rc
@@ -0,0 +1,80 @@
+//Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+1 VERSIONINFO
+ FILEVERSION 3,0,0,0
+ PRODUCTVERSION 2,0,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Microsoft Windows(TM) OLE 2.0 User Interface Support\0"
+ VALUE "FileVersion", "3.0\0"
+ VALUE "InternalName", "MFCUIA32\0"
+ VALUE "LegalCopyright", "Copyright (C) Microsoft Corp. 1995\0"
+ VALUE "OriginalFilename", "MFCUIA32.DLL\0"
+ VALUE "ProductName", "Microsoft Windows(TM) OLE 2.0 User Interface Support\0"
+ VALUE "ProductVersion", "2.01\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/private/ole2ui32/mfcui/mfcuia32/mfcuia32.def b/private/ole2ui32/mfcui/mfcuia32/mfcuia32.def
new file mode 100644
index 000000000..e218230a1
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuia32/mfcuia32.def
@@ -0,0 +1,19 @@
+; mfcuia32.def
+; Copyright 1995 Microsoft Corporation. All Rights Reserved.
+
+DESCRIPTION 'OLE 2.0 UI Support Library.'
+
+EXPORTS
+OleUIAddVerbMenu @1
+OleUICanConvertOrActivateAs @2
+OleUIInsertObject @3
+OleUIPasteSpecial @4
+OleUIEditLinks=OleUIEditLinksA @5
+OleUIChangeIcon=OleUIChangeIconA @6
+OleUIConvert=OleUIConvertA @7
+OleUIBusy=OleUIBusyA @8
+OleUIUpdateLinks=OleUIUpdateLinksA @9
+OleUIPromptUser=OleUIPromptUserA @10
+OleUIObjectProperties=OleUIObjectPropertiesA @11
+OleUIChangeSource=OleUIChangeSourceA @12
+
diff --git a/private/ole2ui32/mfcui/mfcuia32/sources b/private/ole2ui32/mfcui/mfcuia32/sources
new file mode 100644
index 000000000..f7d2102f8
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuia32/sources
@@ -0,0 +1,52 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+
+
+!ENDIF
+
+DLLENTRY=DllMain
+
+DLLBASE=@$(BASEDIR)\PUBLIC\SDK\LIB\coffbase.txt,usermode
+
+DLLDEF=obj\*\mfcuia32.def
+
+MAJORCOMP=mfcuia32
+MINORCOMP=
+
+TARGETNAME=mfcuia32
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+C_DEFINES=-DWIN32
+TARGETTYPE=DYNLINK
+UMTYPE=windows
+
+INCLUDES=..
+
+386_OPTIMIZATION=/Oy-
+
+SOURCES= ..\mfcui.cpp \
+ mfcui.rc
+
+USE_CRTDLL=1
+
+LINKLIBS= $(BASEDIR)\public\sdk\lib\*\oledlg.lib \
+ mfcans32.lib \
+ $(BASEDIR)\public\sdk\lib\*\kernel32.lib \
+ $(BASEDIR)\public\sdk\lib\*\uuid.lib
+
+
diff --git a/private/ole2ui32/mfcui/mfcuiw32/makefile b/private/ole2ui32/mfcui/mfcuiw32/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuiw32/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ole2ui32/mfcui/mfcuiw32/mfcui.rc b/private/ole2ui32/mfcui/mfcuiw32/mfcui.rc
new file mode 100644
index 000000000..2e11ee0d7
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuiw32/mfcui.rc
@@ -0,0 +1,80 @@
+//Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+1 VERSIONINFO
+ FILEVERSION 3,0,0,0
+ PRODUCTVERSION 2,0,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Microsoft Windows(TM) OLE 2.0 User Interface Support\0"
+ VALUE "FileVersion", "3.0\0"
+ VALUE "InternalName", "MFCUIW32\0"
+ VALUE "LegalCopyright", "Copyright \251 Microsoft Corp. 1995\0"
+ VALUE "OriginalFilename", "MFCUIW32.DLL\0"
+ VALUE "ProductName", "Microsoft Windows(TM) OLE 2.0 User Interface Support\0"
+ VALUE "ProductVersion", "2.01\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/private/ole2ui32/mfcui/mfcuiw32/mfcuiw32.def b/private/ole2ui32/mfcui/mfcuiw32/mfcuiw32.def
new file mode 100644
index 000000000..39ee70590
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuiw32/mfcuiw32.def
@@ -0,0 +1,19 @@
+; mfcuiw32.def
+; Copyright 1995 Microsoft Corporation. All Rights Reserved.
+
+DESCRIPTION 'OLE 2.0 UI Support Library.'
+
+
+EXPORTS
+OleUIAddVerbMenu=OleUIAddVerbMenuW @1
+OleUICanConvertOrActivateAs @2
+OleUIInsertObject=OleUIInsertObjectW @3
+OleUIPasteSpecial=OleUIPasteSpecialW @4
+OleUIEditLinks=OleUIEditLinksW @5
+OleUIChangeIcon=OleUIChangeIconW @6
+OleUIConvert=OleUIConvertW @7
+OleUIBusy=OleUIBusyW @8
+OleUIUpdateLinks=OleUIUpdateLinksW @9
+OleUIPromptUser=OleUIPromptUserW @10
+OleUIObjectProperties=OleUIObjectPropertiesW @11
+OleUIChangeSource=OleUIChangeSourceW @12
diff --git a/private/ole2ui32/mfcui/mfcuiw32/sources b/private/ole2ui32/mfcui/mfcuiw32/sources
new file mode 100644
index 000000000..e39252b9a
--- /dev/null
+++ b/private/ole2ui32/mfcui/mfcuiw32/sources
@@ -0,0 +1,50 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+
+
+!ENDIF
+
+
+DLLENTRY=DllMain
+
+DLLBASE=@$(BASEDIR)\PUBLIC\SDK\LIB\coffbase.txt,usermode
+
+DLLDEF=obj\*\mfcuiw32.def
+
+MAJORCOMP=mfcuiw32
+MINORCOMP=
+
+TARGETNAME=mfcuiw32
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+C_DEFINES=-DWIN32 -DUNICODE
+TARGETTYPE=DYNLINK
+UMTYPE=windows
+
+INCLUDES=..
+
+386_OPTIMIZATION=/Oy-
+
+USE_CRTDLL=1
+
+SOURCES= ..\mfcui.cpp \
+ mfcui.rc
+
+LINKLIBS= $(BASEDIR)\public\sdk\lib\*\oledlg.lib \
+ $(BASEDIR)\public\sdk\lib\*\kernel32.lib
+
diff --git a/private/ole2ui32/mfcui/resource.h b/private/ole2ui32/mfcui/resource.h
new file mode 100644
index 000000000..a0484466f
--- /dev/null
+++ b/private/ole2ui32/mfcui/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by mfcui.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/private/ole2ui32/objprop.cpp b/private/ole2ui32/objprop.cpp
new file mode 100644
index 000000000..20b3cabc6
--- /dev/null
+++ b/private/ole2ui32/objprop.cpp
@@ -0,0 +1,1335 @@
+/*
+ * OBJPROP.CPP
+ *
+ * Implements the OleUIObjectProperties function which invokes the complete
+ * Object Properties dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+#include "iconbox.h"
+#include "resimage.h"
+#include <stddef.h>
+
+OLEDBGDATA
+
+// Internally used structure
+typedef struct tagGNRLPROPS
+{
+ // Keep this item first as the Standard* functions depend on it here.
+ LPOLEUIGNRLPROPS lpOGP; // Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ CLSID clsidNew; // new class ID (if conversion done)
+
+} GNRLPROPS, *PGNRLPROPS, FAR* LPGNRLPROPS;
+
+typedef struct tagVIEWPROPS
+{
+ // Keep this item first as the Standard* functions depend on it here.
+ LPOLEUIVIEWPROPS lpOVP; // Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ BOOL bIconChanged;
+ int nCurrentScale;
+ BOOL bRelativeToOrig;
+ DWORD dvAspect;
+
+} VIEWPROPS, *PVIEWPROPS, FAR* LPVIEWPROPS;
+
+typedef struct tagLINKPROPS
+{
+ // Keep this item first as the Standard* functions depend on it here.
+ LPOLEUILINKPROPS lpOLP; // Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ DWORD dwUpdate; // original update mode
+ LPTSTR lpszDisplayName;// new link source
+ ULONG nFileLength; // file name part of source
+
+} LINKPROPS, *PLINKPROPS, FAR* LPLINKPROPS;
+
+// Internal function prototypes
+// OBJPROP.CPP
+
+/*
+ * OleUIObjectProperties
+ *
+ * Purpose:
+ * Invokes the standard OLE Object Properties dialog box allowing the user
+ * to change General, View, and Link properties of an OLE object. This
+ * dialog uses the new Windows 95 tabbed dialogs.
+ *
+ * Parameters:
+ * lpOP LPOLEUIObjectProperties pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * UINT One of the following codes, indicating success or error:
+ * OLEUI_SUCCESS Success
+ * OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
+ *
+ */
+
+static UINT WINAPI ValidateObjectProperties(LPOLEUIOBJECTPROPS);
+static UINT WINAPI PrepareObjectProperties(LPOLEUIOBJECTPROPS);
+
+STDAPI_(UINT) OleUIObjectProperties(LPOLEUIOBJECTPROPS lpOP)
+{
+#ifdef UNICODE
+ return (InternalObjectProperties(lpOP, TRUE));
+#else
+ return (InternalObjectProperties(lpOP, FALSE));
+#endif
+}
+
+UINT InternalObjectProperties(LPOLEUIOBJECTPROPS lpOP, BOOL fWide)
+{
+ // Validate Parameters
+ UINT uRet = ValidateObjectProperties(lpOP);
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+ if (NULL == lpOP->lpObjInfo)
+ {
+ return(OLEUI_OPERR_OBJINFOINVALID);
+ }
+
+ if (IsBadReadPtr(lpOP->lpObjInfo, sizeof(IOleUIObjInfo)))
+ {
+ return(OLEUI_OPERR_OBJINFOINVALID);
+ }
+
+ if (lpOP->dwFlags & OPF_OBJECTISLINK)
+ {
+ if (NULL == lpOP->lpLinkInfo)
+ {
+ return(OLEUI_OPERR_LINKINFOINVALID);
+ }
+
+ if (IsBadReadPtr(lpOP->lpLinkInfo, sizeof(IOleUILinkInfo)))
+ {
+ return(OLEUI_OPERR_LINKINFOINVALID);
+ }
+ }
+
+ // Fill Missing values in lpPS
+ LPPROPSHEETHEADER lpPS = (LPPROPSHEETHEADER)lpOP->lpPS;
+ LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lpPS->ppsp;
+ uRet = PrepareObjectProperties(lpOP);
+ if (OLEUI_SUCCESS != uRet)
+ return uRet;
+
+ LPTSTR lpszShortType = NULL;
+ lpOP->lpObjInfo->GetObjectInfo(lpOP->dwObject, NULL, NULL,
+ NULL, &lpszShortType, NULL);
+ if (lpszShortType == NULL)
+ return OLEUI_ERR_OLEMEMALLOC;
+
+ TCHAR szCaption[256];
+ if (lpPS->pszCaption == NULL)
+ {
+ TCHAR szTemp[256];
+ LoadString(_g_hOleStdResInst,
+ (lpOP->dwFlags & OPF_OBJECTISLINK) ?
+ IDS_LINKOBJECTPROPERTIES : IDS_OBJECTPROPERTIES,
+ szTemp, sizeof(szTemp));
+ wsprintf(szCaption, szTemp, lpszShortType);
+#ifdef UNICODE
+ if (!fWide)
+ {
+ // We're going to actually call the ANSI version of PropertySheet,
+ // so we need to store the caption as an ANSI string.
+ lstrcpy(szTemp, szCaption);
+ WTOA((char *)szCaption, szTemp, 256);
+ }
+#endif
+ lpPS->pszCaption = szCaption;
+ }
+ OleStdFree(lpszShortType);
+ // Invoke the property sheet
+ int nResult = StandardPropertySheet(lpOP->lpPS, fWide);
+
+ // Cleanup any temporary memory allocated during the process
+ if (lpPP == NULL)
+ {
+ OleStdFree((LPVOID)lpOP->lpPS->ppsp);
+ lpOP->lpPS->ppsp = NULL;
+ }
+
+ // map PropertPage return value to OLEUI_ return code
+ if (nResult < 0)
+ uRet = OLEUI_OPERR_PROPERTYSHEET;
+ else if (nResult == 0)
+ uRet = OLEUI_CANCEL;
+ else
+ uRet = OLEUI_OK;
+
+ return uRet;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Validation code
+
+static UINT WINAPI ValidateGnrlProps(LPOLEUIGNRLPROPS lpGP)
+{
+ OleDbgAssert(lpGP != NULL);
+
+ if (lpGP->cbStruct != sizeof(OLEUIGNRLPROPS))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+ if (lpGP->lpfnHook && IsBadCodePtr((FARPROC)lpGP->lpfnHook))
+ return OLEUI_ERR_LPFNHOOKINVALID;
+
+ return OLEUI_SUCCESS;
+}
+
+static UINT WINAPI ValidateViewProps(LPOLEUIVIEWPROPS lpVP)
+{
+ OleDbgAssert(lpVP != NULL);
+
+ if (lpVP->cbStruct != sizeof(OLEUIVIEWPROPS))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+ if (lpVP->lpfnHook && IsBadCodePtr((FARPROC)lpVP->lpfnHook))
+ return OLEUI_ERR_LPFNHOOKINVALID;
+
+ return OLEUI_SUCCESS;
+}
+
+static UINT WINAPI ValidateLinkProps(LPOLEUILINKPROPS lpLP)
+{
+ OleDbgAssert(lpLP != NULL);
+
+ if (lpLP->cbStruct != sizeof(OLEUILINKPROPS))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+ if (lpLP->lpfnHook && IsBadCodePtr((FARPROC)lpLP->lpfnHook))
+ return OLEUI_ERR_LPFNHOOKINVALID;
+
+ return OLEUI_SUCCESS;
+}
+
+static UINT WINAPI ValidateObjectProperties(LPOLEUIOBJECTPROPS lpOP)
+{
+ // Validate LPOLEUIOBJECTPROPS lpOP
+ if (lpOP == NULL)
+ return OLEUI_ERR_STRUCTURENULL;
+
+ if (IsBadWritePtr(lpOP, sizeof(OLEUIOBJECTPROPS)))
+ return OLEUI_ERR_STRUCTUREINVALID;
+
+ // Validate cbStruct field of OLEUIOBJECTPROPS
+ if (lpOP->cbStruct != sizeof(OLEUIOBJECTPROPS))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+
+ // Validate "sub" property pointers
+ if (lpOP->lpGP == NULL || lpOP->lpVP == NULL ||
+ ((lpOP->dwFlags & OPF_OBJECTISLINK) && lpOP->lpLP == NULL))
+ return OLEUI_OPERR_SUBPROPNULL;
+
+ if (IsBadWritePtr(lpOP->lpGP, sizeof(OLEUIGNRLPROPS)) ||
+ IsBadWritePtr(lpOP->lpVP, sizeof(OLEUIVIEWPROPS)) ||
+ ((lpOP->dwFlags & OPF_OBJECTISLINK) &&
+ IsBadWritePtr(lpOP->lpLP, sizeof(OLEUILINKPROPS))))
+ return OLEUI_OPERR_SUBPROPINVALID;
+
+ // Validate property sheet data pointers
+ LPPROPSHEETHEADER lpPS = lpOP->lpPS;
+ if (lpPS == NULL)
+ return OLEUI_OPERR_PROPSHEETNULL;
+
+ if (IsBadWritePtr(lpPS, sizeof(PROPSHEETHEADER)))
+ return OLEUI_OPERR_PROPSHEETINVALID;
+
+ DWORD dwSize = lpPS->dwSize;
+ if (dwSize < sizeof(PROPSHEETHEADER))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+
+ // If links specified, validate "sub" link property pointer
+ if (lpOP->dwFlags & OPF_OBJECTISLINK)
+ {
+ if (lpPS->ppsp != NULL && lpPS->nPages < 3)
+ return OLEUI_OPERR_PAGESINCORRECT;
+ }
+ else
+ {
+ if (lpPS->ppsp != NULL && lpPS->nPages < 2)
+ return OLEUI_OPERR_PAGESINCORRECT;
+ }
+
+ if (lpPS->ppsp != NULL &&
+ IsBadWritePtr((PROPSHEETPAGE*)lpPS->ppsp,
+ lpPS->nPages * sizeof(PROPSHEETPAGE)))
+ {
+ return OLEUI_OPERR_INVALIDPAGES;
+ }
+
+ // not setting PSH_PROPSHEETPAGE is not supported
+ if (lpOP->dwFlags & OPF_NOFILLDEFAULT)
+ {
+ if (!(lpPS->dwFlags & PSH_PROPSHEETPAGE))
+ return OLEUI_OPERR_NOTSUPPORTED;
+ }
+ else if (lpPS->dwFlags != 0)
+ {
+ return OLEUI_OPERR_NOTSUPPORTED;
+ }
+
+ // Sanity check any pages provided
+ for (UINT nPage = 0; nPage < lpPS->nPages; nPage++)
+ {
+ LPPROPSHEETPAGE lpPP = (PROPSHEETPAGE*)&lpPS->ppsp[nPage];
+ if (lpPP->dwSize != sizeof(PROPSHEETPAGE))
+ return OLEUI_ERR_CBSTRUCTINCORRECT;
+ if (lpPP->pfnDlgProc != NULL)
+ return OLEUI_OPERR_DLGPROCNOTNULL;
+ if (lpPP->lParam != 0)
+ return OLEUI_OPERR_LPARAMNOTZERO;
+ }
+
+ // validate individual prop page structures
+ UINT uRet = ValidateGnrlProps(lpOP->lpGP);
+ if (uRet != OLEUI_SUCCESS)
+ return uRet;
+ uRet = ValidateViewProps(lpOP->lpVP);
+ if (uRet != OLEUI_SUCCESS)
+ return uRet;
+ if ((lpOP->dwFlags & OPF_OBJECTISLINK) && lpOP->lpLP != NULL)
+ {
+ uRet = ValidateLinkProps(lpOP->lpLP);
+ if (uRet != OLEUI_SUCCESS)
+ return uRet;
+ }
+
+ return OLEUI_SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// GnrlPropsDialogProc and helpers
+
+// takes a DWORD add commas etc to it and puts the result in the buffer
+LPTSTR AddCommas(DWORD dw, LPTSTR pszResult, UINT nMax)
+{
+ NUMBERFMT numberFmt;
+ numberFmt.NumDigits = 0;
+ numberFmt.LeadingZero = 0;
+
+ TCHAR szSep[5];
+ GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szSep, sizeof(szSep));
+ numberFmt.Grouping = Atol(szSep);
+ GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, sizeof(szSep));
+ numberFmt.lpDecimalSep = numberFmt.lpThousandSep = szSep;
+ numberFmt.NegativeOrder= 0;
+
+ TCHAR szTemp[64];
+ wsprintf(szTemp, TEXT("%lu"), dw);
+
+ GetNumberFormat(LOCALE_USER_DEFAULT, 0, szTemp, &numberFmt, pszResult, nMax);
+ return pszResult;
+}
+
+const short pwOrders[] = {IDS_BYTES, IDS_ORDERKB, IDS_ORDERMB, IDS_ORDERGB, IDS_ORDERTB};
+
+/* converts numbers into short formats
+ * 532 -> 523 bytes
+ * 1340 -> 1.3KB
+ * 23506 -> 23.5KB
+ * -> 2.4MB
+ * -> 5.2GB
+ */
+LPTSTR ShortSizeFormat64(__int64 dw64, LPTSTR szBuf)
+{
+ int i;
+ UINT wInt, wLen, wDec;
+ TCHAR szTemp[10], szOrder[20], szFormat[5];
+
+ if (dw64 < 1000)
+ {
+ wsprintf(szTemp, TEXT("%d"), DWORD(dw64));
+ i = 0;
+ }
+ else
+ {
+ for (i = 1; i < (sizeof(pwOrders)/sizeof(pwOrders))-1
+ && dw64 >= 1000L * 1024L; dw64 >>= 10, i++)
+ ; /* do nothing */
+
+ wInt = DWORD(dw64 >> 10);
+ AddCommas(wInt, szTemp, sizeof(szTemp)/sizeof(TCHAR));
+ wLen = lstrlen(szTemp);
+ if (wLen < 3)
+ {
+ wDec = DWORD(dw64 - (__int64)wInt * 1024L) * 1000 / 1024;
+ // At this point, wDec should be between 0 and 1000
+ // we want get the top one (or two) digits.
+ wDec /= 10;
+ if (wLen == 2)
+ wDec /= 10;
+
+ // Note that we need to set the format before getting the
+ // intl char.
+ lstrcpy(szFormat, TEXT("%02d"));
+
+ szFormat[2] = '0' + 3 - wLen;
+ GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL,
+ szTemp+wLen, sizeof(szTemp)-wLen);
+ wLen = lstrlen(szTemp);
+ wLen += wsprintf(szTemp+wLen, szFormat, wDec);
+ }
+ }
+
+ LoadString(_g_hOleStdResInst, pwOrders[i], szOrder, sizeof(szOrder));
+ wsprintf(szBuf, szOrder, (LPSTR)szTemp);
+
+ return szBuf;
+}
+
+LPTSTR WINAPI ShortSizeFormat(DWORD dw, LPTSTR szBuf)
+{
+ return ShortSizeFormat64((__int64)dw, szBuf);
+}
+
+BOOL FGnrlPropsRefresh(HWND hDlg, LPGNRLPROPS lpGP)
+{
+ // get object information and fill in default fields
+ LPOLEUIOBJECTPROPS lpOP = lpGP->lpOGP->lpOP;
+ LPOLEUIOBJINFO lpObjInfo = lpOP->lpObjInfo;
+
+ // get object's icon
+ HGLOBAL hMetaPict;
+ lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict, NULL, NULL);
+ if (hMetaPict != NULL)
+ {
+ HICON hIcon = OleUIMetafilePictExtractIcon(hMetaPict);
+ SendDlgItemMessage(hDlg, IDC_GP_OBJECTICON, STM_SETICON,
+ (WPARAM)hIcon, 0);
+ }
+ OleUIMetafilePictIconFree(hMetaPict);
+
+ // get type, short type, location, and size of object
+ DWORD dwObjSize;
+ LPTSTR lpszLabel = NULL;
+ LPTSTR lpszType = NULL;
+ LPTSTR lpszShortType = NULL;
+ LPTSTR lpszLocation = NULL;
+ lpObjInfo->GetObjectInfo(lpOP->dwObject, &dwObjSize, &lpszLabel,
+ &lpszType, &lpszShortType, &lpszLocation);
+
+ // set name, type, and size of object
+ SetDlgItemText(hDlg, IDC_GP_OBJECTNAME, lpszLabel);
+ SetDlgItemText(hDlg, IDC_GP_OBJECTTYPE, lpszType);
+ SetDlgItemText(hDlg, IDC_GP_OBJECTLOCATION, lpszLocation);
+ TCHAR szTemp[128];
+ if (dwObjSize == (DWORD)-1)
+ {
+ LoadString(_g_hOleStdResInst, IDS_OLE2UIUNKNOWN, szTemp, 64);
+ SetDlgItemText(hDlg, IDC_GP_OBJECTSIZE, szTemp);
+ }
+ else
+ {
+ // get the master formatting string
+ TCHAR szFormat[64];
+ LoadString(_g_hOleStdResInst, IDS_OBJECTSIZE, szFormat, 64);
+
+ // format the size in two ways (short, and with commas)
+ TCHAR szNum1[20], szNum2[32];
+ ShortSizeFormat(dwObjSize, szNum1);
+ AddCommas(dwObjSize, szNum2, 32);
+ FormatString2(szTemp, szFormat, szNum1, szNum2);
+
+ // set the control's text
+ SetDlgItemText(hDlg, IDC_GP_OBJECTSIZE, szTemp);
+ }
+
+ // enable/disable convert button as necessary
+ BOOL bEnable = TRUE;
+ if (lpOP->dwFlags & (OPF_OBJECTISLINK|OPF_DISABLECONVERT))
+ bEnable = FALSE;
+ else
+ {
+ CLSID clsid; WORD wFormat;
+ lpObjInfo->GetConvertInfo(lpOP->dwObject, &clsid, &wFormat, NULL, NULL, NULL);
+ bEnable = OleUICanConvertOrActivateAs(clsid, FALSE, wFormat);
+ }
+ StandardEnableDlgItem(hDlg, IDC_GP_CONVERT, bEnable);
+
+ // cleanup temporary info strings
+ OleStdFree(lpszLabel);
+ OleStdFree(lpszType);
+ OleStdFree(lpszShortType);
+ OleStdFree(lpszLocation);
+
+ return TRUE;
+}
+
+BOOL FGnrlPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ HFONT hFont;
+ LPGNRLPROPS lpGP = (LPGNRLPROPS)LpvStandardInit(hDlg, sizeof(GNRLPROPS), &hFont);
+
+ // LpvStandardInit send a termination to us already.
+ if (NULL == lpGP)
+ return FALSE;
+
+ LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
+ LPOLEUIGNRLPROPS lpOGP = (LPOLEUIGNRLPROPS)lpPP->lParam;
+ lpGP->lpOGP = lpOGP;
+ lpGP->nIDD = IDD_GNRLPROPS;
+
+ // If we got a font, send it to the necessary controls.
+ if (NULL != hFont)
+ {
+ SendDlgItemMessage(hDlg, IDC_GP_OBJECTNAME, WM_SETFONT, (WPARAM)hFont, 0L);
+ SendDlgItemMessage(hDlg, IDC_GP_OBJECTTYPE, WM_SETFONT, (WPARAM)hFont, 0L);
+ SendDlgItemMessage(hDlg, IDC_GP_OBJECTLOCATION, WM_SETFONT, (WPARAM)hFont, 0L);
+ SendDlgItemMessage(hDlg, IDC_GP_OBJECTSIZE, WM_SETFONT, (WPARAM)hFont, 0L);
+ }
+
+ // Initialize the controls
+ FGnrlPropsRefresh(hDlg, lpGP);
+
+ // Call the hook with lCustData in lParam
+ UStandardHook((PVOID)lpGP, hDlg, WM_INITDIALOG, wParam, lpOGP->lCustData);
+ return TRUE;
+}
+
+BOOL CALLBACK GnrlPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uHook = 0;
+ LPGNRLPROPS lpGP = (LPGNRLPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
+
+ // If the hook processed the message, we're done.
+ if (0 != uHook)
+ return (BOOL)uHook;
+
+ // Get pointers to important info
+ LPOLEUIGNRLPROPS lpOGP = NULL;
+ LPOLEUIOBJECTPROPS lpOP = NULL;
+ LPOLEUIOBJINFO lpObjInfo = NULL;
+ if (lpGP != NULL)
+ {
+ lpOGP = lpGP->lpOGP;
+ if (lpOGP != NULL)
+ {
+ lpObjInfo = lpOGP->lpOP->lpObjInfo;
+ lpOP = lpOGP->lpOP;
+ }
+ }
+
+ switch (iMsg)
+ {
+ case WM_INITDIALOG:
+ FGnrlPropsInit(hDlg, wParam, lParam);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_GP_CONVERT:
+ {
+ // Call up convert dialog to obtain new CLSID
+ OLEUICONVERT cv; memset(&cv, 0, sizeof(cv));
+ cv.cbStruct = sizeof(cv);
+ cv.dwFlags |= CF_CONVERTONLY;
+ if (lpOP->dwFlags & OPF_SHOWHELP)
+ cv.dwFlags |= CF_SHOWHELPBUTTON;
+ cv.clsidConvertDefault = lpGP->clsidNew;
+ cv.dvAspect = DVASPECT_CONTENT;
+ lpObjInfo->GetObjectInfo(lpOP->dwObject,
+ NULL, NULL, &cv.lpszUserType, NULL, NULL);
+ lpObjInfo->GetConvertInfo(lpOP->dwObject,
+ &cv.clsid, &cv.wFormat, &cv.clsidConvertDefault,
+ &cv.lpClsidExclude, &cv.cClsidExclude);
+ cv.fIsLinkedObject =
+ (lpOGP->lpOP->dwFlags & OPF_OBJECTISLINK);
+ if (cv.clsidConvertDefault != CLSID_NULL)
+ cv.dwFlags |= CF_SETCONVERTDEFAULT;
+ cv.hWndOwner = GetParent(GetParent(hDlg));
+
+ // allow caller to hook the convert structure
+ uHook = UStandardHook(lpGP, hDlg, uMsgConvert, 0, (LPARAM)&cv);
+ if (0 == uHook)
+ {
+ uHook = (OLEUI_OK == OleUIConvert(&cv));
+ SetFocus(hDlg);
+ }
+
+ // check to see dialog results
+ if (uHook != 0 && (cv.dwFlags & CF_SELECTCONVERTTO))
+ {
+ lpGP->clsidNew = cv.clsidNew;
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
+ }
+ }
+ return TRUE;
+ }
+ break;
+
+ case PSM_QUERYSIBLINGS:
+ SetWindowLong(hDlg, DWL_MSGRESULT, 0);
+ switch (wParam)
+ {
+ case OLEUI_QUERY_GETCLASSID:
+ *(CLSID*)lParam = lpGP->clsidNew;
+ SetWindowLong(hDlg, DWL_MSGRESULT, 1);
+ return TRUE;
+
+ case OLEUI_QUERY_LINKBROKEN:
+ FGnrlPropsRefresh(hDlg, lpGP);
+ return TRUE;
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch (((NMHDR*)lParam)->code)
+ {
+ case PSN_HELP:
+ PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_GNRLPROPS, 0));
+ break;
+ case PSN_APPLY:
+ // apply changes if changes made
+ if (lpGP->clsidNew != CLSID_NULL)
+ {
+ // convert the object -- fail the apply if convert fails
+ if (NOERROR != lpObjInfo->ConvertObject(lpOP->dwObject,
+ lpGP->clsidNew))
+ {
+ SetWindowLong(hDlg, DWL_MSGRESULT, 1);
+ return TRUE;
+ }
+ lpGP->clsidNew = CLSID_NULL;
+ }
+ SetWindowLong(hDlg, DWL_MSGRESULT, 0);
+ PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
+ return TRUE;
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ HICON hIcon = (HICON)SendDlgItemMessage(hDlg, IDC_GP_OBJECTICON,
+ STM_GETICON, 0, 0);
+ if (hIcon != NULL)
+ DestroyIcon(hIcon);
+ StandardCleanup((PVOID)lpGP, hDlg);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// ViewPropsDialogProc and helpers
+
+void EnableDisableScaleControls(LPVIEWPROPS lpVP, HWND hDlg)
+{
+ LPOLEUIVIEWPROPS lpOVP = lpVP->lpOVP;
+ BOOL bEnable = !(lpOVP->dwFlags & VPF_DISABLESCALE) &&
+ SendDlgItemMessage(hDlg, IDC_VP_ASICON, BM_GETCHECK, 0, 0) == 0;
+ StandardEnableDlgItem(hDlg, IDC_VP_SPIN, bEnable);
+ StandardEnableDlgItem(hDlg, IDC_VP_PERCENT, bEnable);
+ StandardEnableDlgItem(hDlg, IDC_VP_SCALETXT, bEnable);
+ bEnable = bEnable && !(lpOVP->dwFlags & VPF_DISABLERELATIVE);
+ StandardEnableDlgItem(hDlg, IDC_VP_RELATIVE, bEnable);
+}
+
+BOOL FViewPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ LPVIEWPROPS lpVP = (LPVIEWPROPS)LpvStandardInit(hDlg, sizeof(VIEWPROPS));
+
+ // LpvStandardInit send a termination to us already.
+ if (NULL == lpVP)
+ return FALSE;
+
+ LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
+ LPOLEUIVIEWPROPS lpOVP = (LPOLEUIVIEWPROPS)lpPP->lParam;
+ lpVP->lpOVP = lpOVP;
+ lpVP->nIDD = IDD_VIEWPROPS;
+
+ // get object information and fill in default fields
+ LPOLEUIOBJECTPROPS lpOP = lpOVP->lpOP;
+ LPOLEUIOBJINFO lpObjInfo = lpOP->lpObjInfo;
+
+ // initialize icon and scale variables
+ HGLOBAL hMetaPict;
+ DWORD dvAspect;
+ int nCurrentScale;
+ lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict,
+ &dvAspect, &nCurrentScale);
+ SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET,
+ 0, (LPARAM)hMetaPict);
+ lpVP->nCurrentScale = nCurrentScale;
+ lpVP->dvAspect = dvAspect;
+
+ // Initialize the result image
+ SendDlgItemMessage(hDlg, IDC_VP_RESULTIMAGE,
+ RIM_IMAGESET, RESULTIMAGE_EDITABLE, 0L);
+
+ // Initialize controls
+ CheckRadioButton(hDlg, IDC_VP_EDITABLE, IDC_VP_ASICON,
+ dvAspect == DVASPECT_CONTENT ? IDC_VP_EDITABLE : IDC_VP_ASICON);
+ SendDlgItemMessage(hDlg, IDC_VP_RELATIVE, BM_SETCHECK,
+ (lpOVP->dwFlags & VPF_SELECTRELATIVE) != 0, 0L);
+ if (!(lpOVP->dwFlags & VPF_DISABLESCALE))
+ SetDlgItemInt(hDlg, IDC_VP_PERCENT, nCurrentScale, FALSE);
+ lpVP->bRelativeToOrig = SendDlgItemMessage(hDlg, IDC_VP_RELATIVE,
+ BM_GETCHECK, 0, 0) != 0;
+
+ // Setup up-down control as buddy to IDC_VP_PERCENT
+ HWND hWndSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL,
+ WS_CHILD|UDS_SETBUDDYINT|UDS_ARROWKEYS|UDS_ALIGNRIGHT, 0, 0, 0, 0,
+ hDlg, (HMENU)IDC_VP_SPIN, _g_hOleStdInst, NULL);
+ if (hWndSpin != NULL)
+ {
+ SendMessage(hWndSpin, UDM_SETRANGE, 0,
+ MAKELPARAM(lpOVP->nScaleMax, lpOVP->nScaleMin));
+ SendMessage(hWndSpin, UDM_SETPOS, 0, nCurrentScale);
+ SendMessage(hWndSpin, UDM_SETBUDDY,
+ (WPARAM)GetDlgItem(hDlg, IDC_VP_PERCENT), 0);
+ ShowWindow(hWndSpin, SW_SHOW);
+ }
+ EnableDisableScaleControls(lpVP, hDlg);
+
+ // Call the hook with lCustData in lParam
+ UStandardHook((PVOID)lpVP, hDlg, WM_INITDIALOG, wParam, lpOVP->lCustData);
+ return TRUE;
+}
+
+BOOL CALLBACK ViewPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uHook = 0;
+ LPVIEWPROPS lpVP = (LPVIEWPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
+
+ // If the hook processed the message, we're done.
+ if (0 != uHook)
+ return (BOOL)uHook;
+
+ // Get pointers to important info
+ LPOLEUIVIEWPROPS lpOVP = NULL;
+ LPOLEUIOBJECTPROPS lpOP = NULL;
+ LPOLEUIOBJINFO lpObjInfo = NULL;
+ if (lpVP != NULL)
+ {
+ lpOVP = lpVP->lpOVP;
+ if (lpOVP != NULL)
+ {
+ lpObjInfo = lpOVP->lpOP->lpObjInfo;
+ lpOP = lpOVP->lpOP;
+ }
+ }
+
+ switch (iMsg)
+ {
+ case WM_INITDIALOG:
+ FViewPropsInit(hDlg, wParam, lParam);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_VP_ASICON:
+ case IDC_VP_EDITABLE:
+ EnableDisableScaleControls(lpVP, hDlg);
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
+ return TRUE;
+
+ case IDC_VP_CHANGEICON:
+ {
+ // Call up Change Icon dialog to obtain new icon
+ OLEUICHANGEICON ci; memset(&ci, 0, sizeof(ci));
+ ci.cbStruct = sizeof(ci);
+ ci.dwFlags = CIF_SELECTCURRENT;
+ ci.hWndOwner = GetParent(GetParent(hDlg));
+ ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY,
+ IBXM_IMAGEGET, 0, 0L);
+
+ // get classid to look for (may be new class if conversion applied)
+ SendMessage(GetParent(hDlg), PSM_QUERYSIBLINGS,
+ OLEUI_QUERY_GETCLASSID, (LPARAM)&ci.clsid);
+ lpObjInfo->GetConvertInfo(lpOP->dwObject,
+ &ci.clsid, NULL, NULL, NULL, NULL);
+ if (lpOP->dwFlags & OPF_SHOWHELP)
+ ci.dwFlags |= CIF_SHOWHELP;
+
+ // allow the caller to hook the change icon
+ uHook = UStandardHook(lpVP, hDlg, uMsgChangeIcon, 0, (LPARAM)&ci);
+ if (0 == uHook)
+ {
+ uHook = (OLEUI_OK == OleUIChangeIcon(&ci));
+ SetFocus(hDlg);
+ }
+ if (0 != uHook)
+ {
+ // apply the changes
+ SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET, 1,
+ (LPARAM)ci.hMetaPict);
+ lpVP->bIconChanged = TRUE;
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
+ }
+ }
+ return TRUE;
+
+ case IDC_VP_PERCENT:
+ case IDC_VP_RELATIVE:
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
+ return TRUE;
+ }
+ break;
+
+ case WM_VSCROLL:
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
+ break;
+
+ case PSM_QUERYSIBLINGS:
+ SetWindowLong(hDlg, DWL_MSGRESULT, 0);
+ switch (wParam)
+ {
+ case OLEUI_QUERY_LINKBROKEN:
+ if (!lpVP->bIconChanged)
+ {
+ // re-init icon, since user hasn't changed it
+ HGLOBAL hMetaPict;
+ lpObjInfo->GetViewInfo(lpOP->dwObject, &hMetaPict, NULL, NULL);
+ SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGESET,
+ 1, (LPARAM)hMetaPict);
+ }
+ return TRUE;
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch (((NMHDR*)lParam)->code)
+ {
+ case PSN_HELP:
+ PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_VIEWPROPS, 0));
+ break;
+ case PSN_APPLY:
+ {
+ HGLOBAL hMetaPict = NULL;
+ int nCurrentScale = -1;
+ DWORD dvAspect = (DWORD)-1;
+ BOOL bRelativeToOrig = FALSE;
+
+ // handle icon change
+ if (lpVP->bIconChanged)
+ {
+ hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
+ IDC_VP_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ lpVP->bIconChanged = FALSE;
+ }
+
+ // handle scale changes
+ if (IsWindowEnabled(GetDlgItem(hDlg, IDC_VP_PERCENT)))
+ {
+ // parse the percentage entered
+ BOOL bValid;
+ nCurrentScale = GetDlgItemInt(hDlg, IDC_VP_PERCENT, &bValid, FALSE);
+ if (!bValid)
+ {
+ PopupMessage(GetParent(hDlg), IDS_VIEWPROPS,
+ IDS_INVALIDPERCENTAGE, MB_OK|MB_ICONEXCLAMATION);
+
+ // cancel the call
+ SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
+ return TRUE;
+ }
+ // normalize range
+ int nScaleMin, nScaleMax;
+ if (lpOVP->nScaleMin > lpOVP->nScaleMax)
+ {
+ nScaleMin = lpOVP->nScaleMax;
+ nScaleMax = lpOVP->nScaleMin;
+ }
+ else
+ {
+ nScaleMin = lpOVP->nScaleMin;
+ nScaleMax = lpOVP->nScaleMax;
+ }
+ // check range for validity
+ if (nCurrentScale < nScaleMin || nCurrentScale > nScaleMax)
+ {
+ // format appropriate message
+ TCHAR szCaption[128];
+ LoadString(_g_hOleStdResInst, IDS_VIEWPROPS, szCaption, 128);
+ TCHAR szFormat[128];
+ LoadString(_g_hOleStdResInst, IDS_RANGEERROR, szFormat, 128);
+ TCHAR szTemp[256], szNum1[32], szNum2[32];
+ wsprintf(szNum1, _T("%d"), lpOVP->nScaleMin);
+ wsprintf(szNum2, _T("%d"), lpOVP->nScaleMax);
+ FormatString2(szTemp, szFormat, szNum1, szNum2);
+ MessageBox(GetParent(hDlg), szTemp, szCaption, MB_OK|MB_ICONEXCLAMATION);
+
+ // and cancel the call
+ SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
+ return TRUE;
+ }
+
+ // otherwise scale is in correct range
+ bRelativeToOrig =
+ SendDlgItemMessage(hDlg, IDC_VP_RELATIVE, BM_GETCHECK, 0, 0) != 0;
+ if (nCurrentScale != lpVP->nCurrentScale ||
+ bRelativeToOrig != lpVP->bRelativeToOrig)
+ {
+ lpVP->nCurrentScale = nCurrentScale;
+ lpVP->bRelativeToOrig = bRelativeToOrig;
+ }
+ }
+
+ // handle aspect changes
+ if (SendDlgItemMessage(hDlg, IDC_VP_ASICON, BM_GETCHECK, 0, 0L))
+ dvAspect = DVASPECT_ICON;
+ else
+ dvAspect = DVASPECT_CONTENT;
+ if (dvAspect == lpVP->dvAspect)
+ dvAspect = (DWORD)-1;
+ else
+ {
+ lpVP->dvAspect = dvAspect;
+ bRelativeToOrig = 1;
+ }
+
+ lpObjInfo->SetViewInfo(lpOP->dwObject, hMetaPict, dvAspect,
+ nCurrentScale, bRelativeToOrig);
+ }
+ SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
+ PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
+ return TRUE;
+ }
+ break;
+
+ case WM_DESTROY:
+ SendDlgItemMessage(hDlg, IDC_VP_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0);
+ StandardCleanup((PVOID)lpVP, hDlg);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// LinkPropsDialogProc and helpers
+
+static BOOL IsNullTime(const FILETIME* lpFileTime)
+{
+ FILETIME fileTimeNull = { 0, 0 };
+ return CompareFileTime(&fileTimeNull, lpFileTime) == 0;
+}
+
+static BOOL SetDlgItemDate(HWND hDlg, int nID, const FILETIME* lpFileTime)
+{
+ if (IsNullTime(lpFileTime))
+ return FALSE;
+
+ // convert UTC file time to system time
+ FILETIME localTime;
+ FileTimeToLocalFileTime(lpFileTime, &localTime);
+ SYSTEMTIME systemTime;
+ FileTimeToSystemTime(&localTime, &systemTime);
+
+ TCHAR szDate[80];
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemTime,
+ NULL, szDate, sizeof(szDate));
+
+ SetDlgItemText(hDlg, nID, szDate);
+ return TRUE;
+}
+
+static BOOL SetDlgItemTime(HWND hDlg, int nID, const FILETIME* lpFileTime)
+{
+ if (IsNullTime(lpFileTime))
+ return FALSE;
+
+ // convert UTC file time to system time
+ FILETIME localTime;
+ FileTimeToLocalFileTime(lpFileTime, &localTime);
+ SYSTEMTIME systemTime;
+ FileTimeToSystemTime(&localTime, &systemTime);
+
+ if (systemTime.wHour || systemTime.wMinute || systemTime.wSecond)
+ {
+ TCHAR szTime[80];
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systemTime,
+ NULL, szTime, sizeof(szTime));
+
+ SetDlgItemText(hDlg, nID, szTime);
+ }
+ return TRUE;
+}
+
+BOOL FLinkPropsInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ HFONT hFont;
+ LPLINKPROPS lpLP = (LPLINKPROPS)LpvStandardInit(hDlg, sizeof(LINKPROPS), &hFont);
+
+ // LpvStandardInit send a termination to us already.
+ if (NULL == lpLP)
+ return FALSE;
+
+ LPPROPSHEETPAGE lpPP = (LPPROPSHEETPAGE)lParam;
+ LPOLEUILINKPROPS lpOLP = (LPOLEUILINKPROPS)lpPP->lParam;
+ lpLP->lpOLP = lpOLP;
+ lpLP->nIDD = IDD_LINKPROPS;
+
+ // If we got a font, send it to the necessary controls.
+ if (NULL != hFont)
+ {
+ // Do this for as many controls as you need it for.
+ SendDlgItemMessage(hDlg, IDC_LP_LINKSOURCE, WM_SETFONT, (WPARAM)hFont, 0);
+ SendDlgItemMessage(hDlg, IDC_LP_DATE, WM_SETFONT, (WPARAM)hFont, 0);
+ SendDlgItemMessage(hDlg, IDC_LP_TIME, WM_SETFONT, (WPARAM)hFont, 0);
+ }
+
+ // general "Unknown" string for unknown items
+ TCHAR szUnknown[64];
+ LoadString(_g_hOleStdResInst, IDS_OLE2UIUNKNOWN, szUnknown, 64);
+
+ // get object information and fill in default fields
+ LPOLEUIOBJECTPROPS lpOP = lpOLP->lpOP;
+ LPOLEUILINKINFO lpLinkInfo = lpOP->lpLinkInfo;
+ FILETIME lastUpdate; memset(&lastUpdate, 0, sizeof(lastUpdate));
+ lpLinkInfo->GetLastUpdate(lpOP->dwLink, &lastUpdate);
+
+ // initialize time and date static text
+ if (IsNullTime(&lastUpdate))
+ {
+ // time and date are unknown
+ SetDlgItemText(hDlg, IDC_LP_DATE, szUnknown);
+ SetDlgItemText(hDlg, IDC_LP_TIME, szUnknown);
+ }
+ else
+ {
+ // time and date are known
+ SetDlgItemDate(hDlg, IDC_LP_DATE, &lastUpdate);
+ SetDlgItemTime(hDlg, IDC_LP_TIME, &lastUpdate);
+ }
+
+ // initialize source display name
+ LPTSTR lpszDisplayName;
+ lpLinkInfo->GetLinkSource(lpOP->dwLink, &lpszDisplayName,
+ &lpLP->nFileLength, NULL, NULL, NULL, NULL);
+ SetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpszDisplayName);
+ OleStdFree(lpszDisplayName);
+
+ // initialize automatic/manual update field
+ DWORD dwUpdate;
+ lpLinkInfo->GetLinkUpdateOptions(lpOP->dwLink, &dwUpdate);
+ CheckRadioButton(hDlg, IDC_LP_AUTOMATIC, IDC_LP_MANUAL,
+ dwUpdate == OLEUPDATE_ALWAYS ? IDC_LP_AUTOMATIC : IDC_LP_MANUAL);
+ lpLP->dwUpdate = dwUpdate;
+
+ // Call the hook with lCustData in lParam
+ UStandardHook((PVOID)lpLP, hDlg, WM_INITDIALOG, wParam, lpOLP->lCustData);
+ return TRUE;
+}
+
+BOOL CALLBACK LinkPropsDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT uHook = 0;
+ LPLINKPROPS lpLP = (LPLINKPROPS)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
+
+ // If the hook processed the message, we're done.
+ if (0 != uHook)
+ return (BOOL)uHook;
+
+ // Get pointers to important info
+ LPOLEUILINKPROPS lpOLP = NULL;
+ LPOLEUIOBJECTPROPS lpOP = NULL;
+ LPOLEUILINKINFO lpLinkInfo;
+ if (lpLP != NULL)
+ {
+ lpOLP = lpLP->lpOLP;
+ if (lpOLP != NULL)
+ {
+ lpLinkInfo = lpOLP->lpOP->lpLinkInfo;
+ lpOP = lpOLP->lpOP;
+ }
+ }
+
+ switch (iMsg)
+ {
+ case WM_INITDIALOG:
+ FLinkPropsInit(hDlg, wParam, lParam);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_LP_OPENSOURCE:
+ // force update
+ SendMessage(GetParent(hDlg), PSM_APPLY, 0, 0);
+
+ // launch the object
+ lpLinkInfo->OpenLinkSource(lpOP->dwLink);
+
+ // close the dialog
+ SendMessage(GetParent(hDlg), WM_COMMAND, IDOK, 0);
+ break;
+
+ case IDC_LP_UPDATENOW:
+ {
+ // force update
+ SendMessage(GetParent(hDlg), PSM_APPLY, 0, 0);
+
+ // update the link via container provided callback
+ if (lpLinkInfo->UpdateLink(lpOP->dwLink, TRUE, FALSE) != NOERROR)
+ break;
+
+ // since link was updated, update the time/date display
+ SYSTEMTIME systemTime; GetSystemTime(&systemTime);
+ FILETIME localTime; SystemTimeToFileTime(&systemTime, &localTime);
+ FILETIME lastUpdate; LocalFileTimeToFileTime(&localTime, &lastUpdate);
+ lpLinkInfo->GetLastUpdate(lpOP->dwLink, &lastUpdate);
+
+ SetDlgItemDate(hDlg, IDC_LP_DATE, &lastUpdate);
+ SetDlgItemTime(hDlg, IDC_LP_TIME, &lastUpdate);
+
+ // modification that cannot be undone
+ SendMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
+ }
+ break;
+
+ case IDC_LP_BREAKLINK:
+ {
+ UINT uRet = PopupMessage(GetParent(hDlg), IDS_LINKPROPS,
+ IDS_CONFIRMBREAKLINK, MB_YESNO|MB_ICONQUESTION);
+ if (uRet == IDYES)
+ {
+ // cancel the link turning it into a picture
+ lpLinkInfo->CancelLink(lpOP->dwLink);
+
+ // allow other pages to refresh
+ lpOP->dwFlags &= ~OPF_OBJECTISLINK;
+ SendMessage(GetParent(hDlg), PSM_QUERYSIBLINGS,
+ OLEUI_QUERY_LINKBROKEN, 0);
+
+ // remove the links page (since this is no longer a link)
+ SendMessage(GetParent(hDlg), PSM_REMOVEPAGE, 2, 0);
+
+ }
+ }
+ break;
+
+ case IDC_LP_CHANGESOURCE:
+ {
+ // get current source in OLE memory
+ UINT nLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_LP_LINKSOURCE));
+ LPTSTR lpszDisplayName = (LPTSTR)OleStdMalloc((nLen+1) * sizeof(TCHAR));
+ GetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpszDisplayName, nLen+1);
+ if (lpszDisplayName == NULL)
+ break;
+
+ // fill in the OLEUICHANGESOURCE struct
+ OLEUICHANGESOURCE cs; memset(&cs, 0, sizeof(cs));
+ cs.cbStruct = sizeof(cs);
+ cs.hWndOwner = GetParent(GetParent(hDlg));
+ cs.dwFlags = CSF_ONLYGETSOURCE;
+ if (lpOP->dwFlags & OPF_SHOWHELP)
+ cs.dwFlags |= CSF_SHOWHELP;
+ cs.lpOleUILinkContainer = lpLinkInfo;
+ cs.dwLink = lpOP->dwLink;
+ cs.lpszDisplayName = lpszDisplayName;
+ cs.nFileLength = lpLP->nFileLength;
+
+ // allow the Change Souce dialog to be hooked
+ UINT uRet = UStandardHook(lpLP, hDlg, uMsgChangeSource, 0,
+ (LPARAM)&cs);
+ if (!uRet)
+ {
+ uRet = (OLEUI_OK == OleUIChangeSource(&cs));
+ SetFocus(hDlg);
+ }
+ if (uRet)
+ {
+ OleStdFree(lpLP->lpszDisplayName);
+
+ lpLP->lpszDisplayName = cs.lpszDisplayName;
+ lpLP->nFileLength = cs.nFileLength;
+ SetDlgItemText(hDlg, IDC_LP_LINKSOURCE, lpLP->lpszDisplayName);
+
+ OleStdFree(cs.lpszTo);
+ OleStdFree(cs.lpszFrom);
+
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
+ }
+ }
+ break;
+
+ case IDC_LP_MANUAL:
+ case IDC_LP_AUTOMATIC:
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch (((NMHDR*)lParam)->code)
+ {
+ case PSN_HELP:
+ PostMessage(GetParent(GetParent(hDlg)), uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_LINKPROPS, 0));
+ break;
+ case PSN_APPLY:
+ {
+ // update link update options first
+ DWORD dwUpdate;
+ if (SendDlgItemMessage(hDlg, IDC_LP_AUTOMATIC, BM_GETCHECK, 0, 0))
+ dwUpdate = OLEUPDATE_ALWAYS;
+ else
+ dwUpdate = OLEUPDATE_ONCALL;
+ if (dwUpdate != lpLP->dwUpdate)
+ lpLinkInfo->SetLinkUpdateOptions(lpOP->dwLink, dwUpdate);
+
+ // set the link source
+ if (lpLP->lpszDisplayName != NULL)
+ {
+ // try setting with validation first
+ ULONG chEaten;
+ if (NOERROR != lpLinkInfo->SetLinkSource(lpOP->dwLink,
+ lpLP->lpszDisplayName, lpLP->nFileLength, &chEaten,
+ TRUE))
+ {
+ UINT uRet = PopupMessage(GetParent(hDlg), IDS_LINKPROPS,
+ IDS_INVALIDSOURCE, MB_ICONQUESTION|MB_YESNO);
+ if (uRet == IDYES)
+ {
+ // user wants to correct the link source
+ SetWindowLong(hDlg, DWL_MSGRESULT, 1);
+ return TRUE;
+ }
+ // user doesn't care if link source is bogus
+ lpLinkInfo->SetLinkSource(lpOP->dwLink,
+ lpLP->lpszDisplayName, lpLP->nFileLength, &chEaten,
+ FALSE);
+ }
+ OleStdFree(lpLP->lpszDisplayName);
+ lpLP->lpszDisplayName = NULL;
+ }
+ }
+ SetWindowLong(hDlg, DWL_MSGRESULT, 0);
+ PostMessage(GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0);
+ return TRUE;
+ }
+ break;
+
+ case WM_DESTROY:
+ if (lpLP != NULL)
+ {
+ OleStdFree(lpLP->lpszDisplayName);
+ lpLP->lpszDisplayName = NULL;
+ }
+ StandardCleanup((PVOID)lpLP, hDlg);
+ return TRUE;
+
+ default:
+ if (lpOP != NULL && lpOP->lpPS->hwndParent && iMsg == uMsgBrowseOFN)
+ {
+ SendMessage(lpOP->lpPS->hwndParent, uMsgBrowseOFN, wParam, lParam);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Property Page initialization code
+
+struct PROPPAGEDATA
+{
+ UINT nTemplateID;
+ UINT nTemplateID4;
+ DLGPROC pfnDlgProc;
+ size_t nPtrOffset;
+};
+
+#define PTR_OFFSET(x) offsetof(OLEUIOBJECTPROPS, x)
+static PROPPAGEDATA pageData[3] =
+{
+ { IDD_GNRLPROPS,IDD_GNRLPROPS4, GnrlPropsDialogProc, PTR_OFFSET(lpGP), },
+ { IDD_VIEWPROPS,IDD_VIEWPROPS, ViewPropsDialogProc, PTR_OFFSET(lpVP), },
+ { IDD_LINKPROPS,IDD_LINKPROPS4, LinkPropsDialogProc, PTR_OFFSET(lpLP), },
+};
+#undef PTR_OFFSET
+
+static UINT WINAPI PrepareObjectProperties(LPOLEUIOBJECTPROPS lpOP)
+{
+ // setup back pointers from page structs to sheet structs
+ lpOP->lpGP->lpOP = lpOP;
+ lpOP->lpVP->lpOP = lpOP;
+ if ((lpOP->dwFlags & OPF_OBJECTISLINK) && lpOP->lpLP != NULL)
+ lpOP->lpLP->lpOP = lpOP;
+
+ // pre-init GNRLPROPS struct
+ LPOLEUIGNRLPROPS lpGP = lpOP->lpGP;
+
+ // get ready to initialize PROPSHEET structs
+ LPPROPSHEETHEADER lpPS = lpOP->lpPS;
+ LPPROPSHEETPAGE lpPPs = (LPPROPSHEETPAGE)lpPS->ppsp;
+ UINT nMaxPage = (lpOP->dwFlags & OPF_OBJECTISLINK ? 3 : 2);
+
+ // setting OPF_NOFILLDEFAULT allows you to control almost everything
+ if (!(lpOP->dwFlags & OPF_NOFILLDEFAULT))
+ {
+ // get array of 3 PROPSHEETPAGE structs if not provided
+ if (lpPS->ppsp == NULL)
+ {
+ lpPS->nPages = nMaxPage;
+ lpPPs = (LPPROPSHEETPAGE)
+ OleStdMalloc(nMaxPage * sizeof(PROPSHEETPAGE));
+ if (lpPPs == NULL)
+ return OLEUI_ERR_OLEMEMALLOC;
+ memset(lpPPs, 0, nMaxPage * sizeof(PROPSHEETPAGE));
+ lpPS->ppsp = lpPPs;
+ }
+
+ // fill in defaults for lpPS
+ lpPS->dwFlags |= PSH_PROPSHEETPAGE;
+ if (lpPS->hInstance == NULL)
+ lpPS->hInstance = _g_hOleStdResInst;
+
+ // fill Defaults for Standard Property Pages
+ for (UINT nPage = 0; nPage < nMaxPage; nPage++)
+ {
+ LPPROPSHEETPAGE lpPP = &lpPPs[nPage];
+ PROPPAGEDATA* pPageData = &pageData[nPage];
+ if (lpPP->dwSize == 0)
+ lpPP->dwSize = sizeof(PROPSHEETPAGE);
+ if (lpPP->hInstance == NULL)
+ lpPP->hInstance = _g_hOleStdResInst;
+ UINT nIDD = bWin4 ?
+ pPageData->nTemplateID4 : pPageData->nTemplateID;
+ if (lpPP->pszTemplate == NULL)
+ lpPP->pszTemplate = MAKEINTRESOURCE(nIDD);
+ }
+ }
+
+ // fill Property Page info which cannot be overridden
+ for (UINT nPage = 0; nPage < nMaxPage; nPage++)
+ {
+ LPPROPSHEETPAGE lpPP = &lpPPs[nPage];
+ PROPPAGEDATA* pPageData = &pageData[nPage];
+ lpPP->pfnDlgProc = pPageData->pfnDlgProc;
+ lpPP->lParam = (LONG)
+ *(OLEUIGNRLPROPS**)((LPBYTE)lpOP + pPageData->nPtrOffset);
+ }
+ return OLEUI_SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/private/ole2ui32/ole2ui.cpp b/private/ole2ui32/ole2ui.cpp
new file mode 100644
index 000000000..30828b946
--- /dev/null
+++ b/private/ole2ui32/ole2ui.cpp
@@ -0,0 +1,1036 @@
+/*
+ * OLE2UI.CPP
+ *
+ * Contains initialization routines and miscellaneous API implementations for
+ * the OLE 2.0 User Interface Support Library.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+#include "resimage.h"
+#include "iconbox.h"
+#include <commdlg.h>
+#include <stdarg.h>
+
+OLEDBGDATA
+
+// Registered messages for use with all the dialogs, registered in LibMain
+UINT uMsgHelp;
+UINT uMsgEndDialog;
+UINT uMsgBrowse;
+UINT uMsgChangeIcon;
+UINT uMsgFileOKString;
+UINT uMsgCloseBusyDlg;
+UINT uMsgConvert;
+UINT uMsgChangeSource;
+UINT uMsgAddControl;
+UINT uMsgBrowseOFN;
+
+// local function prototypes
+BOOL CALLBACK PromptUserDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK UpdateLinksDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam);
+
+// local definition
+#define WM_U_UPDATELINK (WM_USER+0x2000)
+#define WM_U_SHOWWINDOW (WM_USER+0x2001)
+
+// local structure definition
+typedef struct tagUPDATELINKS
+{
+ LPOLEUILINKCONTAINER lpOleUILinkCntr; // pointer to Link Container
+ UINT cLinks; // total number of links
+ UINT cUpdated; // number of links updated
+ DWORD dwLink; // pointer to link
+ BOOL fError; // error flag
+ LPTSTR lpszTitle; // caption for dialog box
+} UPDATELINKS, *PUPDATELINKS, FAR *LPUPDATELINKS;
+
+
+/*
+ * OleUIInitialize
+ *
+ * NOTE: This function should only be called by your application IF it is
+ * using the static-link version of this library. If the DLL version is
+ * being used, this function is automatically called from the OLEDLG DLL's
+ * LibMain.
+ *
+ * Purpose:
+ * Initializes the OLE UI Library. Registers the OLE clipboard formats
+ * used in the Paste Special dialog, registers private custom window
+ * messages, and registers window classes of the "Result Image"
+ * and "Icon Box" custom controls used in the UI dialogs.
+ *
+ * Parameters:
+ *
+ * hInstance HINSTANCE of the module where the UI library resources
+ * and Dialog Procedures are contained. If you are calling
+ * this function yourself, this should be the instance handle
+ * of your application.
+ *
+ * hPrevInst HINSTANCE of the previous application instance.
+ * This is the parameter passed in to your WinMain. For
+ * the DLL version, this should always be set to zero (for
+ * WIN16 DLLs).
+ *
+ * Return Value:
+ * BOOL TRUE if initialization was successful.
+ * FALSE otherwise.
+ */
+
+#pragma code_seg(".text$initseg")
+
+BOOL bWin4; // TRUE if running Windows4 or greater
+BOOL bSharedData; // TRUE if running Win32s (it has shared data)
+
+static DWORD tlsIndex= (DWORD)-1;
+static TASKDATA taskData;
+
+STDAPI_(TASKDATA*) GetTaskData()
+{
+ TASKDATA* pData;
+ if (tlsIndex == (DWORD)-1)
+ pData = &taskData;
+ else
+ pData = (TASKDATA*)TlsGetValue(tlsIndex);
+ return pData;
+}
+
+DWORD WINAPI _AfxTlsAlloc()
+{
+ DWORD dwResult = TlsAlloc();
+ DWORD dwVersion = GetVersion();
+ if ((dwVersion & 0x80000000) && (BYTE)dwVersion <= 3)
+ {
+ while (dwResult >= 0 && dwResult <= 2)
+ dwResult = TlsAlloc();
+ }
+ return dwResult;
+}
+
+static int nInitCount;
+
+STDAPI_(BOOL) OleUIUnInitialize();
+
+STDAPI_(BOOL) OleUIInitialize(HINSTANCE hInstance,
+ HINSTANCE hPrevInst)
+{
+ OleDbgOut1(TEXT("OleUIInitialize called.\r\n"));
+
+ // Cache information about the windows version we are running
+ DWORD dwVersion = GetVersion();
+ bWin4 = LOBYTE(dwVersion) >= 4;
+ bSharedData = !bWin4 && (dwVersion & 0x80000000);
+
+ if (nInitCount == 0)
+ {
+ if (bSharedData)
+ {
+ // allocate thread local storage on Win32s
+ tlsIndex = _AfxTlsAlloc();
+ if (tlsIndex == (DWORD)-1)
+ return FALSE;
+ }
+ }
+ ++nInitCount;
+
+ // Setup process local storage if necessary
+ if (tlsIndex != (DWORD)-1)
+ {
+ void* pData = LocalAlloc(LPTR, sizeof(TASKDATA));
+ if (pData == NULL)
+ {
+ if (nInitCount == 0)
+ {
+ OleUIUnInitialize();
+ return FALSE;
+ }
+ }
+ TlsSetValue(tlsIndex, pData);
+ }
+
+ // Initialize OleStd functions
+ OleStdInitialize(hInstance, hInstance);
+
+ // Register messages we need for the dialogs.
+ uMsgHelp = RegisterWindowMessage(SZOLEUI_MSG_HELP);
+ uMsgEndDialog = RegisterWindowMessage(SZOLEUI_MSG_ENDDIALOG);
+ uMsgBrowse = RegisterWindowMessage(SZOLEUI_MSG_BROWSE);
+ uMsgChangeIcon = RegisterWindowMessage(SZOLEUI_MSG_CHANGEICON);
+ uMsgFileOKString = RegisterWindowMessage(FILEOKSTRING);
+ uMsgCloseBusyDlg = RegisterWindowMessage(SZOLEUI_MSG_CLOSEBUSYDIALOG);
+ uMsgConvert = RegisterWindowMessage(SZOLEUI_MSG_CONVERT);
+ uMsgChangeSource = RegisterWindowMessage(SZOLEUI_MSG_CHANGESOURCE);
+ uMsgAddControl = RegisterWindowMessage(SZOLEUI_MSG_ADDCONTROL);
+ uMsgBrowseOFN = RegisterWindowMessage(SZOLEUI_MSG_BROWSE_OFN);
+
+ if (!FResultImageInitialize(hInstance, hPrevInst))
+ {
+ OleDbgOut1(TEXT("OleUIInitialize: FResultImageInitialize failed. Terminating.\r\n"));
+ return 0;
+ }
+ if (!FIconBoxInitialize(hInstance, hPrevInst))
+ {
+ OleDbgOut1(TEXT("OleUIInitialize: FIconBoxInitialize failed. Terminating.\r\n"));
+ return 0;
+ }
+ return TRUE;
+}
+
+#pragma code_seg()
+
+
+/*
+ * OleUIUnInitialize
+ *
+ * NOTE: This function should only be called by your application IF it is using
+ * the static-link version of this library. If the DLL version is being used,
+ * this function is automatically called from the DLL's LibMain.
+ *
+ * Purpose:
+ * Uninitializes OLE UI libraries. Deletes any resources allocated by the
+ * library.
+ *
+ * Return Value:
+ * BOOL TRUE if successful, FALSE if not. Current implementation always
+ * returns TRUE.
+ */
+STDAPI_(BOOL) OleUIUnInitialize()
+{
+ IconBoxUninitialize();
+ ResultImageUninitialize();
+
+ // Cleanup thread local storage
+ if (tlsIndex != (DWORD)-1)
+ {
+ TASKDATA* pData = (TASKDATA*)TlsGetValue(tlsIndex);
+ TlsSetValue(tlsIndex, NULL);
+ if (pData != NULL)
+ {
+ if (pData->hInstCommCtrl != NULL)
+ FreeLibrary(pData->hInstCommCtrl);
+ if (pData->hInstShell != NULL)
+ FreeLibrary(pData->hInstShell);
+ if (pData->hInstComDlg != NULL)
+ FreeLibrary(pData->hInstComDlg);
+ LocalFree(pData);
+ }
+ }
+
+ // Last chance cleanup
+ if (nInitCount == 1)
+ {
+ // cleanup thread local storage
+ if (tlsIndex != (DWORD)-1)
+ {
+ TlsFree(tlsIndex);
+ tlsIndex = (DWORD)-1;
+ }
+ }
+ if (nInitCount != 0)
+ --nInitCount;
+
+ return TRUE;
+}
+
+
+/*
+ * OleUIAddVerbMenu
+ *
+ * Purpose:
+ * Add the Verb menu for the specified object to the given menu. If the
+ * object has one verb, we directly add the verb to the given menu. If
+ * the object has multiple verbs we create a cascading sub-menu.
+ *
+ * Parameters:
+ * lpObj LPOLEOBJECT pointing to the selected object. If this
+ * is NULL, then we create a default disabled menu item.
+ *
+ * lpszShortType LPTSTR with short type name (AuxName==2) corresponding
+ * to the lpOleObj. if the string is NOT known, then NULL
+ * may be passed. if NULL is passed, then
+ * IOleObject::GetUserType will be called to retrieve it.
+ * if the caller has the string handy, then it is faster
+ * to pass it in.
+ *
+ * hMenu HMENU in which to make modifications.
+ *
+ * uPos Position of the menu item
+ *
+ * uIDVerbMin UINT ID value at which to start the verbs.
+ * verb_0 = wIDMVerbMin + verb_0
+ * verb_1 = wIDMVerbMin + verb_1
+ * verb_2 = wIDMVerbMin + verb_2
+ * etc.
+ * uIDVerbMax UINT maximum ID value allowed for object verbs.
+ * if uIDVerbMax==0 then any ID value is allowed
+ *
+ * bAddConvert BOOL specifying whether or not to add a "Convert" item
+ * to the bottom of the menu (with a separator).
+ *
+ * idConvert UINT ID value to use for the Convert menu item, if
+ * bAddConvert is TRUE.
+ *
+ * lphMenu HMENU FAR * of the cascading verb menu if it's created.
+ * If there is only one verb, this will be filled with NULL.
+ *
+ *
+ * Return Value:
+ * BOOL TRUE if lpObj was valid and we added at least one verb
+ * to the menu. FALSE if lpObj was NULL and we created
+ * a disabled default menu item
+ */
+
+STDAPI_(BOOL) OleUIAddVerbMenu(LPOLEOBJECT lpOleObj,
+ LPCTSTR lpszShortType,
+ HMENU hMenu, UINT uPos,
+ UINT uIDVerbMin, UINT uIDVerbMax,
+ BOOL bAddConvert, UINT idConvert,
+ HMENU FAR *lphMenu)
+{
+ LPPERSISTSTORAGE lpPS=NULL;
+ LPENUMOLEVERB lpEnumOleVerb = NULL;
+ OLEVERB oleverb;
+ LPCTSTR lpszShortTypeName = lpszShortType;
+ LPTSTR lpszVerbName = NULL;
+ HRESULT hrErr;
+ BOOL fStatus;
+ BOOL fIsLink = FALSE;
+ BOOL fResult = TRUE;
+ BOOL fAddConvertItem = FALSE;
+ int cVerbs = 0;
+ UINT uFlags = MF_BYPOSITION;
+ static BOOL fFirstTime = TRUE;
+ static TCHAR szBuffer[OLEUI_OBJECTMENUMAX];
+ static TCHAR szNoObjectCmd[OLEUI_OBJECTMENUMAX];
+ static TCHAR szObjectCmd1Verb[OLEUI_OBJECTMENUMAX];
+ static TCHAR szLinkCmd1Verb[OLEUI_OBJECTMENUMAX];
+ static TCHAR szObjectCmdNVerb[OLEUI_OBJECTMENUMAX];
+ static TCHAR szLinkCmdNVerb[OLEUI_OBJECTMENUMAX];
+ static TCHAR szUnknown[OLEUI_OBJECTMENUMAX];
+ static TCHAR szEdit[OLEUI_OBJECTMENUMAX];
+ static TCHAR szConvert[OLEUI_OBJECTMENUMAX];
+
+ // Set fAddConvertItem flag
+ if (bAddConvert & (idConvert != 0))
+ fAddConvertItem = TRUE;
+
+ // only need to load the strings the 1st time
+ if (fFirstTime)
+ {
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UIEDITNOOBJCMD,
+ szNoObjectCmd, OLEUI_OBJECTMENUMAX))
+ return FALSE;
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UIEDITLINKCMD_1VERB,
+ szLinkCmd1Verb, OLEUI_OBJECTMENUMAX))
+ return FALSE;
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UIEDITOBJECTCMD_1VERB,
+ szObjectCmd1Verb, OLEUI_OBJECTMENUMAX))
+ return FALSE;
+
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UIEDITLINKCMD_NVERB,
+ szLinkCmdNVerb, OLEUI_OBJECTMENUMAX))
+ return FALSE;
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UIEDITOBJECTCMD_NVERB,
+ szObjectCmdNVerb, OLEUI_OBJECTMENUMAX))
+ return FALSE;
+
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UIUNKNOWN,
+ szUnknown, OLEUI_OBJECTMENUMAX))
+ return FALSE;
+
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UIEDIT,
+ szEdit, OLEUI_OBJECTMENUMAX))
+ return FALSE;
+
+ if (0 == LoadString(_g_hOleStdResInst, IDS_OLE2UICONVERT,
+ szConvert, OLEUI_OBJECTMENUMAX) && fAddConvertItem)
+ return FALSE;
+
+ fFirstTime = FALSE;
+ }
+
+ // Delete whatever menu may happen to be here already.
+ DeleteMenu(hMenu, uPos, uFlags);
+
+ if (lphMenu == NULL || IsBadWritePtr(lphMenu, sizeof(HMENU)))
+ {
+ goto AVMError;
+ }
+ *lphMenu=NULL;
+
+ if ((!lpOleObj) || IsBadReadPtr(lpOleObj, sizeof (IOleObject)))
+ goto AVMError;
+
+ if ((!lpszShortTypeName) || IsBadReadPtr(lpszShortTypeName, sizeof(TCHAR)))
+ {
+ // get the Short form of the user type name for the menu
+ OLEDBG_BEGIN2(TEXT("IOleObject::GetUserType called\r\n"))
+#if defined(WIN32) && !defined(UNICODE)
+ LPOLESTR wszShortTypeName = NULL;
+ lpszShortTypeName = NULL;
+ hrErr = lpOleObj->GetUserType(
+ USERCLASSTYPE_SHORT,
+ &wszShortTypeName);
+ if (NULL != wszShortTypeName)
+ {
+ UINT uLen = WTOALEN(wszShortTypeName);
+ lpszShortTypeName = (LPTSTR) OleStdMalloc(uLen);
+ if (NULL != lpszShortTypeName)
+ {
+ WTOA((char *)lpszShortTypeName, wszShortTypeName, uLen);
+ }
+ OleStdFree(wszShortTypeName);
+ }
+#else
+ hrErr = lpOleObj->GetUserType(
+ USERCLASSTYPE_SHORT,
+ (LPTSTR FAR*)&lpszShortTypeName);
+#endif
+ OLEDBG_END2
+
+ if (NOERROR != hrErr)
+ OleDbgOutHResult(TEXT("IOleObject::GetUserType returned"), hrErr);
+ }
+
+ // check if the object is a link
+ fIsLink = OleStdIsOleLink((LPUNKNOWN)lpOleObj);
+
+ // Get the verb enumerator from the OLE object
+ OLEDBG_BEGIN2(TEXT("IOleObject::EnumVerbs called\r\n"))
+ hrErr = lpOleObj->EnumVerbs(
+ (LPENUMOLEVERB FAR*)&lpEnumOleVerb
+ );
+ OLEDBG_END2
+
+ if (NOERROR != hrErr)
+ OleDbgOutHResult(TEXT("IOleObject::EnumVerbs returned"), hrErr);
+
+ if (!(*lphMenu = CreatePopupMenu()))
+ goto AVMError;
+
+ // loop through all verbs
+ while (lpEnumOleVerb != NULL)
+ {
+ hrErr = lpEnumOleVerb->Next(
+ 1,
+ (LPOLEVERB)&oleverb,
+ NULL
+ );
+ if (NOERROR != hrErr)
+ break; // DONE! no more verbs
+
+ /* OLE2NOTE: negative verb numbers and verbs that do not
+ ** indicate ONCONTAINERMENU should NOT be put on the verb menu
+ */
+ if (oleverb.lVerb < 0 ||
+ ! (oleverb.grfAttribs & OLEVERBATTRIB_ONCONTAINERMENU))
+ {
+ /* OLE2NOTE: we must still free the verb name string */
+ if (oleverb.lpszVerbName)
+ OleStdFree(oleverb.lpszVerbName);
+ continue;
+ }
+
+ // we must free the previous verb name string
+ if (lpszVerbName)
+ OleStdFree(lpszVerbName);
+
+#if defined(WIN32) && !defined(UNICODE)
+ lpszVerbName = NULL;
+ if (NULL != oleverb.lpszVerbName)
+ {
+ UINT uLen = WTOALEN(oleverb.lpszVerbName);
+ lpszVerbName = (LPTSTR) OleStdMalloc(uLen);
+ if (NULL != lpszVerbName)
+ {
+ WTOA(lpszVerbName, oleverb.lpszVerbName, uLen);
+ }
+ OleStdFree(oleverb.lpszVerbName);
+ }
+#else
+ lpszVerbName = oleverb.lpszVerbName;
+#endif
+ if ( 0 == uIDVerbMax ||
+ (uIDVerbMax >= uIDVerbMin+(UINT)oleverb.lVerb) )
+ {
+ fStatus = InsertMenu(
+ *lphMenu,
+ (UINT)-1,
+ MF_BYPOSITION | (UINT)oleverb.fuFlags,
+ uIDVerbMin+(UINT)oleverb.lVerb,
+ lpszVerbName
+ );
+ if (! fStatus)
+ goto AVMError;
+
+ cVerbs++;
+ }
+ }
+
+ // Add the separator and "Convert" menu item.
+ if (fAddConvertItem)
+ {
+ if (0 == cVerbs)
+ {
+ LPTSTR lpsz;
+
+ // if object has no verbs, then use "Convert" as the obj's verb
+ lpsz = lpszVerbName = OleStdCopyString(szConvert);
+ uIDVerbMin = idConvert;
+
+ // remove "..." from "Convert..." string; it will be added later
+ if (lpsz)
+ {
+ while(*lpsz && *lpsz != '.')
+ lpsz = CharNext(lpsz);
+ *lpsz = '\0';
+ }
+ }
+
+ if (cVerbs > 0)
+ {
+ fStatus = InsertMenu(*lphMenu,
+ (UINT)-1,
+ MF_BYPOSITION | MF_SEPARATOR,
+ (UINT)0,
+ (LPCTSTR)NULL);
+ if (! fStatus)
+ goto AVMError;
+ }
+
+ /* add convert menu */
+ fStatus = InsertMenu(*lphMenu,
+ (UINT)-1,
+ MF_BYPOSITION,
+ idConvert,
+ (LPCTSTR)szConvert);
+ if (! fStatus)
+ goto AVMError;
+
+ cVerbs++;
+ }
+
+
+ /*
+ * Build the appropriate menu based on the number of verbs found
+ *
+ */
+ if (cVerbs == 0)
+ {
+ // there are NO verbs (not even Convert...). set the menu to be
+ // "<short type> &Object/Link" and gray it out.
+ wsprintf(
+ szBuffer,
+ (fIsLink ? szLinkCmdNVerb : szObjectCmdNVerb),
+ (lpszShortTypeName ? lpszShortTypeName : TEXT(""))
+ );
+ uFlags |= MF_GRAYED;
+
+ fResult = FALSE;
+ DestroyMenu(*lphMenu);
+ *lphMenu = NULL;
+
+ }
+ else if (cVerbs == 1)
+ {
+ //One verb without Convert, one item.
+ LPTSTR lpsz = (fIsLink ? szLinkCmd1Verb : szObjectCmd1Verb);
+
+ // strip ampersands from lpszVerbName to ensure that
+ // the right character is used as the menu key
+ LPTSTR pchIn;
+ LPTSTR pchOut;
+ pchIn = pchOut = lpszVerbName;
+ while (*pchIn)
+ {
+ while (*pchIn && '&' == *pchIn)
+ {
+ pchIn++;
+ }
+ *pchOut = *pchIn;
+ pchOut++;
+ pchIn++;
+ }
+ *pchOut = 0;
+
+ FormatString2(szBuffer, lpsz, lpszVerbName, lpszShortTypeName);
+
+ // if only "verb" is "Convert..." then append the ellipses
+ if (fAddConvertItem)
+ lstrcat(szBuffer, TEXT("..."));
+
+ DestroyMenu(*lphMenu);
+ *lphMenu=NULL;
+ }
+ else
+ {
+
+ //Multiple verbs or one verb with Convert, add the cascading menu
+ wsprintf(
+ szBuffer,
+ (fIsLink ? szLinkCmdNVerb: szObjectCmdNVerb),
+ (lpszShortTypeName ? lpszShortTypeName : TEXT(""))
+ );
+ uFlags |= MF_ENABLED | MF_POPUP;
+ uIDVerbMin=(UINT)*lphMenu;
+ }
+
+ if (!InsertMenu(hMenu, uPos, uFlags, uIDVerbMin, szBuffer))
+ {
+AVMError:
+ InsertMenu(hMenu, uPos, MF_GRAYED | uFlags,
+ uIDVerbMin, szNoObjectCmd);
+ fResult = FALSE;
+ }
+
+ if (lpszVerbName)
+ OleStdFree(lpszVerbName);
+ if (!lpszShortType && lpszShortTypeName)
+ OleStdFree((LPVOID)lpszShortTypeName);
+ if (lpEnumOleVerb)
+ lpEnumOleVerb->Release();
+ return fResult;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Support for special error prompts
+
+typedef struct tagPROMPTUSER
+{
+ va_list argptr;
+ UINT nIDD; // dialog/help ID
+ LPTSTR szTitle;
+} PROMPTUSER, *PPROMPTUSER, FAR* LPPROMPTUSER;
+
+/* PromptUserDlgProc
+ * -----------------
+ *
+ * Purpose:
+ * Dialog procedure used by OleUIPromptUser(). Returns when a button is
+ * clicked in the dialog box and the button id is return.
+ *
+ * Parameters:
+ * hDlg
+ * iMsg
+ * wParam
+ * lParam
+ *
+ * Returns:
+ *
+ */
+BOOL CALLBACK PromptUserDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (iMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ SendDlgItemMessage(hDlg, IDC_PU_ICON,
+ STM_SETICON, (WPARAM)LoadIcon(NULL, IDI_EXCLAMATION), 0L);
+
+ LPPROMPTUSER lpPU = (LPPROMPTUSER)lParam;
+ SetProp(hDlg, STRUCTUREPROP, lpPU);
+ SetWindowText(hDlg, lpPU->szTitle);
+
+ TCHAR szFormat[256];
+ GetDlgItemText(hDlg, IDC_PU_TEXT, szFormat,
+ sizeof(szFormat)/sizeof(TCHAR));
+ TCHAR szBuf[256];
+ wvsprintf(szBuf, szFormat, lpPU->argptr);
+ SetDlgItemText(hDlg, IDC_PU_TEXT, szBuf);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ EndDialog(hDlg, wParam);
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIPromptUserInternal
+//
+// Synopsis: internal entry point to start the PromptUser dialog
+// Used to support both ANSI and Unicode entrypoints
+//
+// Arguments: [nTemplate] - dialog template ID
+// [szTitle] - the title string
+// [hwndParent] - the dialog's parent window
+// [arglist] - variable argument list
+//
+// History: 12-01-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+int OleUIPromptUserInternal(int nTemplate, HWND hwndParent, LPTSTR szTitle, va_list arglist)
+{
+ PROMPTUSER pu;
+ pu.szTitle = szTitle;
+ pu.argptr = arglist;
+ pu.nIDD = nTemplate;
+ return (DialogBoxParam(_g_hOleStdResInst, MAKEINTRESOURCE(nTemplate), hwndParent,
+ PromptUserDlgProc, (LPARAM)&pu));
+}
+
+/* OleUIPromptUser
+ * ---------------
+ *
+ * Purpose:
+ * Popup a dialog box with the specified template and returned the
+ * response (button id) from the user.
+ *
+ * Parameters:
+ * nTemplate resource number of the dialog
+ * hwndParent parent of the dialog box
+ * ... title of the dialog box followed by argument list
+ * for the format string in the static control
+ * (IDC_PU_TEXT) of the dialog box.
+ * The caller has to make sure that the correct number
+ * and type of argument are passed in.
+ *
+ * Returns:
+ * button id selected by the user (template dependent)
+ *
+ * Comments:
+ * the following message dialog boxes are supported:
+ *
+ * IDD_LINKSOURCEUNAVAILABLE -- Link source is unavailable
+ * VARARG Parameters:
+ * None.
+ * Used for the following error codes:
+ * OLE_E_CANT_BINDTOSOURCE
+ * STG_E_PATHNOTFOUND
+ * (sc >= MK_E_FIRST) && (sc <= MK_E_LAST) -- any Moniker error
+ * any unknown error if object is a link
+ *
+ * IDD_SERVERNOTFOUND -- server registered but NOT found
+ * VARARG Parameters:
+ * LPSTR lpszUserType -- user type name of object
+ * Used for the following error codes:
+ * CO_E_APPNOTFOUND
+ * CO_E_APPDIDNTREG
+ * any unknown error if object is an embedded object
+ *
+ * IDD_SERVERNOTREG -- server NOT registered
+ * VARARG Parameters:
+ * LPSTR lpszUserType -- user type name of object
+ * Used for the following error codes:
+ * REGDB_E_CLASSNOTREG
+ * OLE_E_STATIC -- static object with no server registered
+ *
+ * IDD_LINKTYPECHANGED -- class of link source changed since last binding
+ * VARARG Parameters:
+ * LPSTR lpszUserType -- user type name of ole link source
+ * Used for the following error codes:
+ * OLE_E_CLASSDIFF
+ *
+ * IDD_LINKTYPECHANGED -- class of link source changed since last binding
+ * VARARG Parameters:
+ * LPSTR lpszUserType -- user type name of ole link source
+ * Used for the following error codes:
+ * OLE_E_CLASSDIFF
+ *
+ * IDD_OUTOFMEMORY -- out of memory
+ * VARARG Parameters:
+ * None.
+ * Used for the following error codes:
+ * E_OUTOFMEMORY
+ *
+ */
+
+int FAR CDECL OleUIPromptUser(int nTemplate, HWND hwndParent, ...)
+{
+ va_list arglist;
+ va_start(arglist, hwndParent);
+ LPTSTR szTitle = va_arg(arglist, LPTSTR);
+ int nRet = OleUIPromptUserInternal(nTemplate, hwndParent, szTitle, arglist);
+ va_end(arglist);
+
+ return nRet;
+}
+
+/* UpdateLinksDlgProc
+ * ------------------
+ *
+ * Purpose:
+ * Dialog procedure used by OleUIUpdateLinks(). It will enumerate all
+ * all links in the container and updates all automatic links.
+ * Returns when the Stop Button is clicked in the dialog box or when all
+ * links are updated
+ *
+ * Parameters:
+ * hDlg
+ * iMsg
+ * wParam
+ * lParam pointer to the UPDATELINKS structure
+ *
+ * Returns:
+ *
+ */
+
+#define UPDATELINKS_STARTDELAY 2000 // delay before 1st link updates
+
+BOOL CALLBACK UpdateLinksDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ LPUPDATELINKS FAR* lplpUL = NULL;
+ HANDLE gh;
+ static BOOL fAbort = FALSE;
+
+ // Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ gh = RemoveProp(hDlg, STRUCTUREPROP);
+ if (NULL != gh)
+ {
+ GlobalUnlock(gh);
+ GlobalFree(gh);
+ }
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ switch (iMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ gh = GlobalAlloc(GHND, sizeof(LPUPDATELINKS));
+ SetProp(hDlg, STRUCTUREPROP, gh);
+
+ if (NULL == gh)
+ {
+ PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC,0L);
+ return FALSE;
+ }
+
+ fAbort = FALSE;
+ lplpUL = (LPUPDATELINKS FAR*)GlobalLock(gh);
+
+ if (!lplpUL)
+ {
+ PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC,0L);
+ return FALSE;
+ }
+
+ if (bWin4)
+ {
+ if (StandardInitCommonControls() >= 0)
+ {
+ // get rect of the existing "progress" control
+ RECT rect;
+ GetWindowRect(GetDlgItem(hDlg, IDC_UL_METER), &rect);
+ ScreenToClient(hDlg, ((POINT*)&rect)+0);
+ ScreenToClient(hDlg, ((POINT*)&rect)+1);
+
+ // create progress control in that rect
+ HWND hProgress = CreateWindowEx(
+ 0, PROGRESS_CLASS, NULL, WS_CHILD|WS_VISIBLE,
+ rect.left, rect.top,
+ rect.right-rect.left, rect.bottom-rect.top, hDlg,
+ (HMENU)IDC_UL_PROGRESS, _g_hOleStdInst, NULL);
+ if (hProgress != NULL)
+ {
+ // initialize the progress control
+ SendMessage(hProgress, PBM_SETRANGE, 0, MAKELONG(0, 100));
+
+ // hide the other "meter" control
+ StandardShowDlgItem(hDlg, IDC_UL_METER, SW_HIDE);
+ }
+ }
+ }
+
+ *lplpUL = (LPUPDATELINKS)lParam;
+ if ((*lplpUL)->lpszTitle)
+ {
+ SetWindowText(hDlg, (*lplpUL)->lpszTitle);
+ }
+ SetTimer(hDlg, 1, UPDATELINKS_STARTDELAY, NULL);
+ return TRUE;
+ }
+
+ case WM_TIMER:
+ KillTimer(hDlg, 1);
+ gh = GetProp(hDlg, STRUCTUREPROP);
+
+ if (NULL!=gh)
+ {
+ // gh was locked previously, lock and unlock to get lplpUL
+ lplpUL = (LPUPDATELINKS*)GlobalLock(gh);
+ GlobalUnlock(gh);
+ }
+ if (! fAbort && lplpUL)
+ PostMessage(hDlg, WM_U_UPDATELINK, 0, (LPARAM)(*lplpUL));
+ else
+ PostMessage(hDlg,uMsgEndDialog,OLEUI_CANCEL,0L);
+
+ return 0;
+
+ case WM_COMMAND: // Stop button
+ fAbort = TRUE;
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ return TRUE;
+
+ case WM_U_UPDATELINK:
+ {
+ HRESULT hErr;
+ int nPercent;
+ RECT rc;
+ TCHAR szPercent[5]; // 0% to 100%
+ HBRUSH hbr;
+ HDC hDC;
+ HWND hwndMeter;
+ MSG msg;
+ DWORD dwUpdateOpt;
+ LPUPDATELINKS lpUL = (LPUPDATELINKS)lParam;
+
+ lpUL->dwLink=lpUL->lpOleUILinkCntr->GetNextLink(lpUL->dwLink);
+
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (! IsDialogMessage(hDlg, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ if (fAbort)
+ return FALSE;
+
+ if (!lpUL->dwLink)
+ {
+ // all links processed
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ return TRUE;
+ }
+
+ hErr = lpUL->lpOleUILinkCntr->GetLinkUpdateOptions(
+ lpUL->dwLink, (LPDWORD)&dwUpdateOpt);
+
+ if ((hErr == NOERROR) && (dwUpdateOpt == OLEUPDATE_ALWAYS))
+ {
+ hErr = lpUL->lpOleUILinkCntr->UpdateLink(lpUL->dwLink, FALSE, FALSE);
+ lpUL->fError |= (hErr != NOERROR);
+ lpUL->cUpdated++;
+
+ nPercent = (lpUL->cLinks > 0) ? (lpUL->cUpdated * 100 / lpUL->cLinks) : 100;
+ if (nPercent <= 100)
+ {
+ // update percentage
+ wsprintf(szPercent, TEXT("%d%%"), nPercent);
+ SetDlgItemText(hDlg, IDC_UL_PERCENT, szPercent);
+
+ HWND hProgress = GetDlgItem(hDlg, IDC_UL_PROGRESS);
+ if (hProgress == NULL)
+ {
+ // update indicator
+ hwndMeter = GetDlgItem(hDlg, IDC_UL_METER);
+ GetClientRect(hwndMeter, (LPRECT)&rc);
+ InflateRect((LPRECT)&rc, -1, -1);
+ rc.right = (rc.right - rc.left) * nPercent / 100 + rc.left;
+ hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
+ if (hbr)
+ {
+ hDC = GetDC(hwndMeter);
+ if (hDC)
+ {
+ FillRect(hDC, (LPRECT)&rc, hbr);
+ ReleaseDC(hwndMeter, hDC);
+ }
+ DeleteObject(hbr);
+ }
+ }
+ else
+ {
+ // update the progress indicator
+ SendMessage(hProgress, PBM_SETPOS, nPercent, 0);
+ }
+ }
+ }
+
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (! IsDialogMessage(hDlg, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ PostMessage(hDlg, WM_U_UPDATELINK, 0, lParam);
+ }
+ return TRUE;
+
+ case WM_U_SHOWWINDOW:
+ ShowWindow(hDlg, SW_SHOW);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* OleUIUpdateLinkS
+ * ----------------
+ *
+ * Purpose:
+ * Update all links in the Link Container and popup a dialog box which
+ * shows the progress of the updating.
+ * The process is stopped when the user press Stop button or when all
+ * links are processed.
+ *
+ * Parameters:
+ * lpOleUILinkCntr pointer to Link Container
+ * hwndParent parent window of the dialog
+ * lpszTitle title of the dialog box
+ * cLinks total number of links
+ *
+ * Returns:
+ * TRUE all links updated successfully or user aborted dialog
+ * FALSE oherwise
+ */
+STDAPI_(BOOL) OleUIUpdateLinks(
+ LPOLEUILINKCONTAINER lpOleUILinkCntr, HWND hwndParent, LPTSTR lpszTitle, int cLinks)
+{
+ LPUPDATELINKS lpUL = (LPUPDATELINKS)OleStdMalloc(sizeof(UPDATELINKS));
+ BOOL fError = TRUE;
+
+
+ // Validate interface.
+ if (NULL == lpOleUILinkCntr || IsBadReadPtr(lpOleUILinkCntr, sizeof(IOleUILinkContainer)))
+ goto Error;
+
+
+ // Validate parent-window handle. NULL is considered valid.
+ if (NULL != hwndParent && !IsWindow(hwndParent))
+ goto Error;
+
+ // Validate the dialog title. NULL is considered valid.
+ if (NULL != lpszTitle && IsBadReadPtr(lpszTitle, 1))
+ goto Error;
+
+ if (cLinks < 0)
+ goto Error;
+
+ OleDbgAssert(lpOleUILinkCntr && hwndParent && lpszTitle && (cLinks>0));
+ OleDbgAssert(lpUL);
+
+ lpUL->lpOleUILinkCntr = lpOleUILinkCntr;
+ lpUL->cLinks = cLinks;
+ lpUL->cUpdated = 0;
+ lpUL->dwLink = 0;
+ lpUL->fError = FALSE;
+ lpUL->lpszTitle = lpszTitle;
+
+ DialogBoxParam(_g_hOleStdResInst, MAKEINTRESOURCE(IDD_UPDATELINKS),
+ hwndParent, UpdateLinksDlgProc, (LPARAM)lpUL);
+
+ fError = lpUL->fError;
+Error:
+ OleStdFree((LPVOID)lpUL);
+
+ return !fError;
+}
diff --git a/private/ole2ui32/ole2ui.rc b/private/ole2ui32/ole2ui.rc
new file mode 100644
index 000000000..315eccec9
--- /dev/null
+++ b/private/ole2ui32/ole2ui.rc
@@ -0,0 +1,254 @@
+//Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+#include "winuser.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "oledlg.dlg"
+
+IDB_RESULTSEGA BITMAP MOVEABLE PURE "res\\egares.bmp"
+IDB_RESULTSVGA BITMAP MOVEABLE PURE "res\\vgares.bmp"
+IDB_RESULTSHIRESVGA BITMAP MOVEABLE PURE "res\\hivgares.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+#ifdef WIN32
+#include <windows.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DLL
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "Microsoft Windows(TM) OLE 2.0 User Interface Support"
+#define VER_FILEVERSION_STR "1.0"
+#undef VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR "Microsoft Windows(TM) OLE 2.0 User Interface Support"
+#undef VER_PRODUCTVERSION_STR
+#define VER_PRODUCTVERSION_STR "2.01"
+#define VER_INTERNALNAME_STR "OLEDLG"
+#define VER_ORIGINALFILENAME_STR "OLEDLG.DLL"
+
+#include "common.ver"
+
+#else
+
+
+1 VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 2,0,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Microsoft Windows(TM) OLE 2.0 User Interface Support\0"
+ VALUE "FileVersion", "1.0\0"
+ VALUE "InternalName", "OLEDLG\0"
+ VALUE "LegalCopyright", "Copyright (C) Microsoft Corp. 1995\0"
+ VALUE "OriginalFilename", "OLEDLG.DLL\0"
+ VALUE "ProductName", "Microsoft Windows(TM) OLE 2.0 User Interface Support\0"
+ VALUE "ProductVersion", "2.01\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+#endif
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "#include ""dlgs.h""\r\n"
+ "#include ""oledlg.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""res/ole2ui.rc2""\r\n"
+ "\0"
+END
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_FILTERS "All Files (*.*)|*.*|"
+ IDS_ICONFILTERS "Icon Files|*.exe;*.dll;*.ico|Programs (*.exe)|*.exe|Libraries (*.dll)|*.dll|Icons (*.ico)|*.ico|All Files (*.*)|*.*|"
+ IDS_BROWSE "Browse"
+ IDS_OCX_FILTERS "OLE Controls (*.ocx)|*.ocx|Libraries (*.dll)|*.dll|All Files (*.*)|*.*|"
+ IDS_INSERT "Insert"
+ IDS_CHNGSRCOKBUTTON "OK"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_IORESULTNEW "Inserts a new %s object into your document."
+ IDS_IORESULTNEWICON "Inserts a new %s object into your document. It will be displayed as an icon."
+ IDS_IORESULTFROMFILE1 "Inserts the contents of the file as an object into your document so that you may activate it using the "
+ IDS_IORESULTFROMFILE2 "program which created it."
+ IDS_IORESULTFROMFILEICON2
+ "program which created it. It will be displayed as an icon."
+ IDS_IORESULTLINKFILE1 "Inserts a picture of the file contents into your document. The picture will be linked to "
+ IDS_IORESULTLINKFILE2 "the file so that changes to the file will be reflected in your document."
+ IDS_IORESULTLINKFILEICON1
+ "Inserts a shortcut which represents the file. The shortcut will be linked to "
+ IDS_IORESULTLINKFILEICON2
+ "the file so that changes to the file will be reflected in your document."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_CINOICONSINFILE "There are no icons in %s."
+ IDS_CIINVALIDFILE "File %s does not exist."
+ IDS_CIFILEACCESS "Unable to open file %s. Access denied."
+ IDS_CIFILESHARE "Unable to open file %s. Sharing violation."
+ IDS_CIFILEOPENFAIL "Unable to open file %s. General failure."
+ IDS_OLE2UIUNKNOWN "Unknown"
+ IDS_OLE2UILINK "Link"
+ IDS_OLE2UIOBJECT "Object"
+ IDS_OLE2UIEDIT "&Edit"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_CVRESULTCONVERTLINK "A linked object must be converted at the source."
+ IDS_CVRESULTCONVERTTO "Permanently changes the selected %1 object to a %2 object."
+ IDS_CVRESULTNOCHANGE "The selected %s object will not be converted."
+ IDS_CVRESULTDISPLAYASICON " It will be displayed as an icon."
+ IDS_CVRESULTACTIVATEAS "Every %1 object will be activated as a %2 object"
+ IDS_CVRESULTACTIVATEDIFF ", but it will not be converted."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PSPASTEDATA "Inserts the contents of the clipboard into your document as %s."
+ IDS_PSPASTEOBJECT "Inserts the contents of the clipboard into your document so that you may activate it using %s."
+ IDS_PSPASTEOBJECTASICON "Inserts the contents of the clipboard into your document so that you may activate it using %s. It will be displayed as an icon."
+ IDS_PSPASTELINKDATA "Inserts the contents of the clipboard into your document as %s. The data is linked to the source file so that changes to the file will be reflected in your document."
+ IDS_PSPASTELINKOBJECT "Inserts a picture of the clipboard contents into your document. The picure is linked to the source file so that changes to the file will be reflected in your document."
+ IDS_PSPASTELINKOBJECTASICON
+ "Inserts a shortcut which points to the location of the clipboard contents. The shortcut is linked to the source file so that changes to the file will be reflected in your document."
+ IDS_PSNONOLE "Inserts the contents of the clipboard into your document."
+ IDS_PSUNKNOWNTYPE "Unknown Type"
+ IDS_PSUNKNOWNSRC "Unknown Source"
+ IDS_PSUNKNOWNAPP "the program which created it"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+#ifdef CHICO
+ IDS_BZRESULTTEXTBUSY "This action cannot be completed because the ""%1"" program is busy. Click the appropriate button on the task bar to activate the program and correct the problem."
+ IDS_BZRESULTTEXTNOTRESPONDING
+ "This action cannot be completed because the ""%1"" program is not responding. Click the appropriate button on the task bar to activate the program and correct the problem."
+#else
+ IDS_BZRESULTTEXTBUSY "This action cannot be completed because the ""%1"" program is busy. Choose ""Switch To"" and correct the problem."
+ IDS_BZRESULTTEXTNOTRESPONDING
+ "This action cannot be completed because the ""%1"" program is not responding. Choose ""Switch To"" and correct the problem."
+#endif
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_OLESTDNOCREATEFILE "Could not create file!"
+ IDS_OLESTDNOOPENFILE "Could not open file!"
+ IDS_OLESTDDISKFULL "Disk full--unable to complete save operation"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_OLE2UICONVERT "&Convert..."
+ IDS_OLE2UIEDITLINKCMD_1VERB "%1 Linked %2 &Object"
+ IDS_OLE2UIEDITOBJECTCMD_1VERB "%1 %2 &Object"
+ IDS_OLE2UIEDITLINKCMD_NVERB "Linked %s &Object"
+ IDS_OLE2UIEDITOBJECTCMD_NVERB "%s &Object"
+ IDS_OLE2UIEDITNOOBJCMD "&Object"
+ IDS_DEFICONLABEL "Document"
+ IDS_OLE2UIPASTELINKEDTYPE "Linked %s"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_LINK_AUTO "Automatic"
+ IDS_LINK_MANUAL "Manual"
+ IDS_LINK_UNKNOWN "Unavail"
+ IDS_LINKS "Links"
+ IDS_FAILED "Operation failed!"
+ IDS_CHANGESOURCE "Change Source"
+ IDS_INVALIDSOURCE "Invalid Source : Do you want to correct it?"
+ IDS_ERR_GETLINKSOURCE "Fail to get source of the link!"
+ IDS_ERR_GETLINKUPDATEOPTIONS "Fail to get update option of the link!"
+ IDS_ERR_ADDSTRING "Fail to add item to ListBox!"
+ IDS_CHANGEADDITIONALLINKS
+ "The selected link has been changed.\nThis document contains additional links to\n%s.\n\nChange additional links?"
+ IDS_CLOSE "Close"
+ IDS_OBJECTPROPERTIES "%s Properties"
+ IDS_LINKOBJECTPROPERTIES "Linked %s Properties"
+ IDS_LINKPROPS "Link Properties"
+ IDS_CONFIRMBREAKLINK "Breaking a link will disconnect it from its link source. Are you sure you want to break this link?"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_BYTES """%s bytes"""
+ IDS_ORDERKB "%sKB"
+ IDS_ORDERMB "%sMB"
+ IDS_ORDERGB "%sGB"
+ IDS_ORDERTB "%sTB"
+ IDS_OBJECTSIZE "%1 (%2 bytes)"
+ IDS_CANNOTLOADOCX "Unable to load the requested OLE control."
+ IDS_NODLLREGISTERSERVER "The file does not appear to be a valid OLE control module. Unable to register the OLE control."
+ IDS_DLLREGISTERFAILED "The OLE control module failed to register correctly."
+ IDS_ADDCONTROL "Add Control"
+ IDS_RANGEERROR "The scaling factor specified is not in the correct range. Valid scaling factors are between %1 and %2."
+ IDS_INVALIDPERCENTAGE "The scaling factor specified is not a valid positive integer."
+ IDS_VIEWPROPS "View Properties"
+END
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "res/ole2ui.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/private/ole2ui32/oledlg.def b/private/ole2ui32/oledlg.def
new file mode 100644
index 000000000..dea30fe8f
--- /dev/null
+++ b/private/ole2ui32/oledlg.def
@@ -0,0 +1,46 @@
+;///////////////////////////////////////////////////////////////////////////
+;
+; ole2ui.def
+;
+; Definition file for oledlg.dll
+; c) Copyright Microsoft Corp. 1992 - 1994 All Rights Reserved
+;
+
+DESCRIPTION 'OLEDLG - OLE 2 Common Dialog Support Library.'
+EXPORTS
+
+; Narrow APIs:
+
+; OLE Menu APIs
+OleUIAddVerbMenuA @1
+OleUICanConvertOrActivateAs @2
+
+; OLE Common Dialog APIs
+OleUIInsertObjectA @3
+OleUIPasteSpecialA @4
+OleUIEditLinksA @5
+OleUIChangeIconA @6
+OleUIConvertA @7
+OleUIBusyA @8
+OleUIUpdateLinksA @9
+OleUIPromptUserA @10
+OleUIObjectPropertiesA @11
+OleUIChangeSourceA @12
+
+; Wide APIs:
+
+; OLE Menu APIs
+OleUIAddVerbMenuW
+
+; OLE Common Dialog APIs
+OleUIInsertObjectW
+OleUIPasteSpecialW
+OleUIEditLinksW
+OleUIChangeIconW
+OleUIConvertW
+OleUIBusyW
+OleUIUpdateLinksW
+OleUIPromptUserW
+OleUIObjectPropertiesW
+OleUIChangeSourceW
+
diff --git a/private/ole2ui32/oledlgs.h b/private/ole2ui32/oledlgs.h
new file mode 100644
index 000000000..d93b62cb9
--- /dev/null
+++ b/private/ole2ui32/oledlgs.h
@@ -0,0 +1,170 @@
+/*++ BUILD Version: 0002 Increment this if a change has global effects
+
+Copyright (c) 1993-1995, Microsoft Corporation
+
+Module Name:
+
+ oledlgs.h
+
+Abstract:
+
+ Resource ID identifiers for the OLE common dialog boxes.
+
+--*/
+
+// Help Button Identifier
+#define IDC_OLEUIHELP 99
+
+// Insert Object Dialog identifiers
+#define IDC_IO_CREATENEW 2100
+#define IDC_IO_CREATEFROMFILE 2101
+#define IDC_IO_INSERTCONTROL 2102
+#define IDC_IO_LINKFILE 2103
+#define IDC_IO_OBJECTTYPELIST 2104
+#define IDC_IO_DISPLAYASICON 2105
+#define IDC_IO_CHANGEICON 2106
+#define IDC_IO_FILE 2107
+#define IDC_IO_FILEDISPLAY 2108
+#define IDC_IO_RESULTIMAGE 2109
+#define IDC_IO_RESULTTEXT 2110
+#define IDC_IO_ICONDISPLAY 2111
+#define IDC_IO_OBJECTTYPETEXT 2112
+#define IDC_IO_FILETEXT 2113
+#define IDC_IO_FILETYPE 2114
+#define IDC_IO_ADDCONTROL 2115
+#define IDC_IO_CONTROLTYPELIST 2116
+
+// Paste Special Dialog identifiers
+#define IDC_PS_PASTE 500
+#define IDC_PS_PASTELINK 501
+#define IDC_PS_SOURCETEXT 502
+#define IDC_PS_PASTELIST 503 //{{NOHELP}}
+#define IDC_PS_PASTELINKLIST 504 //{{NOHELP}}
+#define IDC_PS_DISPLAYLIST 505
+#define IDC_PS_DISPLAYASICON 506
+#define IDC_PS_ICONDISPLAY 507
+#define IDC_PS_CHANGEICON 508
+#define IDC_PS_RESULTIMAGE 509
+#define IDC_PS_RESULTTEXT 510
+
+// Change Icon Dialog identifiers
+#define IDC_CI_GROUP 120 //{{NOHELP}}
+#define IDC_CI_CURRENT 121
+#define IDC_CI_CURRENTICON 122
+#define IDC_CI_DEFAULT 123
+#define IDC_CI_DEFAULTICON 124
+#define IDC_CI_FROMFILE 125
+#define IDC_CI_FROMFILEEDIT 126
+#define IDC_CI_ICONLIST 127
+#define IDC_CI_LABEL 128 //{{NOHELP}
+#define IDC_CI_LABELEDIT 129
+#define IDC_CI_BROWSE 130
+#define IDC_CI_ICONDISPLAY 131
+
+// Convert Dialog identifiers
+#define IDC_CV_OBJECTTYPE 150
+#define IDC_CV_DISPLAYASICON 152
+#define IDC_CV_CHANGEICON 153
+#define IDC_CV_ACTIVATELIST 154
+#define IDC_CV_CONVERTTO 155
+#define IDC_CV_ACTIVATEAS 156
+#define IDC_CV_RESULTTEXT 157
+#define IDC_CV_CONVERTLIST 158
+#define IDC_CV_ICONDISPLAY 165
+
+// Edit Links Dialog identifiers
+#define IDC_EL_CHANGESOURCE 201
+#define IDC_EL_AUTOMATIC 202
+#define IDC_EL_CANCELLINK 209
+#define IDC_EL_UPDATENOW 210
+#define IDC_EL_OPENSOURCE 211
+#define IDC_EL_MANUAL 212
+#define IDC_EL_LINKSOURCE 216
+#define IDC_EL_LINKTYPE 217
+#define IDC_EL_LINKSLISTBOX 206
+#define IDC_EL_COL1 220
+#define IDC_EL_COL2 221
+#define IDC_EL_COL3 222
+
+// Busy dialog identifiers
+#define IDC_BZ_RETRY 600
+#define IDC_BZ_ICON 601
+#define IDC_BZ_MESSAGE1 602 //{{NOHELP}}
+#define IDC_BZ_SWITCHTO 604
+
+// Update Links dialog identifiers
+#define IDC_UL_METER 1029 //{{NOHELP}}
+#define IDC_UL_STOP 1030 //{{NOHELP}}
+#define IDC_UL_PERCENT 1031 //{{NOHELP}}
+#define IDC_UL_PROGRESS 1032 //{{NOHELP}}
+
+// User Prompt dialog identifiers
+#define IDC_PU_LINKS 900 //{{NOHELP}}
+#define IDC_PU_TEXT 901 //{{NOHELP}}
+#define IDC_PU_CONVERT 902 //{{NOHELP}}
+#define IDC_PU_ICON 908 //{{NOHELP}}
+
+// General Properties identifiers
+#define IDC_GP_OBJECTNAME 1009
+#define IDC_GP_OBJECTTYPE 1010
+#define IDC_GP_OBJECTSIZE 1011
+#define IDC_GP_CONVERT 1013
+#define IDC_GP_OBJECTICON 1014 //{{NOHELP}}
+#define IDC_GP_OBJECTLOCATION 1022
+
+// View Properties identifiers
+#define IDC_VP_PERCENT 1000
+#define IDC_VP_CHANGEICON 1001
+#define IDC_VP_EDITABLE 1002
+#define IDC_VP_ASICON 1003
+#define IDC_VP_RELATIVE 1005
+#define IDC_VP_SPIN 1006
+#define IDC_VP_SCALETXT 1034
+#define IDC_VP_ICONDISPLAY 1021
+#define IDC_VP_RESULTIMAGE 1033
+
+// Link Properties identifiers
+#define IDC_LP_OPENSOURCE 1006
+#define IDC_LP_UPDATENOW 1007
+#define IDC_LP_BREAKLINK 1008
+#define IDC_LP_LINKSOURCE 1012
+#define IDC_LP_CHANGESOURCE 1015
+#define IDC_LP_AUTOMATIC 1016
+#define IDC_LP_MANUAL 1017
+#define IDC_LP_DATE 1018
+#define IDC_LP_TIME 1019
+
+// Dialog Identifiers as passed in Help messages to identify the source.
+#define IDD_INSERTOBJECT 1000
+#define IDD_CHANGEICON 1001
+#define IDD_CONVERT 1002
+#define IDD_PASTESPECIAL 1003
+#define IDD_EDITLINKS 1004
+#define IDD_BUSY 1006
+#define IDD_UPDATELINKS 1007
+#define IDD_CHANGESOURCE 1009
+#define IDD_INSERTFILEBROWSE 1010
+#define IDD_CHANGEICONBROWSE 1011
+#define IDD_CONVERTONLY 1012
+#define IDD_CHANGESOURCE4 1013
+#define IDD_GNRLPROPS 1100
+#define IDD_VIEWPROPS 1101
+#define IDD_LINKPROPS 1102
+
+// The following Dialogs are message dialogs used by OleUIPromptUser API
+#define IDD_CANNOTUPDATELINK 1008
+#define IDD_LINKSOURCEUNAVAILABLE 1020
+#define IDD_SERVERNOTFOUND 1023
+#define IDD_OUTOFMEMORY 1024
+#define IDD_SERVERNOTREGW 1021
+#define IDD_LINKTYPECHANGEDW 1022
+#define IDD_SERVERNOTREGA 1025
+#define IDD_LINKTYPECHANGEDA 1026
+#ifdef UNICODE
+#define IDD_SERVERNOTREG IDD_SERVERNOTREGW
+#define IDD_LINKTYPECHANGED IDD_LINKTYPECHANGEDW
+#else
+#define IDD_SERVERNOTREG IDD_SERVERNOTREGA
+#define IDD_LINKTYPECHANGED IDD_LINKTYPECHANGEDA
+#endif
+/////////////////////////////////////////////////////////////////////////////
diff --git a/private/ole2ui32/olestd.cpp b/private/ole2ui32/olestd.cpp
new file mode 100644
index 000000000..0701b6c54
--- /dev/null
+++ b/private/ole2ui32/olestd.cpp
@@ -0,0 +1,816 @@
+/*************************************************************************
+**
+** OLE 2 Standard Utilities
+**
+** olestd.c
+**
+** This file contains utilities that are useful for most standard
+** OLE 2.0 compound document type applications.
+**
+** (c) Copyright Microsoft Corp. 1992 All Rights Reserved
+**
+*************************************************************************/
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+#include <stdlib.h>
+#include <shellapi.h>
+#include <wchar.h>
+
+OLEDBGDATA
+
+#ifdef _DEBUG
+static TCHAR szAssertMemAlloc[] = TEXT("CoGetMalloc failed");
+#endif
+
+static int IsCloseFormatEtc(FORMATETC FAR* pFetcLeft, FORMATETC FAR* pFetcRight);
+
+/* OleStdInitialize
+** ----------------
+** Call to initialize this library sample code
+**
+*/
+
+UINT _g_cfObjectDescriptor;
+UINT _g_cfLinkSrcDescriptor;
+UINT _g_cfEmbedSource;
+UINT _g_cfEmbeddedObject;
+UINT _g_cfLinkSource;
+UINT _g_cfOwnerLink;
+UINT _g_cfFileName;
+UINT _g_cfFileNameW;
+
+HINSTANCE _g_hOleStdInst;
+HINSTANCE _g_hOleStdResInst;
+
+#pragma code_seg(".text$initseg")
+
+STDAPI_(void) OleStdInitialize(HINSTANCE hInstance, HINSTANCE hResInstance)
+{
+ _g_hOleStdInst = hInstance;
+ _g_hOleStdResInst = hResInstance ? hResInstance : hInstance;
+
+ _g_cfObjectDescriptor = RegisterClipboardFormat(CF_OBJECTDESCRIPTOR);
+ _g_cfLinkSrcDescriptor = RegisterClipboardFormat(CF_LINKSRCDESCRIPTOR);
+ _g_cfEmbedSource = RegisterClipboardFormat(CF_EMBEDSOURCE);
+ _g_cfEmbeddedObject = RegisterClipboardFormat(CF_EMBEDDEDOBJECT);
+ _g_cfLinkSource = RegisterClipboardFormat(CF_LINKSOURCE);
+ _g_cfOwnerLink = RegisterClipboardFormat(CF_OWNERLINK);
+ _g_cfFileName = RegisterClipboardFormat(CF_FILENAME);
+ _g_cfFileNameW = RegisterClipboardFormat(CF_FILENAMEW);
+}
+
+#pragma code_seg()
+
+/* OleStdIsOleLink
+** ---------------
+** Returns TRUE if the OleObject is infact an OLE link object. this
+** checks if IOleLink interface is supported. if so, the object is a
+** link, otherwise not.
+*/
+STDAPI_(BOOL) OleStdIsOleLink(LPUNKNOWN lpUnk)
+{
+ LPUNKNOWN lpOleLink;
+ lpOleLink = OleStdQueryInterface(lpUnk, IID_IOleLink);
+ if (lpOleLink)
+ {
+ OleStdRelease(lpOleLink);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* OleStdQueryInterface
+** --------------------
+** Returns the desired interface pointer if exposed by the given object.
+** Returns NULL if the interface is not available.
+** eg.:
+** lpDataObj = OleStdQueryInterface(lpOleObj, &IID_DataObject);
+*/
+STDAPI_(LPUNKNOWN) OleStdQueryInterface(LPUNKNOWN lpUnk, REFIID riid)
+{
+ LPUNKNOWN lpInterface;
+ HRESULT hrErr;
+
+ hrErr = lpUnk->QueryInterface(
+ riid,
+ (LPVOID FAR*)&lpInterface
+ );
+
+ if (hrErr == NOERROR)
+ return lpInterface;
+ else
+ return NULL;
+}
+
+
+/* OleStdGetData
+** -------------
+** Retrieve data from an IDataObject in a specified format on a
+** global memory block. This function ALWAYS returns a private copy
+** of the data to the caller. if necessary a copy is made of the
+** data (ie. if lpMedium->pUnkForRelease != NULL). The caller assumes
+** ownership of the data block in all cases and must free the data
+** when done with it. The caller may directly free the data handle
+** returned (taking care whether it is a simple HGLOBAL or a HANDLE
+** to a MetafilePict) or the caller may call
+** ReleaseStgMedium(lpMedium). this OLE helper function will do the
+** right thing.
+**
+** PARAMETERS:
+** LPDATAOBJECT lpDataObj -- object on which GetData should be
+** called.
+** CLIPFORMAT cfFormat -- desired clipboard format (eg. CF_TEXT)
+** DVTARGETDEVICE FAR* lpTargetDevice -- target device for which
+** the data should be composed. This may
+** be NULL. NULL can be used whenever the
+** data format is insensitive to target
+** device or when the caller does not care
+** what device is used.
+** LPSTGMEDIUM lpMedium -- ptr to STGMEDIUM struct. the
+** resultant medium from the
+** IDataObject::GetData call is
+** returned.
+**
+** RETURNS:
+** HGLOBAL -- global memory handle of retrieved data block.
+** NULL -- if error.
+*/
+STDAPI_(HGLOBAL) OleStdGetData(
+ LPDATAOBJECT lpDataObj,
+ CLIPFORMAT cfFormat,
+ DVTARGETDEVICE FAR* lpTargetDevice,
+ DWORD dwDrawAspect,
+ LPSTGMEDIUM lpMedium)
+{
+ HRESULT hrErr;
+ FORMATETC formatetc;
+ HGLOBAL hGlobal = NULL;
+ HGLOBAL hCopy;
+ LPVOID lp;
+
+ formatetc.cfFormat = cfFormat;
+ formatetc.ptd = lpTargetDevice;
+ formatetc.dwAspect = dwDrawAspect;
+ formatetc.lindex = -1;
+
+ switch (cfFormat)
+ {
+ case CF_METAFILEPICT:
+ formatetc.tymed = TYMED_MFPICT;
+ break;
+
+ case CF_BITMAP:
+ formatetc.tymed = TYMED_GDI;
+ break;
+
+ default:
+ formatetc.tymed = TYMED_HGLOBAL;
+ break;
+ }
+
+ OLEDBG_BEGIN2(TEXT("IDataObject::GetData called\r\n"))
+ hrErr = lpDataObj->GetData(
+ (LPFORMATETC)&formatetc,
+ lpMedium
+ );
+ OLEDBG_END2
+
+ if (hrErr != NOERROR)
+ return NULL;
+
+ if ((hGlobal = lpMedium->hGlobal) == NULL)
+ return NULL;
+
+ // Check if hGlobal really points to valid memory
+ if ((lp = GlobalLock(hGlobal)) != NULL)
+ {
+ if (IsBadReadPtr(lp, 1))
+ {
+ GlobalUnlock(hGlobal);
+ return NULL; // ERROR: memory is NOT valid
+ }
+ GlobalUnlock(hGlobal);
+ }
+
+ if (hGlobal != NULL && lpMedium->pUnkForRelease != NULL)
+ {
+ /* OLE2NOTE: the callee wants to retain ownership of the data.
+ ** this is indicated by passing a non-NULL pUnkForRelease.
+ ** thus, we will make a copy of the data and release the
+ ** callee's copy.
+ */
+
+ hCopy = OleDuplicateData(hGlobal, cfFormat, GHND|GMEM_SHARE);
+ ReleaseStgMedium(lpMedium); // release callee's copy of data
+
+ hGlobal = hCopy;
+ lpMedium->hGlobal = hCopy;
+ lpMedium->pUnkForRelease = NULL;
+ }
+ return hGlobal;
+}
+
+
+/* OleStdMalloc
+** ------------
+** allocate memory using the currently active IMalloc* allocator
+*/
+STDAPI_(LPVOID) OleStdMalloc(ULONG ulSize)
+{
+ LPVOID pout;
+ LPMALLOC pmalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
+ {
+ OleDbgAssertSz(0, szAssertMemAlloc);
+ return NULL;
+ }
+ pout = (LPVOID)pmalloc->Alloc(ulSize);
+ pmalloc->Release();
+
+ return pout;
+}
+
+
+/* OleStdRealloc
+** -------------
+** re-allocate memory using the currently active IMalloc* allocator
+*/
+STDAPI_(LPVOID) OleStdRealloc(LPVOID pmem, ULONG ulSize)
+{
+ LPVOID pout;
+ LPMALLOC pmalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
+ {
+ OleDbgAssertSz(0, szAssertMemAlloc);
+ return NULL;
+ }
+ pout = (LPVOID)pmalloc->Realloc(pmem, ulSize);
+ pmalloc->Release();
+
+ return pout;
+}
+
+
+/* OleStdFree
+** ----------
+** free memory using the currently active IMalloc* allocator
+*/
+STDAPI_(void) OleStdFree(LPVOID pmem)
+{
+ LPMALLOC pmalloc;
+
+ if (pmem == NULL)
+ return;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
+ {
+ OleDbgAssertSz(0, szAssertMemAlloc);
+ return;
+ }
+ if (1 == pmalloc->DidAlloc(pmem))
+ {
+ pmalloc->Free(pmem);
+ }
+ pmalloc->Release();
+}
+
+
+/* OleStdGetSize
+** -------------
+** Get the size of a memory block that was allocated using the
+** currently active IMalloc* allocator.
+*/
+STDAPI_(ULONG) OleStdGetSize(LPVOID pmem)
+{
+ ULONG ulSize;
+ LPMALLOC pmalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
+ {
+ OleDbgAssertSz(0, szAssertMemAlloc);
+ return (ULONG)-1;
+ }
+ ulSize = pmalloc->GetSize(pmem);
+ pmalloc->Release();
+
+ return ulSize;
+}
+
+
+/* OleStdLoadString
+** ----------------
+** Load a string from resources. The string is allocated
+** with the active IMalloc allocator.
+*/
+STDAPI_(LPTSTR) OleStdLoadString(HINSTANCE hInst, UINT nID)
+{
+ LPTSTR lpszResult = (LPTSTR)OleStdMalloc(256 * sizeof(TCHAR));
+ if (lpszResult == NULL)
+ return NULL;
+ LoadString(hInst, nID, lpszResult, 256);
+ return lpszResult;
+}
+
+/* OleStdCopyString
+** ----------------
+** Copy a string into memory allocated with the currently active
+** IMalloc* allocator.
+*/
+STDAPI_(LPTSTR) OleStdCopyString(LPTSTR lpszSrc)
+{
+ UINT nSize = (lstrlen(lpszSrc)+1) * sizeof(TCHAR);
+ LPTSTR lpszResult = (LPTSTR)OleStdMalloc(nSize);
+ if (lpszResult == NULL)
+ return NULL;
+ memcpy(lpszResult, lpszSrc, nSize);
+ return lpszResult;
+}
+
+/*
+ * OleStdGetObjectDescriptorData
+ *
+ * Purpose:
+ * Fills and returns a OBJECTDESCRIPTOR structure.
+ * See OBJECTDESCRIPTOR for more information.
+ *
+ * Parameters:
+ * clsid CLSID CLSID of object being transferred
+ * dwDrawAspect DWORD Display Aspect of object
+ * sizel SIZEL Size of object in HIMETRIC
+ * pointl POINTL Offset from upper-left corner of object where mouse went
+ * down for drag. Meaningful only when drag-drop is used.
+ * dwStatus DWORD OLEMISC flags
+ * lpszFullUserTypeName LPSTR Full User Type Name
+ * lpszSrcOfCopy LPSTR Source of Copy
+ *
+ * Return Value:
+ * HBGLOBAL Handle to OBJECTDESCRIPTOR structure.
+ */
+STDAPI_(HGLOBAL) OleStdGetObjectDescriptorData(
+ CLSID clsid,
+ DWORD dwDrawAspect,
+ SIZEL sizel,
+ POINTL pointl,
+ DWORD dwStatus,
+ LPTSTR lpszFullUserTypeName,
+ LPTSTR lpszSrcOfCopy)
+{
+ HGLOBAL hMem = NULL;
+ IBindCtx FAR *pbc = NULL;
+ LPOBJECTDESCRIPTOR lpOD;
+ DWORD dwObjectDescSize, dwFullUserTypeNameLen, dwSrcOfCopyLen;
+
+ // Get the length of Full User Type Name; Add 1 for the null terminator
+#if defined(WIN32) && !defined(UNICODE)
+ dwFullUserTypeNameLen = lpszFullUserTypeName ? ATOWLEN(lpszFullUserTypeName) : 0;
+ // Get the Source of Copy string and it's length; Add 1 for the null terminator
+ if (lpszSrcOfCopy)
+ dwSrcOfCopyLen = ATOWLEN(lpszSrcOfCopy);
+ else
+ {
+ // No src moniker so use user type name as source string.
+ lpszSrcOfCopy = lpszFullUserTypeName;
+ dwSrcOfCopyLen = dwFullUserTypeNameLen;
+ }
+#else
+ dwFullUserTypeNameLen = lpszFullUserTypeName ? lstrlen(lpszFullUserTypeName)+1 : 0;
+ // Get the Source of Copy string and it's length; Add 1 for the null terminator
+ if (lpszSrcOfCopy)
+ dwSrcOfCopyLen = lstrlen(lpszSrcOfCopy)+1;
+ else
+ {
+ // No src moniker so use user type name as source string.
+ lpszSrcOfCopy = lpszFullUserTypeName;
+ dwSrcOfCopyLen = dwFullUserTypeNameLen;
+ }
+#endif
+ // Allocate space for OBJECTDESCRIPTOR and the additional string data
+ dwObjectDescSize = sizeof(OBJECTDESCRIPTOR);
+ hMem = GlobalAlloc(GHND|GMEM_SHARE, dwObjectDescSize +
+ (dwFullUserTypeNameLen + dwSrcOfCopyLen) * sizeof(OLECHAR));
+ if (!hMem)
+ return NULL;
+
+ lpOD = (LPOBJECTDESCRIPTOR)GlobalLock(hMem);
+
+ // Set the FullUserTypeName offset and copy the string
+ if (lpszFullUserTypeName)
+ {
+ lpOD->dwFullUserTypeName = dwObjectDescSize;
+#if defined(WIN32) && !defined(UNICODE)
+ ATOW((LPWSTR)((LPBYTE)lpOD+lpOD->dwFullUserTypeName), lpszFullUserTypeName, dwFullUserTypeNameLen);
+#else
+ lstrcpy((LPTSTR)((LPBYTE)lpOD+lpOD->dwFullUserTypeName), lpszFullUserTypeName);
+#endif
+ }
+ else
+ lpOD->dwFullUserTypeName = 0; // zero offset indicates that string is not present
+
+ // Set the SrcOfCopy offset and copy the string
+ if (lpszSrcOfCopy)
+ {
+ lpOD->dwSrcOfCopy = dwObjectDescSize + dwFullUserTypeNameLen * sizeof(OLECHAR);
+#if defined(WIN32) && !defined(UNICODE)
+ ATOW((LPWSTR)((LPBYTE)lpOD+lpOD->dwSrcOfCopy), lpszSrcOfCopy, dwSrcOfCopyLen);
+#else
+ lstrcpy((LPTSTR)((LPBYTE)lpOD+lpOD->dwSrcOfCopy), lpszSrcOfCopy);
+#endif
+ }
+ else
+ lpOD->dwSrcOfCopy = 0; // zero offset indicates that string is not present
+
+ // Initialize the rest of the OBJECTDESCRIPTOR
+ lpOD->cbSize = dwObjectDescSize +
+ (dwFullUserTypeNameLen + dwSrcOfCopyLen) * sizeof(OLECHAR);
+ lpOD->clsid = clsid;
+ lpOD->dwDrawAspect = dwDrawAspect;
+ lpOD->sizel = sizel;
+ lpOD->pointl = pointl;
+ lpOD->dwStatus = dwStatus;
+
+ GlobalUnlock(hMem);
+ return hMem;
+}
+
+/*
+ * OleStdFillObjectDescriptorFromData
+ *
+ * Purpose:
+ * Fills and returns a OBJECTDESCRIPTOR structure. The source object will
+ * offer CF_OBJECTDESCRIPTOR if it is an OLE2 object, CF_OWNERLINK if it
+ * is an OLE1 object, or CF_FILENAME if it has been copied to the clipboard
+ * by FileManager.
+ *
+ * Parameters:
+ * lpDataObject LPDATAOBJECT Source object
+ * lpmedium LPSTGMEDIUM Storage medium
+ * lpcfFmt CLIPFORMAT FAR * Format offered by lpDataObject
+ * (OUT parameter)
+ *
+ * Return Value:
+ * HBGLOBAL Handle to OBJECTDESCRIPTOR structure.
+ */
+
+STDAPI_(HGLOBAL) OleStdFillObjectDescriptorFromData(
+ LPDATAOBJECT lpDataObject,
+ LPSTGMEDIUM lpmedium,
+ CLIPFORMAT FAR* lpcfFmt)
+{
+ CLSID clsid;
+ SIZEL sizelHim;
+ POINTL pointl;
+ LPTSTR lpsz, szFullUserTypeName, szSrcOfCopy, szClassName, szDocName, szItemName;
+ int nClassName, nDocName, nItemName, nFullUserTypeName;
+ LPTSTR szBuf = NULL;
+ HGLOBAL hMem = NULL;
+ HKEY hKey = NULL;
+ DWORD dw = OLEUI_CCHKEYMAX_SIZE;
+ HGLOBAL hObjDesc;
+ HRESULT hrErr;
+
+
+ // GetData CF_OBJECTDESCRIPTOR format from the object on the clipboard.
+ // Only OLE 2 objects on the clipboard will offer CF_OBJECTDESCRIPTOR
+ hMem = OleStdGetData(
+ lpDataObject,
+ (CLIPFORMAT) _g_cfObjectDescriptor,
+ NULL,
+ DVASPECT_CONTENT,
+ lpmedium);
+ if (hMem)
+ {
+ *lpcfFmt = (CLIPFORMAT)_g_cfObjectDescriptor;
+ return hMem; // Don't drop to clean up at the end of this function
+ }
+ // If CF_OBJECTDESCRIPTOR is not available, i.e. if this is not an OLE2 object,
+ // check if this is an OLE 1 object. OLE 1 objects will offer CF_OWNERLINK
+ else
+ {
+ hMem = OleStdGetData(
+ lpDataObject,
+ (CLIPFORMAT) _g_cfOwnerLink,
+ NULL,
+ DVASPECT_CONTENT,
+ lpmedium);
+ if (hMem)
+ {
+ *lpcfFmt = (CLIPFORMAT)_g_cfOwnerLink;
+ // CF_OWNERLINK contains null-terminated strings for class name, document name
+ // and item name with two null terminating characters at the end
+ szClassName = (LPTSTR)GlobalLock(hMem);
+ nClassName = lstrlen(szClassName);
+ szDocName = szClassName + nClassName + 1;
+ nDocName = lstrlen(szDocName);
+ szItemName = szDocName + nDocName + 1;
+ nItemName = lstrlen(szItemName);
+
+ // Find FullUserTypeName from Registration database using class name
+ if (RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey) != ERROR_SUCCESS)
+ goto error;
+
+ // Allocate space for szFullUserTypeName & szSrcOfCopy. Maximum length of FullUserTypeName
+ // is OLEUI_CCHKEYMAX_SIZE. SrcOfCopy is constructed by concatenating FullUserTypeName, Document
+ // Name and ItemName separated by spaces.
+ szBuf = (LPTSTR)OleStdMalloc(
+ (DWORD)2*OLEUI_CCHKEYMAX_SIZE+
+ (nDocName+nItemName+4)*sizeof(TCHAR));
+ if (NULL == szBuf)
+ goto error;
+ szFullUserTypeName = szBuf;
+ szSrcOfCopy = szFullUserTypeName+OLEUI_CCHKEYMAX_SIZE+1;
+
+ // Get FullUserTypeName
+ if (RegQueryValue(hKey, NULL, szFullUserTypeName, (LONG*)&dw) != ERROR_SUCCESS)
+ goto error;
+
+ // Build up SrcOfCopy string from FullUserTypeName, DocumentName & ItemName
+ lpsz = szSrcOfCopy;
+ lstrcpy(lpsz, szFullUserTypeName);
+ nFullUserTypeName = lstrlen(szFullUserTypeName);
+ lpsz[nFullUserTypeName]= ' ';
+ lpsz += nFullUserTypeName+1;
+ lstrcpy(lpsz, szDocName);
+ lpsz[nDocName] = ' ';
+ lpsz += nDocName+1;
+ lstrcpy(lpsz, szItemName);
+
+ sizelHim.cx = sizelHim.cy = 0;
+ pointl.x = pointl.y = 0;
+
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszClassName[OLEUI_CCHKEYMAX];
+ ATOW(wszClassName, szClassName, OLEUI_CCHKEYMAX);
+ CLSIDFromProgID(wszClassName, &clsid);
+#else
+ CLSIDFromProgID(szClassName, &clsid);
+#endif
+ hObjDesc = OleStdGetObjectDescriptorData(
+ clsid,
+ DVASPECT_CONTENT,
+ sizelHim,
+ pointl,
+ 0,
+ szFullUserTypeName,
+ szSrcOfCopy
+ );
+ if (!hObjDesc)
+ goto error;
+ }
+ else
+ {
+ BOOL fUnicode = TRUE;
+
+ hMem = OleStdGetData(
+ lpDataObject,
+ (CLIPFORMAT) _g_cfFileNameW,
+ NULL,
+ DVASPECT_CONTENT,
+ lpmedium);
+
+ if (!hMem)
+ {
+ hMem = OleStdGetData(
+ lpDataObject,
+ (CLIPFORMAT) _g_cfFileName,
+ NULL,
+ DVASPECT_CONTENT,
+ lpmedium);
+
+ fUnicode = FALSE;
+ }
+
+ if (hMem)
+ {
+ *lpcfFmt = fUnicode ? (CLIPFORMAT)_g_cfFileNameW : (CLIPFORMAT)_g_cfFileName;
+ lpsz = (LPTSTR)GlobalLock(hMem);
+ if (!fUnicode)
+ {
+ OLECHAR wsz[OLEUI_CCHKEYMAX];
+ ATOW(wsz, (LPSTR)lpsz, OLEUI_CCHKEYMAX);
+ hrErr = GetClassFile(wsz, &clsid);
+ }
+ else
+ hrErr = GetClassFile((LPWSTR)lpsz, &clsid);
+
+ /* OLE2NOTE: if the file does not have an OLE class
+ ** associated, then use the OLE 1 Packager as the class of
+ ** the object to be created. this is the behavior of
+ ** OleCreateFromData API
+ */
+ if (hrErr != NOERROR)
+ CLSIDFromProgID(OLESTR("Package"), &clsid);
+ sizelHim.cx = sizelHim.cy = 0;
+ pointl.x = pointl.y = 0;
+
+#if defined(WIN32) && !defined(UNICODE)
+ LPOLESTR wszBuf = NULL;
+ szBuf = NULL;
+ if (OleRegGetUserType(clsid, USERCLASSTYPE_FULL, &wszBuf) != NOERROR)
+ {
+ OleStdFree(wszBuf);
+ goto error;
+ }
+ if (NULL != wszBuf)
+ {
+ UINT uLen = WTOALEN(wszBuf) + 1;
+ szBuf = (LPTSTR) OleStdMalloc(uLen);
+ if (NULL != szBuf)
+ {
+ WTOA(szBuf, wszBuf, uLen);
+ }
+ else
+ {
+ OleStdFree(wszBuf);
+ goto error;
+ }
+ OleStdFree(wszBuf);
+ }
+#else
+ if (OleRegGetUserType(clsid, USERCLASSTYPE_FULL, &szBuf) != NOERROR)
+ goto error;
+#endif
+
+ hObjDesc = OleStdGetObjectDescriptorData(
+ clsid,
+ DVASPECT_CONTENT,
+ sizelHim,
+ pointl,
+ 0,
+ szBuf,
+ lpsz
+ );
+ if (!hObjDesc)
+ goto error;
+ }
+ else
+ goto error;
+ }
+ }
+ // Check if object is CF_FILENAME
+
+ // Clean up
+ OleStdFree(szBuf);
+ if (hMem)
+ {
+ GlobalUnlock(hMem);
+ GlobalFree(hMem);
+ }
+ if (hKey)
+ RegCloseKey(hKey);
+ return hObjDesc;
+
+error:
+ OleStdFree(szBuf);
+ if (hMem)
+ {
+ GlobalUnlock(hMem);
+ GlobalFree(hMem);
+ }
+ if (hKey)
+ RegCloseKey(hKey);
+ return NULL;
+}
+
+/* Call Release on the object that is NOT necessarily expected to go away.
+*/
+STDAPI_(ULONG) OleStdRelease(LPUNKNOWN lpUnk)
+{
+ ULONG cRef;
+ cRef = lpUnk->Release();
+
+#ifdef _DEBUG
+ {
+ TCHAR szBuf[80];
+ wsprintf(
+ szBuf,
+ TEXT("refcnt = %ld after object (0x%lx) release\n"),
+ cRef,
+ lpUnk
+ );
+ OleDbgOut4(szBuf);
+ }
+#endif
+ return cRef;
+}
+
+
+/*
+ * OleStdMarkPasteEntryList
+ *
+ * Purpose:
+ * Mark each entry in the PasteEntryList if its format is available from
+ * the source IDataObject*. the dwScratchSpace field of each PasteEntry
+ * is set to TRUE if available, else FALSE.
+ *
+ * Parameters:
+ * LPOLEUIPASTEENTRY array of PasteEntry structures
+ * int count of elements in PasteEntry array
+ * LPDATAOBJECT source IDataObject* pointer
+ *
+ * Return Value:
+ * none
+ */
+STDAPI_(void) OleStdMarkPasteEntryList(
+ LPDATAOBJECT lpSrcDataObj,
+ LPOLEUIPASTEENTRY lpPriorityList,
+ int cEntries)
+{
+ LPENUMFORMATETC lpEnumFmtEtc = NULL;
+ #define FORMATETC_MAX 20
+ FORMATETC rgfmtetc[FORMATETC_MAX];
+ int i;
+ HRESULT hrErr;
+ DWORD j, cFetched;
+
+ // Clear all marks
+ for (i = 0; i < cEntries; i++)
+ {
+ lpPriorityList[i].dwScratchSpace = FALSE;
+ if (! lpPriorityList[i].fmtetc.cfFormat)
+ {
+ // caller wants this item always considered available
+ // (by specifying a NULL format)
+ lpPriorityList[i].dwScratchSpace = TRUE;
+ }
+ else if (lpPriorityList[i].fmtetc.cfFormat == _g_cfEmbeddedObject
+ || lpPriorityList[i].fmtetc.cfFormat == _g_cfEmbedSource
+ || lpPriorityList[i].fmtetc.cfFormat == _g_cfFileName)
+ {
+ // if there is an OLE object format, then handle it
+ // specially by calling OleQueryCreateFromData. the caller
+ // need only specify one object type format.
+ OLEDBG_BEGIN2(TEXT("OleQueryCreateFromData called\r\n"))
+ hrErr = OleQueryCreateFromData(lpSrcDataObj);
+ OLEDBG_END2
+ if(NOERROR == hrErr)
+ lpPriorityList[i].dwScratchSpace = TRUE;
+ }
+ else if (lpPriorityList[i].fmtetc.cfFormat == _g_cfLinkSource)
+ {
+ // if there is OLE 2.0 LinkSource format, then handle it
+ // specially by calling OleQueryLinkFromData.
+ OLEDBG_BEGIN2(TEXT("OleQueryLinkFromData called\r\n"))
+ hrErr = OleQueryLinkFromData(lpSrcDataObj);
+ OLEDBG_END2
+ if(NOERROR == hrErr) {
+ lpPriorityList[i].dwScratchSpace = TRUE;
+ }
+ }
+ }
+
+ OLEDBG_BEGIN2(TEXT("IDataObject::EnumFormatEtc called\r\n"))
+ hrErr = lpSrcDataObj->EnumFormatEtc(
+ DATADIR_GET,
+ (LPENUMFORMATETC FAR*)&lpEnumFmtEtc
+ );
+ OLEDBG_END2
+
+ if (hrErr != NOERROR)
+ return; // unable to get format enumerator
+
+ // Enumerate the formats offered by the source
+ // Loop over all formats offered by the source
+ cFetched = 0;
+ memset(rgfmtetc,0,sizeof(rgfmtetc[FORMATETC_MAX]) );
+ if (lpEnumFmtEtc->Next(
+ FORMATETC_MAX, rgfmtetc, &cFetched) == NOERROR
+ || (cFetched > 0 && cFetched <= FORMATETC_MAX) )
+ {
+ for (j = 0; j < cFetched; j++)
+ {
+ for (i = 0; i < cEntries; i++)
+ {
+ if (!lpPriorityList[i].dwScratchSpace &&
+ IsCloseFormatEtc(&lpPriorityList[i].fmtetc, &rgfmtetc[j]))
+ {
+ lpPriorityList[i].dwScratchSpace = TRUE;
+ }
+ }
+ }
+ } // endif
+
+ OleStdRelease((LPUNKNOWN)lpEnumFmtEtc);
+}
+
+
+// returns 1 for a close match
+// (all fields match exactly except the tymed which simply overlaps)
+// 0 for no match
+
+int IsCloseFormatEtc(FORMATETC FAR* pFetcLeft, FORMATETC FAR* pFetcRight)
+{
+ if (pFetcLeft->cfFormat != pFetcRight->cfFormat)
+ return 0;
+ else if (!OleStdCompareTargetDevice (pFetcLeft->ptd, pFetcRight->ptd))
+ return 0;
+ if (pFetcLeft->dwAspect != pFetcRight->dwAspect)
+ return 0;
+ return((pFetcLeft->tymed | pFetcRight->tymed) != 0);
+}
+
+
diff --git a/private/ole2ui32/olestd.h b/private/ole2ui32/olestd.h
new file mode 100644
index 000000000..2f406bc2d
--- /dev/null
+++ b/private/ole2ui32/olestd.h
@@ -0,0 +1,328 @@
+/*************************************************************************
+**
+** OLE 2.0 Utility Library
+**
+** olestd.h
+**
+** This file contains file contains data structure defintions,
+** function prototypes, constants, etc. for the common OLE 2.0
+** utilities.
+** These utilities include the following:
+** Debuging Assert/Verify macros
+** HIMETRIC conversion routines
+** reference counting debug support
+** OleStd API's for common compound-document app support
+**
+** (c) Copyright Microsoft Corp. 1990 - 1995 All Rights Reserved
+**
+*************************************************************************/
+
+#ifndef _OLESTD_H_
+#define _OLESTD_H_
+
+#include <commdlg.h> // needed for LPPRINTDLG
+#include <shellapi.h> // needed for HKEY
+#include <oledlg.h> // need some paste special defines
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+STDAPI_(void) OleStdInitialize(HINSTANCE hInstance, HINSTANCE hResInstance);
+
+// Clipboard Copy/Paste & Drag/Drop support support
+
+// Clipboard format strings
+#define CF_EMBEDSOURCE TEXT("Embed Source")
+#define CF_EMBEDDEDOBJECT TEXT("Embedded Object")
+#define CF_LINKSOURCE TEXT("Link Source")
+#define CF_OBJECTDESCRIPTOR TEXT("Object Descriptor")
+#define CF_LINKSRCDESCRIPTOR TEXT("Link Source Descriptor")
+#define CF_OWNERLINK TEXT("OwnerLink")
+#define CF_FILENAME TEXT("FileName")
+#define CF_FILENAMEW TEXT("FileNameW")
+
+// Other useful defines
+#define HIMETRIC_PER_INCH 2540 // number HIMETRIC units per inch
+#define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH)
+
+/****** DEBUG Support *****************************************************/
+
+#ifdef _DEBUG
+
+#ifndef _DBGTRACE
+ #define _DEBUGLEVEL 2
+#else
+ #define _DEBUGLEVEL _DBGTRACE
+#endif
+
+#ifdef NOASSERT
+
+#define OLEDBGASSERTDATA
+#define OleDbgAssert(a)
+#define OleDbgAssertSz(a, b)
+#define OleDbgVerify(a)
+#define OleDbgVerifySz(a, b)
+
+#else // ! NOASSERT
+
+STDAPI OleStdAssert(LPTSTR lpstrExpr, LPTSTR lpstrMsg,
+ LPTSTR lpstrFileName, UINT iLine);
+
+#define OLEDBGASSERTDATA \
+ static TCHAR _szAssertFile[]= TEXT(__FILE__);
+
+#define OleDbgAssert(a) \
+ (!(a) ? OleStdAssert(TEXT(#a), NULL, _szAssertFile, __LINE__) : (HRESULT)1)
+
+#define OleDbgAssertSz(a, b) \
+ (!(a) ? OleStdAssert(TEXT(#a), b, _szAssertFile, __LINE__) : (HRESULT)1)
+
+#endif
+
+#define OleDbgVerify(a) \
+ OleDbgAssert(a)
+
+#define OleDbgVerifySz(a, b) \
+ OleDbgAssertSz(a, b)
+
+#define OLEDBGDATA_MAIN(szPrefix) \
+ TCHAR g_szDbgPrefix[] = szPrefix; \
+ OLEDBGASSERTDATA
+#define OLEDBGDATA \
+ extern TCHAR g_szDbgPrefix[]; \
+ OLEDBGASSERTDATA
+
+#define OLEDBG_BEGIN(lpsz) \
+ OleDbgPrintAlways(g_szDbgPrefix,lpsz,1);
+
+#define OLEDBG_END \
+ OleDbgPrintAlways(g_szDbgPrefix,TEXT("End\r\n"),-1);
+
+#define OleDbgOut(lpsz) \
+ OleDbgPrintAlways(g_szDbgPrefix,lpsz,0)
+
+#define OleDbgOutNoPrefix(lpsz) \
+ OleDbgPrintAlways(TEXT(""),lpsz,0)
+
+#define OleDbgOutRefCnt(lpsz,lpObj,refcnt) \
+ OleDbgPrintRefCntAlways(g_szDbgPrefix,lpsz,lpObj,(ULONG)refcnt)
+
+#define OleDbgOutRect(lpsz,lpRect) \
+ OleDbgPrintRectAlways(g_szDbgPrefix,lpsz,lpRect)
+
+#define OleDbgOutHResult(lpsz,hr) \
+ OleDbgPrintScodeAlways(g_szDbgPrefix,lpsz,GetScode(hr))
+
+#define OleDbgOutScode(lpsz,sc) \
+ OleDbgPrintScodeAlways(g_szDbgPrefix,lpsz,sc)
+
+#define OleDbgOut1(lpsz) \
+ OleDbgPrint(1,g_szDbgPrefix,lpsz,0)
+
+#define OleDbgOutNoPrefix1(lpsz) \
+ OleDbgPrint(1,TEXT(""),lpsz,0)
+
+#define OLEDBG_BEGIN1(lpsz) \
+ OleDbgPrint(1,g_szDbgPrefix,lpsz,1);
+
+#define OLEDBG_END1 \
+ OleDbgPrint(1,g_szDbgPrefix,TEXT("End\r\n"),-1);
+
+#define OleDbgOutRefCnt1(lpsz,lpObj,refcnt) \
+ OleDbgPrintRefCnt(1,g_szDbgPrefix,lpsz,lpObj,(ULONG)refcnt)
+
+#define OleDbgOutRect1(lpsz,lpRect) \
+ OleDbgPrintRect(1,g_szDbgPrefix,lpsz,lpRect)
+
+#define OleDbgOut2(lpsz) \
+ OleDbgPrint(2,g_szDbgPrefix,lpsz,0)
+
+#define OleDbgOutNoPrefix2(lpsz) \
+ OleDbgPrint(2,TEXT(""),lpsz,0)
+
+#define OLEDBG_BEGIN2(lpsz) \
+ OleDbgPrint(2,g_szDbgPrefix,lpsz,1);
+
+#define OLEDBG_END2 \
+ OleDbgPrint(2,g_szDbgPrefix, TEXT("End\r\n"),-1);
+
+#define OleDbgOutRefCnt2(lpsz,lpObj,refcnt) \
+ OleDbgPrintRefCnt(2,g_szDbgPrefix,lpsz,lpObj,(ULONG)refcnt)
+
+#define OleDbgOutRect2(lpsz,lpRect) \
+ OleDbgPrintRect(2,g_szDbgPrefix,lpsz,lpRect)
+
+#define OleDbgOut3(lpsz) \
+ OleDbgPrint(3,g_szDbgPrefix,lpsz,0)
+
+#define OleDbgOutNoPrefix3(lpsz) \
+ OleDbgPrint(3,TEXT(""),lpsz,0)
+
+#define OLEDBG_BEGIN3(lpsz) \
+ OleDbgPrint(3,g_szDbgPrefix,lpsz,1);
+
+#define OLEDBG_END3 \
+ OleDbgPrint(3,g_szDbgPrefix,TEXT("End\r\n"),-1);
+
+#define OleDbgOutRefCnt3(lpsz,lpObj,refcnt) \
+ OleDbgPrintRefCnt(3,g_szDbgPrefix,lpsz,lpObj,(ULONG)refcnt)
+
+#define OleDbgOutRect3(lpsz,lpRect) \
+ OleDbgPrintRect(3,g_szDbgPrefix,lpsz,lpRect)
+
+#define OleDbgOut4(lpsz) \
+ OleDbgPrint(4,g_szDbgPrefix,lpsz,0)
+
+#define OleDbgOutNoPrefix4(lpsz) \
+ OleDbgPrint(4,TEXT(""),lpsz,0)
+
+#define OLEDBG_BEGIN4(lpsz) \
+ OleDbgPrint(4,g_szDbgPrefix,lpsz,1);
+
+#define OLEDBG_END4 \
+ OleDbgPrint(4,g_szDbgPrefix,TEXT("End\r\n"),-1);
+
+#define OleDbgOutRefCnt4(lpsz,lpObj,refcnt) \
+ OleDbgPrintRefCnt(4,g_szDbgPrefix,lpsz,lpObj,(ULONG)refcnt)
+
+#define OleDbgOutRect4(lpsz,lpRect) \
+ OleDbgPrintRect(4,g_szDbgPrefix,lpsz,lpRect)
+
+#else // !_DEBUG
+
+#define OLEDBGDATA_MAIN(szPrefix)
+#define OLEDBGDATA
+#define OleDbgAssert(a)
+#define OleDbgAssertSz(a, b)
+#define OleDbgVerify(a) (a)
+#define OleDbgVerifySz(a, b) (a)
+#define OleDbgOutHResult(lpsz,hr)
+#define OleDbgOutScode(lpsz,sc)
+#define OLEDBG_BEGIN(lpsz)
+#define OLEDBG_END
+#define OleDbgOut(lpsz)
+#define OleDbgOut1(lpsz)
+#define OleDbgOut2(lpsz)
+#define OleDbgOut3(lpsz)
+#define OleDbgOut4(lpsz)
+#define OleDbgOutNoPrefix(lpsz)
+#define OleDbgOutNoPrefix1(lpsz)
+#define OleDbgOutNoPrefix2(lpsz)
+#define OleDbgOutNoPrefix3(lpsz)
+#define OleDbgOutNoPrefix4(lpsz)
+#define OLEDBG_BEGIN1(lpsz)
+#define OLEDBG_BEGIN2(lpsz)
+#define OLEDBG_BEGIN3(lpsz)
+#define OLEDBG_BEGIN4(lpsz)
+#define OLEDBG_END1
+#define OLEDBG_END2
+#define OLEDBG_END3
+#define OLEDBG_END4
+#define OleDbgOutRefCnt(lpsz,lpObj,refcnt)
+#define OleDbgOutRefCnt1(lpsz,lpObj,refcnt)
+#define OleDbgOutRefCnt2(lpsz,lpObj,refcnt)
+#define OleDbgOutRefCnt3(lpsz,lpObj,refcnt)
+#define OleDbgOutRefCnt4(lpsz,lpObj,refcnt)
+#define OleDbgOutRect(lpsz,lpRect)
+#define OleDbgOutRect1(lpsz,lpRect)
+#define OleDbgOutRect2(lpsz,lpRect)
+#define OleDbgOutRect3(lpsz,lpRect)
+#define OleDbgOutRect4(lpsz,lpRect)
+
+#endif // _DEBUG
+
+/*************************************************************************
+** Function prototypes
+*************************************************************************/
+
+// OLESTD.CPP
+STDAPI_(int) XformWidthInHimetricToPixels(HDC, int);
+STDAPI_(int) XformHeightInHimetricToPixels(HDC, int);
+
+STDAPI_(BOOL) OleStdIsOleLink(LPUNKNOWN lpUnk);
+STDAPI_(LPUNKNOWN) OleStdQueryInterface(LPUNKNOWN lpUnk, REFIID riid);
+STDAPI_(HGLOBAL) OleStdGetData(
+ LPDATAOBJECT lpDataObj,
+ CLIPFORMAT cfFormat,
+ DVTARGETDEVICE FAR* lpTargetDevice,
+ DWORD dwAspect,
+ LPSTGMEDIUM lpMedium
+);
+STDAPI_(void) OleStdMarkPasteEntryList(
+ LPDATAOBJECT lpSrcDataObj,
+ LPOLEUIPASTEENTRY lpPriorityList,
+ int cEntries
+);
+STDAPI_(HGLOBAL) OleStdGetObjectDescriptorData(
+ CLSID clsid,
+ DWORD dwAspect,
+ SIZEL sizel,
+ POINTL pointl,
+ DWORD dwStatus,
+ LPTSTR lpszFullUserTypeName,
+ LPTSTR lpszSrcOfCopy
+);
+STDAPI_(HGLOBAL) OleStdFillObjectDescriptorFromData(
+ LPDATAOBJECT lpDataObject,
+ LPSTGMEDIUM lpmedium,
+ CLIPFORMAT FAR* lpcfFmt
+);
+
+STDAPI_(LPVOID) OleStdMalloc(ULONG ulSize);
+STDAPI_(LPVOID) OleStdRealloc(LPVOID pmem, ULONG ulSize);
+STDAPI_(void) OleStdFree(LPVOID pmem);
+STDAPI_(ULONG) OleStdGetSize(LPVOID pmem);
+STDAPI_(LPTSTR) OleStdCopyString(LPTSTR lpszSrc);
+STDAPI_(LPTSTR) OleStdLoadString(HINSTANCE hInst, UINT nID);
+STDAPI_(ULONG) OleStdRelease(LPUNKNOWN lpUnk);
+
+STDAPI_(BOOL) OleStdCompareTargetDevice
+ (DVTARGETDEVICE FAR* ptdLeft, DVTARGETDEVICE FAR* ptdRight);
+
+STDAPI_(void) OleDbgPrint(
+ int nDbgLvl,
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ int nIndent
+);
+STDAPI_(void) OleDbgPrintAlways(LPTSTR lpszPrefix, LPTSTR lpszMsg, int nIndent);
+STDAPI_(void) OleDbgSetDbgLevel(int nDbgLvl);
+STDAPI_(int) OleDbgGetDbgLevel( void );
+STDAPI_(void) OleDbgIndent(int n);
+STDAPI_(void) OleDbgPrintRefCnt(
+ int nDbgLvl,
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPVOID lpObj,
+ ULONG refcnt
+);
+STDAPI_(void) OleDbgPrintRefCntAlways(
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPVOID lpObj,
+ ULONG refcnt
+);
+STDAPI_(void) OleDbgPrintRect(
+ int nDbgLvl,
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPRECT lpRect
+);
+STDAPI_(void) OleDbgPrintRectAlways(
+ LPTSTR lpszPrefix,
+ LPTSTR lpszMsg,
+ LPRECT lpRect
+);
+STDAPI_(void) OleDbgPrintScodeAlways(LPTSTR lpszPrefix, LPTSTR lpszMsg, SCODE sc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#define ATOW(wsz, sz, cch) MultiByteToWideChar(CP_ACP, 0, sz, -1, wsz, cch)
+#define WTOA(sz, wsz, cch) WideCharToMultiByte(CP_ACP, 0, wsz, -1, sz, cch, NULL, NULL)
+#define ATOWLEN(sz) MultiByteToWideChar(CP_ACP, 0, sz, -1, NULL, 0)
+#define WTOALEN(wsz) WideCharToMultiByte(CP_ACP, 0, wsz, -1, NULL, 0, NULL, NULL)
+
+#endif // _OLESTD_H_
diff --git a/private/ole2ui32/oleutl.cpp b/private/ole2ui32/oleutl.cpp
new file mode 100644
index 000000000..1a0b0ca6b
--- /dev/null
+++ b/private/ole2ui32/oleutl.cpp
@@ -0,0 +1,132 @@
+/*
+ * OLEUTL.CPP
+ *
+ * Miscellaneous utility functions for OLE 2.0 Applications:
+ *
+ * Function Purpose
+ * -------------------------------------------------------------------
+ * XformWidthInHimetricToPixels Converts an int width from HiMetric units
+ * XformHeightInHimetricToPixels Converts an int height from HiMetric units
+ *
+ * CommitStorage Commits all changes in a docfile
+ * CreateChildStorage Creates child storage in another storage
+ * OpenChildStorage Opens child storage in another storage
+ *
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+
+#include "precomp.h"
+#include <stdlib.h>
+
+//Internal function to this module. No need for UNICODE in this function
+static LPSTR GetWord(LPSTR lpszSrc, LPSTR lpszDst);
+
+/*
+ * XformWidthInHimetricToPixels
+ * XformHeightInHimetricToPixels
+ *
+ * Functions to convert an int between a device coordinate system and
+ * logical HiMetric units.
+ *
+ * Parameters:
+ * hDC HDC providing reference to the pixel mapping. If
+ * NULL, a screen DC is used.
+ *
+ * Size Functions:
+ * lpSizeSrc LPSIZEL providing the structure to convert.
+ * lpSizeDst LPSIZEL providing the structure to receive converted
+ * units.
+ *
+ * Width Functions:
+ * iWidth int containing the value to convert.
+ *
+ * Return Value:
+ * Size Functions: None
+ * Width Functions: Converted value of the input parameters.
+ *
+ * NOTE:
+ * When displaying on the screen, Window apps display everything enlarged
+ * from its actual size so that it is easier to read. For example, if an
+ * app wants to display a 1in. horizontal line, that when printed is
+ * actually a 1in. line on the printed page, then it will display the line
+ * on the screen physically larger than 1in. This is described as a line
+ * that is "logically" 1in. along the display width. Windows maintains as
+ * part of the device-specific information about a given display device:
+ * LOGPIXELSX -- no. of pixels per logical in along the display width
+ * LOGPIXELSY -- no. of pixels per logical in along the display height
+ *
+ * The following formula converts a distance in pixels into its equivalent
+ * logical HIMETRIC units:
+ *
+ * DistInHiMetric = (HIMETRIC_PER_INCH * DistInPix)
+ * -------------------------------
+ * PIXELS_PER_LOGICAL_IN
+ *
+ */
+STDAPI_(int) XformWidthInHimetricToPixels(HDC hDC, int iWidthInHiMetric)
+{
+ int iXppli; //Pixels per logical inch along width
+ int iWidthInPix;
+ BOOL fSystemDC=FALSE;
+
+ if (NULL==hDC)
+ {
+ hDC=GetDC(NULL);
+ fSystemDC=TRUE;
+ }
+
+ iXppli = GetDeviceCaps (hDC, LOGPIXELSX);
+
+ //We got logical HIMETRIC along the display, convert them to pixel units
+ iWidthInPix = MAP_LOGHIM_TO_PIX(iWidthInHiMetric, iXppli);
+
+ if (fSystemDC)
+ ReleaseDC(NULL, hDC);
+
+ return iWidthInPix;
+}
+
+
+STDAPI_(int) XformHeightInHimetricToPixels(HDC hDC, int iHeightInHiMetric)
+{
+ int iYppli; //Pixels per logical inch along height
+ int iHeightInPix;
+ BOOL fSystemDC=FALSE;
+
+ if (NULL==hDC)
+ {
+ hDC=GetDC(NULL);
+ fSystemDC=TRUE;
+ }
+
+ iYppli = GetDeviceCaps (hDC, LOGPIXELSY);
+
+ //* We got logical HIMETRIC along the display, convert them to pixel units
+ iHeightInPix = MAP_LOGHIM_TO_PIX(iHeightInHiMetric, iYppli);
+
+ if (fSystemDC)
+ ReleaseDC(NULL, hDC);
+
+ return iHeightInPix;
+}
+
+/* GetWord
+ * -------
+ *
+ * LPSTR lpszSrc - Pointer to a source string
+ * LPSTR lpszDst - Pointer to destination buffer
+ *
+ * Will copy one space-terminated or null-terminated word from the source
+ * string to the destination buffer.
+ * returns: pointer to next character following the word.
+ */
+static LPSTR GetWord(LPSTR lpszSrc, LPSTR lpszDst)
+{
+ while (*lpszSrc && !(*lpszSrc == ' ' || *lpszSrc == '\t' || *lpszSrc == '\n'))
+ *lpszDst++ = *lpszSrc++;
+
+ *lpszDst = '\0';
+ return lpszSrc;
+}
diff --git a/private/ole2ui32/pastespl.cpp b/private/ole2ui32/pastespl.cpp
new file mode 100644
index 000000000..1c55b2948
--- /dev/null
+++ b/private/ole2ui32/pastespl.cpp
@@ -0,0 +1,1881 @@
+/*
+ * PASTESPL.CPP
+ *
+ * Implements the OleUIPasteSpecial function which invokes the complete
+ * Paste Special dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Rights Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include "utility.h"
+#include "resimage.h"
+#include "iconbox.h"
+#include <stdlib.h>
+
+OLEDBGDATA
+
+// Length of buffers to hold the strings 'Unknown Type', Unknown Source'
+// and 'the application which created it'
+// Extra long to allow room for localization.
+#define PS_UNKNOWNSTRLEN 200
+#define PS_UNKNOWNNAMELEN 256
+
+// Property label used to store clipboard viewer chain information
+#define NEXTCBVIEWER TEXT("NextCBViewer")
+
+// Internally used structure
+typedef struct tagPASTESPECIAL
+{
+ // Keep this item first as the Standard* functions depend on it here.
+ LPOLEUIPASTESPECIAL lpOPS; //Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ /*
+ * What we store extra in this structure besides the original caller's
+ * pointer are those fields that we need to modify during the life of
+ * the dialog but that we don't want to change in the original structure
+ * until the user presses OK.
+ */
+
+ DWORD dwFlags; // Local copy of paste special flags
+
+ int nPasteListCurSel; // Save the selection the user made last
+ int nPasteLinkListCurSel; // in the paste and pastelink lists
+ int nSelectedIndex; // Index in arrPasteEntries[] corresponding to user selection
+ BOOL fLink; // Indicates if Paste or PasteLink was selected by user
+
+ HGLOBAL hBuff; // Scratch Buffer for building up strings
+ TCHAR szUnknownType[PS_UNKNOWNSTRLEN]; // Buffer for 'Unknown Type' string
+ TCHAR szUnknownSource[PS_UNKNOWNSTRLEN]; // Buffer for 'Unknown Source' string
+ TCHAR szAppName[OLEUI_CCHKEYMAX]; // Application name of Source. Used in the result text
+ // when Paste is selected. Obtained using clsidOD.
+
+ // Information obtained from OBJECTDESCRIPTOR. This information is accessed when the Paste
+ // radio button is selected.
+ CLSID clsidOD; // ClassID of source
+ SIZEL sizelOD; // sizel transfered in
+ // ObjectDescriptor
+ TCHAR szFullUserTypeNameOD[PS_UNKNOWNNAMELEN]; // Full User Type Name
+ TCHAR szSourceOfDataOD[PS_UNKNOWNNAMELEN]; // Source of Data
+ BOOL fSrcAspectIconOD; // Does Source specify DVASPECT_ICON?
+ BOOL fSrcOnlyIconicOD; // Does Source specify OLEMISC_ONLYICONIC?
+ HGLOBAL hMetaPictOD; // Metafile containing icon and icon title
+ HGLOBAL hObjDesc; // Handle to OBJECTDESCRIPTOR structure from which the
+ // above information is obtained
+
+ // Information obtained from LINKSRCDESCRIPTOR. This infomation is accessed when the PasteLink
+ // radio button is selected.
+ CLSID clsidLSD; // ClassID of source
+ SIZEL sizelLSD; // sizel transfered in
+ // LinkSrcDescriptor
+ TCHAR szFullUserTypeNameLSD[PS_UNKNOWNNAMELEN];// Full User Type Name
+ TCHAR szSourceOfDataLSD[PS_UNKNOWNNAMELEN]; // Source of Data
+ BOOL fSrcAspectIconLSD; // Does Source specify DVASPECT_ICON?
+ BOOL fSrcOnlyIconicLSD; // Does Source specify OLEMISC_ONLYICONIC?
+ HGLOBAL hMetaPictLSD; // Metafile containing icon and icon title
+ HGLOBAL hLinkSrcDesc; // Handle to LINKSRCDESCRIPTOR structure from which the
+ // above information is obtained
+
+ BOOL fClipboardChanged; // Has clipboard content changed
+ // if so bring down dlg after
+ // ChangeIcon dlg returns.
+} PASTESPECIAL, *PPASTESPECIAL, FAR *LPPASTESPECIAL;
+
+// Data corresponding to each list item. A pointer to this structure is attached to each
+// Paste\PasteLink list box item using LB_SETITEMDATA
+typedef struct tagPASTELISTITEMDATA
+{
+ int nPasteEntriesIndex; // Index of arrPasteEntries[] corresponding to list item
+ BOOL fCntrEnableIcon; // Does calling application (called container here)
+ // specify OLEUIPASTE_ENABLEICON for this item?
+} PASTELISTITEMDATA, *PPASTELISTITEMDATA, FAR *LPPASTELISTITEMDATA;
+
+// Internal function prototypes
+// PASTESPL.CPP
+BOOL CALLBACK PasteSpecialDialogProc(HWND, UINT, WPARAM, LPARAM);
+BOOL FPasteSpecialInit(HWND hDlg, WPARAM, LPARAM);
+BOOL FTogglePasteType(HWND, LPPASTESPECIAL, DWORD);
+void ChangeListSelection(HWND, LPPASTESPECIAL, HWND);
+void EnableDisplayAsIcon(HWND, LPPASTESPECIAL);
+void ToggleDisplayAsIcon(HWND, LPPASTESPECIAL);
+void ChangeIcon(HWND, LPPASTESPECIAL);
+void SetPasteSpecialHelpResults(HWND, LPPASTESPECIAL);
+BOOL FAddPasteListItem(HWND, BOOL, int, LPPASTESPECIAL, LPTSTR, LPTSTR);
+BOOL FFillPasteList(HWND, LPPASTESPECIAL);
+BOOL FFillPasteLinkList(HWND, LPPASTESPECIAL);
+BOOL FHasPercentS(LPCTSTR, LPPASTESPECIAL);
+HGLOBAL AllocateScratchMem(LPPASTESPECIAL);
+void FreeListData(HWND);
+BOOL FPasteSpecialReInit(HWND hDlg, LPPASTESPECIAL lpPS);
+
+/*
+ * OleUIPasteSpecial
+ *
+ * Purpose:
+ * Invokes the standard OLE Paste Special dialog box which allows the user
+ * to select the format of the clipboard object to be pasted or paste linked.
+ *
+ * Parameters:
+ * lpPS LPOLEUIPasteSpecial pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * UINT One of the following codes or one of the standard error codes (OLEUI_ERR_*)
+ * defined in OLEDLG.H, indicating success or error:
+ * OLEUI_OK User selected OK
+ * OLEUI_CANCEL User cancelled the dialog
+ * OLEUI_IOERR_SRCDATAOBJECTINVALID lpSrcDataObject field of OLEUIPASTESPECIAL invalid
+ * OLEUI_IOERR_ARRPASTEENTRIESINVALID arrPasteEntries field of OLEUIPASTESPECIAL invalid
+ * OLEUI_IOERR_ARRLINKTYPESINVALID arrLinkTypes field of OLEUIPASTESPECIAL invalid
+ * OLEUI_PSERR_CLIPBOARDCHANGED Clipboard contents changed while dialog was up
+ */
+STDAPI_(UINT) OleUIPasteSpecial(LPOLEUIPASTESPECIAL lpPS)
+{
+ UINT uRet;
+ HGLOBAL hMemDlg=NULL;
+
+ uRet = UStandardValidation((LPOLEUISTANDARD)lpPS, sizeof(OLEUIPASTESPECIAL),
+ &hMemDlg);
+
+ if (uRet != OLEUI_SUCCESS)
+ return uRet;
+
+ // Validate PasteSpecial specific fields
+ if (NULL != lpPS->lpSrcDataObj && IsBadReadPtr(lpPS->lpSrcDataObj, sizeof(IDataObject)))
+ {
+ uRet = OLEUI_IOERR_SRCDATAOBJECTINVALID;
+ }
+ if (NULL == lpPS->arrPasteEntries ||
+ IsBadReadPtr(lpPS->arrPasteEntries, lpPS->cPasteEntries * sizeof(OLEUIPASTEENTRY)))
+ {
+ uRet = OLEUI_IOERR_ARRPASTEENTRIESINVALID;
+ }
+ if (0 > lpPS->cLinkTypes || lpPS->cLinkTypes > PS_MAXLINKTYPES ||
+ IsBadReadPtr(lpPS->arrLinkTypes, lpPS->cLinkTypes * sizeof(UINT)))
+ {
+ uRet = OLEUI_IOERR_ARRLINKTYPESINVALID;
+ }
+
+ if (0 != lpPS->cClsidExclude &&
+ IsBadReadPtr(lpPS->lpClsidExclude, lpPS->cClsidExclude * sizeof(CLSID)))
+ {
+ uRet = OLEUI_IOERR_LPCLSIDEXCLUDEINVALID;
+ }
+
+ // If IDataObject passed is NULL, collect it from the clipboard
+ if (NULL == lpPS->lpSrcDataObj)
+ {
+ if (OleGetClipboard(&lpPS->lpSrcDataObj) != NOERROR)
+ uRet = OLEUI_PSERR_GETCLIPBOARDFAILED;
+
+ if (NULL == lpPS->lpSrcDataObj)
+ uRet = OLEUI_PSERR_GETCLIPBOARDFAILED;
+ }
+
+ if (uRet >= OLEUI_ERR_STANDARDMIN)
+ {
+ return uRet;
+ }
+
+ UINT nIDD = bWin4 ? IDD_PASTESPECIAL4 : IDD_PASTESPECIAL;
+
+ //Now that we've validated everything, we can invoke the dialog.
+ uRet = UStandardInvocation(PasteSpecialDialogProc, (LPOLEUISTANDARD)lpPS,
+ hMemDlg, MAKEINTRESOURCE(nIDD));
+
+ return uRet;
+}
+
+/*
+ * PasteSpecialDialogProc
+ *
+ * Purpose:
+ * Implements the OLE Paste Special dialog as invoked through the
+ * OleUIPasteSpecial function.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ */
+BOOL CALLBACK PasteSpecialDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ // Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ // This will fail under WM_INITDIALOG, where we allocate it.
+ UINT fHook = FALSE;
+ LPPASTESPECIAL lpPS = (LPPASTESPECIAL)LpvStandardEntry(
+ hDlg, iMsg, wParam, lParam, &fHook);
+ LPOLEUIPASTESPECIAL lpOPS = NULL;
+ if (lpPS != NULL)
+ lpOPS = lpPS->lpOPS;
+
+ //If the hook processed the message, we're done.
+ if (0!=fHook)
+ return fHook;
+
+ // Process help message from Change Icon
+ if (iMsg == uMsgHelp)
+ {
+ PostMessage(lpPS->lpOPS->hWndOwner, uMsgHelp, wParam, lParam);
+ return FALSE;
+ }
+
+ //Process the temination message
+ if (iMsg == uMsgEndDialog)
+ {
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ switch (iMsg)
+ {
+ case WM_DESTROY:
+ if (lpPS)
+ {
+ HWND hwndNextViewer;
+
+ // Free the icon/icon-title metafile corresponding to Paste/PasteList option which is not selected
+ if (lpPS->fLink)
+ OleUIMetafilePictIconFree(lpPS->hMetaPictOD);
+ else
+ OleUIMetafilePictIconFree(lpPS->hMetaPictLSD);
+
+ // Free data associated with each list box entry
+ FreeListData(GetDlgItem(hDlg, IDC_PS_PASTELIST));
+ FreeListData(GetDlgItem(hDlg, IDC_PS_PASTELINKLIST));
+
+ //Free any specific allocations before calling StandardCleanup
+ if (lpPS->hObjDesc) GlobalFree(lpPS->hObjDesc);
+ if (lpPS->hLinkSrcDesc) GlobalFree(lpPS->hLinkSrcDesc);
+ if (lpPS->hBuff)
+ {
+ GlobalFree(lpPS->hBuff);
+ lpPS->hBuff = NULL;
+ }
+
+ // Change the clipboard notification chain
+ hwndNextViewer = (HWND)GetProp(hDlg, NEXTCBVIEWER);
+ if (hwndNextViewer != HWND_BROADCAST)
+ {
+ SetProp(hDlg, NEXTCBVIEWER, HWND_BROADCAST);
+ ChangeClipboardChain(hDlg, hwndNextViewer);
+ }
+ RemoveProp(hDlg, NEXTCBVIEWER);
+
+ StandardCleanup(lpPS, hDlg);
+ }
+ break;
+ case WM_INITDIALOG:
+ FPasteSpecialInit(hDlg, wParam, lParam);
+ return FALSE;
+
+ case WM_DRAWCLIPBOARD:
+ {
+ HWND hwndNextViewer = (HWND)GetProp(hDlg, NEXTCBVIEWER);
+ HWND hDlg_ChgIcon;
+
+ if (hwndNextViewer == HWND_BROADCAST)
+ break;
+
+ if (hwndNextViewer)
+ {
+ SendMessage(hwndNextViewer, iMsg, wParam, lParam);
+ // Refresh next viewer in case it got modified
+ // by the SendMessage() (likely if multiple
+ // PasteSpecial dialogs are up simultaneously)
+ hwndNextViewer = (HWND)GetProp(hDlg, NEXTCBVIEWER);
+ }
+
+ if (!(lpPS->dwFlags & PSF_STAYONCLIPBOARDCHANGE))
+ {
+ SetProp(hDlg, NEXTCBVIEWER, HWND_BROADCAST);
+ ChangeClipboardChain(hDlg, hwndNextViewer);
+
+ /* OLE2NOTE: if the ChangeIcon dialog is currently up, then
+ ** we need to defer bringing down PasteSpecial dialog
+ ** until after ChangeIcon dialog returns. if the
+ ** ChangeIcon dialog is NOT up, then we can bring down
+ ** the PasteSpecial dialog immediately.
+ */
+ if ((hDlg_ChgIcon=(HWND)GetProp(hDlg,PROP_HWND_CHGICONDLG))!=NULL)
+ {
+ // ChangeIcon dialog is UP
+ lpPS->fClipboardChanged = TRUE;
+ }
+ else
+ {
+ // ChangeIcon dialog is NOT up
+
+ // Free icon and icon title metafile
+ SendDlgItemMessage(
+ hDlg, IDC_PS_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0L);
+ SendMessage(
+ hDlg, uMsgEndDialog, OLEUI_PSERR_CLIPBOARDCHANGED,0L);
+ }
+ }
+ else
+ {
+ // skip refresh, ignoring clipboard change if PSF_NOREFRESHDATAOBJECT
+ if (lpPS->dwFlags & PSF_NOREFRESHDATAOBJECT)
+ break;
+
+ // release current data object
+ if (lpOPS->lpSrcDataObj != NULL)
+ {
+ lpOPS->lpSrcDataObj->Release();
+ lpOPS->lpSrcDataObj = NULL;
+ }
+
+ // obtain new one
+ if (OleGetClipboard(&lpOPS->lpSrcDataObj) != NOERROR)
+ {
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_PSERR_GETCLIPBOARDFAILED, 0);
+ break;
+ }
+
+ // otherwise update the display to the new clipboard object
+ FPasteSpecialReInit(hDlg, lpPS);
+ }
+ }
+ break;
+
+ case WM_CHANGECBCHAIN:
+ {
+ HWND hwndNextViewer = (HWND)GetProp(hDlg, NEXTCBVIEWER);
+ if ((HWND)wParam == hwndNextViewer)
+ SetProp(hDlg, NEXTCBVIEWER, (hwndNextViewer = (HWND)lParam));
+ else if (hwndNextViewer && hwndNextViewer != HWND_BROADCAST)
+ SendMessage(hwndNextViewer, iMsg, wParam, lParam);
+ }
+ break;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDC_PS_PASTE:
+ FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTE);
+ break;
+
+ case IDC_PS_PASTELINK:
+ FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTELINK);
+ break;
+
+ case IDC_PS_DISPLAYLIST:
+ switch (wCode)
+ {
+ case LBN_SELCHANGE:
+ ChangeListSelection(hDlg, lpPS, hWndMsg);
+ break;
+ case LBN_DBLCLK:
+ // Same as pressing OK
+ if (IsWindowEnabled(GetDlgItem(hDlg, IDOK)))
+ SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg);
+ break;
+ }
+ break;
+
+ case IDC_PS_DISPLAYASICON:
+ ToggleDisplayAsIcon(hDlg, lpPS);
+ break;
+
+ case IDC_PS_CHANGEICON:
+ ChangeIcon(hDlg, lpPS);
+ if (lpPS->fClipboardChanged)
+ {
+ // Free icon and icon title metafile
+ SendDlgItemMessage(
+ hDlg, IDC_PS_ICONDISPLAY, IBXM_IMAGEFREE,0,0L);
+ SendMessage(hDlg, uMsgEndDialog,
+ OLEUI_PSERR_CLIPBOARDCHANGED, 0L);
+ }
+ break;
+
+ case IDOK:
+ {
+ BOOL fDestAspectIcon =
+ ((lpPS->dwFlags & PSF_CHECKDISPLAYASICON) ?
+ TRUE : FALSE);
+ // Return current flags
+ lpOPS->dwFlags = lpPS->dwFlags;
+ // Return index of arrPasteEntries[] corresponding to format selected by user
+ lpOPS->nSelectedIndex = lpPS->nSelectedIndex;
+ // Return if user selected Paste or PasteLink
+ lpOPS->fLink = lpPS->fLink;
+
+ /* if user selected same ASPECT as displayed in the
+ ** source, then sizel passed in the
+ ** ObjectDescriptor/LinkSrcDescriptor is
+ ** applicable. otherwise, the sizel does not apply.
+ */
+ if (lpPS->fLink)
+ {
+ if (lpPS->fSrcAspectIconLSD == fDestAspectIcon)
+ lpOPS->sizel = lpPS->sizelLSD;
+ else
+ lpOPS->sizel.cx = lpOPS->sizel.cy = 0;
+ }
+ else
+ {
+ if (lpPS->fSrcAspectIconOD == fDestAspectIcon)
+ lpOPS->sizel = lpPS->sizelOD;
+ else
+ lpOPS->sizel.cx = lpOPS->sizel.cy = 0;
+ }
+ // Return metafile with icon and icon title that the user selected
+ lpOPS->hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg,
+ IDC_PS_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L);
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ }
+ break;
+
+ case IDCANCEL:
+ // Free icon and icon title metafile
+ SendDlgItemMessage(
+ hDlg, IDC_PS_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0L);
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
+ break;
+
+ case IDC_OLEUIHELP:
+ PostMessage(lpPS->lpOPS->hWndOwner, uMsgHelp,
+ (WPARAM)hDlg, MAKELPARAM(IDD_PASTESPECIAL, 0));
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+BOOL FPasteSpecialReInit(HWND hDlg, LPPASTESPECIAL lpPS)
+{
+ LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS;
+
+ // free the icon/icon-title metafiel
+ if (lpPS->fLink)
+ OleUIMetafilePictIconFree(lpPS->hMetaPictOD);
+ else
+ OleUIMetafilePictIconFree(lpPS->hMetaPictLSD);
+
+ // Free data assocatiated with each list box entry
+ FreeListData(GetDlgItem(hDlg, IDC_PS_PASTELIST));
+ FreeListData(GetDlgItem(hDlg, IDC_PS_PASTELINKLIST));
+ SendDlgItemMessage(hDlg, IDC_PS_DISPLAYLIST, LB_RESETCONTENT, 0, 0);
+
+ // Initialize user selections in the Paste and PasteLink listboxes
+ lpPS->nPasteListCurSel = 0;
+ lpPS->nPasteLinkListCurSel = 0;
+
+ // Free previous object descriptor/link descriptor data
+ if (lpPS->hObjDesc != NULL)
+ {
+ GlobalFree(lpPS->hObjDesc);
+ lpPS->hObjDesc = NULL;
+ }
+ if (lpPS->hLinkSrcDesc != NULL)
+ {
+ GlobalFree(lpPS->hLinkSrcDesc);
+ lpPS->hLinkSrcDesc = NULL;
+ }
+
+ lpPS->szAppName[0] = '\0';
+
+ // GetData CF_OBJECTDESCRIPTOR. If the object on the clipboard in an
+ // OLE1 object (offering CF_OWNERLINK) or has been copied to
+ // clipboard by FileMaager (offering CF_FILENAME), an
+ // OBJECTDESCRIPTOR will be created will be created from CF_OWNERLINK
+ // or CF_FILENAME. See OBJECTDESCRIPTOR for more info.
+
+ STGMEDIUM medium;
+ CLIPFORMAT cfFormat;
+ lpPS->hObjDesc = OleStdFillObjectDescriptorFromData(
+ lpOPS->lpSrcDataObj, &medium, &cfFormat);
+ if (lpPS->hObjDesc)
+ {
+ LPOBJECTDESCRIPTOR lpOD = (LPOBJECTDESCRIPTOR)GlobalLock(lpPS->hObjDesc);
+
+ // Get FullUserTypeName, SourceOfCopy and CLSID
+ if (lpOD->dwFullUserTypeName)
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpPS->szFullUserTypeNameOD, (LPWSTR)((LPBYTE)lpOD+lpOD->dwFullUserTypeName), PS_UNKNOWNNAMELEN);
+#else
+ lstrcpyn(lpPS->szFullUserTypeNameOD, (LPTSTR)((LPBYTE)lpOD+lpOD->dwFullUserTypeName), PS_UNKNOWNNAMELEN);
+#endif
+ else
+ lstrcpyn(lpPS->szFullUserTypeNameOD, lpPS->szUnknownType, PS_UNKNOWNNAMELEN);
+
+ if (lpOD->dwSrcOfCopy)
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpPS->szSourceOfDataOD, (LPWSTR)((LPBYTE)lpOD+lpOD->dwSrcOfCopy), PS_UNKNOWNNAMELEN);
+#else
+ lstrcpyn(lpPS->szSourceOfDataOD, (LPTSTR)((LPBYTE)lpOD+lpOD->dwSrcOfCopy), PS_UNKNOWNNAMELEN);
+#endif
+ // If CF_FILENAME was offered, source of copy is a
+ // path name. Fit the path to the static control that will display it.
+ if (cfFormat == _g_cfFileName)
+ {
+ lstrcpyn(lpPS->szSourceOfDataOD, ChopText(GetDlgItem(hDlg, IDC_PS_SOURCETEXT), 0,
+ lpPS->szSourceOfDataOD, 0), PS_UNKNOWNNAMELEN);
+ }
+ }
+ else
+ lstrcpyn(lpPS->szSourceOfDataOD, lpPS->szUnknownSource, PS_UNKNOWNNAMELEN);
+
+ lpPS->clsidOD = lpOD->clsid;
+ lpPS->sizelOD = lpOD->sizel;
+
+ // Does source specify DVASPECT_ICON?
+ if (lpOD->dwDrawAspect & DVASPECT_ICON)
+ lpPS->fSrcAspectIconOD = TRUE;
+ else
+ lpPS->fSrcAspectIconOD = FALSE;
+
+ // Does source specify OLEMISC_ONLYICONIC?
+ if (lpOD->dwStatus & OLEMISC_ONLYICONIC)
+ lpPS->fSrcOnlyIconicOD = TRUE;
+ else
+ lpPS->fSrcOnlyIconicOD = FALSE;
+
+ // Get application name of source from auxusertype3 in the registration database
+ LPOLESTR lpszAppName = NULL;
+ if (OleRegGetUserType(lpPS->clsidOD, USERCLASSTYPE_APPNAME,
+ &lpszAppName) == NOERROR)
+ {
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpPS->szAppName, lpszAppName, OLEUI_CCHKEYMAX);
+#else
+ lstrcpyn(lpPS->szAppName, lpszAppName, OLEUI_CCHKEYMAX);
+#endif
+ OleStdFree(lpszAppName);
+ }
+ else
+ {
+ if (0 == LoadString(_g_hOleStdResInst, IDS_PSUNKNOWNAPP, lpPS->szAppName,
+ PS_UNKNOWNSTRLEN))
+ {
+ PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L);
+ return FALSE;
+ }
+ }
+
+ // Retrieve an icon from the object
+ if (lpPS->fSrcAspectIconOD)
+ {
+ lpPS->hMetaPictOD = OleStdGetData(
+ lpOPS->lpSrcDataObj,
+ (CLIPFORMAT) CF_METAFILEPICT,
+ NULL,
+ DVASPECT_ICON,
+ &medium
+ );
+
+ }
+ // If object does not offer icon, obtain it from the CLSID
+ if (NULL == lpPS->hMetaPictOD)
+ lpPS->hMetaPictOD = OleGetIconOfClass(lpPS->clsidOD, NULL, TRUE);
+ }
+
+ // Does object offer CF_LINKSRCDESCRIPTOR?
+ lpPS->hLinkSrcDesc = OleStdGetData(
+ lpOPS->lpSrcDataObj,
+ (CLIPFORMAT) _g_cfLinkSrcDescriptor,
+ NULL,
+ DVASPECT_CONTENT,
+ &medium);
+ if (lpPS->hLinkSrcDesc)
+ {
+ // Get FullUserTypeName, SourceOfCopy and CLSID
+ LPLINKSRCDESCRIPTOR lpLSD = (LPLINKSRCDESCRIPTOR)GlobalLock(lpPS->hLinkSrcDesc);
+ if (lpLSD->dwFullUserTypeName)
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpPS->szFullUserTypeNameLSD, (LPWSTR)((LPBYTE)lpLSD+lpLSD->dwFullUserTypeName), PS_UNKNOWNNAMELEN);
+#else
+ lstrcpyn(lpPS->szFullUserTypeNameLSD, (LPTSTR)((LPBYTE)lpLSD+lpLSD->dwFullUserTypeName), PS_UNKNOWNNAMELEN);
+#endif
+ else
+ lstrcpyn(lpPS->szFullUserTypeNameLSD, lpPS->szUnknownType, PS_UNKNOWNNAMELEN);
+
+ if (lpLSD->dwSrcOfCopy)
+#if defined(WIN32) && !defined(UNICODE)
+ WTOA(lpPS->szSourceOfDataLSD, (LPWSTR)((LPBYTE)lpLSD+lpLSD->dwSrcOfCopy), PS_UNKNOWNNAMELEN);
+#else
+ lstrcpyn(lpPS->szSourceOfDataLSD, (LPTSTR)((LPBYTE)lpLSD+lpLSD->dwSrcOfCopy), PS_UNKNOWNNAMELEN);
+#endif
+ else
+ lstrcpyn(lpPS->szSourceOfDataLSD, lpPS->szUnknownSource, PS_UNKNOWNNAMELEN);
+
+ // if no ObjectDescriptor, then use LinkSourceDescriptor source string
+ if (!lpPS->hObjDesc)
+ lstrcpyn(lpPS->szSourceOfDataOD, lpPS->szSourceOfDataLSD, PS_UNKNOWNNAMELEN);
+
+ lpPS->clsidLSD = lpLSD->clsid;
+ lpPS->sizelLSD = lpLSD->sizel;
+
+ // Does source specify DVASPECT_ICON?
+ if (lpLSD->dwDrawAspect & DVASPECT_ICON)
+ lpPS->fSrcAspectIconLSD = TRUE;
+ else
+ lpPS->fSrcAspectIconLSD = FALSE;
+
+ // Does source specify OLEMISC_ONLYICONIC?
+ if (lpLSD->dwStatus & OLEMISC_ONLYICONIC)
+ lpPS->fSrcOnlyIconicLSD = TRUE;
+ else
+ lpPS->fSrcOnlyIconicLSD = FALSE;
+
+ // Retrieve an icon from the object
+ if (lpPS->fSrcAspectIconLSD)
+ {
+ lpPS->hMetaPictLSD = OleStdGetData(
+ lpOPS->lpSrcDataObj,
+ CF_METAFILEPICT,
+ NULL,
+ DVASPECT_ICON,
+ &medium
+ );
+ }
+ // If object does not offer icon, obtain it from the CLSID
+ if (NULL == lpPS->hMetaPictLSD)
+ {
+ HWND hIconWnd = GetDlgItem(hDlg, IDC_PS_ICONDISPLAY);
+ RECT IconRect; GetClientRect(hIconWnd, &IconRect);
+
+ LPTSTR lpszLabel = OleStdCopyString(lpPS->szSourceOfDataLSD);
+ // width is 2 times width of iconbox because it can wrap
+ int nWidth = (IconRect.right-IconRect.left) * 2;
+ // limit text to the width or max characters
+ LPTSTR lpszChopLabel = ChopText(hIconWnd, nWidth, lpszLabel,
+ lstrlen(lpszLabel));
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszChopLabel[MAX_PATH];
+ ATOW(wszChopLabel, lpszChopLabel, MAX_PATH);
+ lpPS->hMetaPictLSD =
+ OleGetIconOfClass(lpPS->clsidLSD, wszChopLabel, FALSE);
+#else
+ lpPS->hMetaPictLSD =
+ OleGetIconOfClass(lpPS->clsidLSD, lpszChopLabel, FALSE);
+#endif
+ OleStdFree(lpszLabel);
+ }
+ }
+ else if (lpPS->hObjDesc) // Does not offer CF_LINKSRCDESCRIPTOR but offers CF_OBJECTDESCRIPTOR
+ {
+ // Copy the values of OBJECTDESCRIPTOR
+ lstrcpyn(lpPS->szFullUserTypeNameLSD, lpPS->szFullUserTypeNameOD, PS_UNKNOWNNAMELEN);
+ lstrcpyn(lpPS->szSourceOfDataLSD, lpPS->szSourceOfDataOD, PS_UNKNOWNNAMELEN);
+ lpPS->clsidLSD = lpPS->clsidOD;
+ lpPS->sizelLSD = lpPS->sizelOD;
+ lpPS->fSrcAspectIconLSD = lpPS->fSrcAspectIconOD;
+ lpPS->fSrcOnlyIconicLSD = lpPS->fSrcOnlyIconicOD;
+
+ // Don't copy the hMetaPict; instead get a separate copy
+ if (lpPS->fSrcAspectIconLSD)
+ {
+ lpPS->hMetaPictLSD = OleStdGetData(
+ lpOPS->lpSrcDataObj,
+ CF_METAFILEPICT,
+ NULL,
+ DVASPECT_ICON,
+ &medium
+ );
+ }
+ if (NULL == lpPS->hMetaPictLSD)
+ {
+ HWND hIconWnd = GetDlgItem(hDlg, IDC_PS_ICONDISPLAY);
+ RECT IconRect; GetClientRect(hIconWnd, &IconRect);
+
+ LPTSTR lpszLabel = OleStdCopyString(lpPS->szSourceOfDataLSD);
+ // width is 2 times width of iconbox because it can wrap
+ int nWidth = (IconRect.right-IconRect.left) * 2;
+ // limit text to the width or max characters
+ LPTSTR lpszChopLabel = ChopText(hIconWnd, nWidth, lpszLabel,
+ lstrlen(lpszLabel));
+#if defined(WIN32) && !defined(UNICODE)
+ OLECHAR wszChopLabel[MAX_PATH];
+ ATOW(wszChopLabel, lpszChopLabel, MAX_PATH);
+ lpPS->hMetaPictLSD =
+ OleGetIconOfClass(lpPS->clsidLSD, wszChopLabel, FALSE);
+#else
+ lpPS->hMetaPictLSD =
+ OleGetIconOfClass(lpPS->clsidLSD, lpszChopLabel, FALSE);
+#endif
+ OleStdFree(lpszLabel);
+ }
+ }
+
+ // Not an OLE object
+ if (lpPS->hObjDesc == NULL && lpPS->hLinkSrcDesc == NULL)
+ {
+ lstrcpyn(lpPS->szFullUserTypeNameLSD, lpPS->szUnknownType, PS_UNKNOWNNAMELEN);
+ lstrcpyn(lpPS->szFullUserTypeNameOD, lpPS->szUnknownType, PS_UNKNOWNNAMELEN);
+ lstrcpyn(lpPS->szSourceOfDataLSD, lpPS->szUnknownSource, PS_UNKNOWNNAMELEN);
+ lstrcpyn(lpPS->szSourceOfDataOD, lpPS->szUnknownSource, PS_UNKNOWNNAMELEN);
+ lpPS->hMetaPictLSD = lpPS->hMetaPictOD = NULL;
+ }
+
+ // Allocate scratch memory to construct item names in the paste and pastelink listboxes
+ if (lpPS->hBuff != NULL)
+ {
+ GlobalFree(lpPS->hBuff);
+ lpPS->hBuff = NULL;
+ }
+
+ lpPS->hBuff = AllocateScratchMem(lpPS);
+ if (lpPS->hBuff == NULL)
+ {
+ PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L);
+ return FALSE;
+ }
+
+ // Select the Paste Link Button if specified. Otherwise select
+ // Paste Button by default
+ if (lpPS->dwFlags & PSF_SELECTPASTELINK)
+ lpPS->dwFlags = (lpPS->dwFlags & ~PSF_SELECTPASTE) | PSF_SELECTPASTELINK;
+ else
+ lpPS->dwFlags =(lpPS->dwFlags & ~PSF_SELECTPASTELINK) | PSF_SELECTPASTE;
+
+ // Mark which PasteEntry formats are available from source data object
+ OleStdMarkPasteEntryList(
+ lpOPS->lpSrcDataObj, lpOPS->arrPasteEntries, lpOPS->cPasteEntries);
+
+ // Check if items are available to be pasted
+ BOOL fPasteAvailable = FFillPasteList(hDlg, lpPS);
+ if (!fPasteAvailable)
+ lpPS->dwFlags &= ~PSF_SELECTPASTE;
+ StandardEnableDlgItem(hDlg, IDC_PS_PASTE, fPasteAvailable);
+
+ // Check if items are available to be paste-linked
+ BOOL fPasteLinkAvailable = FFillPasteLinkList(hDlg, lpPS);
+ if (!fPasteLinkAvailable)
+ lpPS->dwFlags &= ~PSF_SELECTPASTELINK;
+ StandardEnableDlgItem(hDlg, IDC_PS_PASTELINK, fPasteLinkAvailable);
+
+ // If one of Paste or PasteLink is disabled, select the other one
+ // regardless of what the input flags say
+ if (fPasteAvailable && !fPasteLinkAvailable)
+ lpPS->dwFlags |= PSF_SELECTPASTE;
+ if (fPasteLinkAvailable && !fPasteAvailable)
+ lpPS->dwFlags |= PSF_SELECTPASTELINK;
+
+ BOOL bEnabled = TRUE;
+ if (lpPS->dwFlags & PSF_SELECTPASTE)
+ {
+ // FTogglePaste will set the PSF_SELECTPASTE flag, so clear it.
+ lpPS->dwFlags &= ~PSF_SELECTPASTE;
+ CheckRadioButton(hDlg, IDC_PS_PASTE, IDC_PS_PASTELINK, IDC_PS_PASTE);
+ FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTE);
+ }
+ else if (lpPS->dwFlags & PSF_SELECTPASTELINK)
+ {
+ // FTogglePaste will set the PSF_SELECTPASTELINK flag, so clear it.
+ lpPS->dwFlags &= ~PSF_SELECTPASTELINK;
+ CheckRadioButton(hDlg, IDC_PS_PASTE, IDC_PS_PASTELINK, IDC_PS_PASTELINK);
+ FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTELINK);
+ }
+ else // Items are not available to be be Pasted or Paste-Linked
+ {
+ // Enable or disable DisplayAsIcon and set the result text and image
+ EnableDisplayAsIcon(hDlg, lpPS);
+ SetPasteSpecialHelpResults(hDlg, lpPS);
+ SetDlgItemText(hDlg, IDC_PS_SOURCETEXT, lpPS->szSourceOfDataOD);
+ CheckRadioButton(hDlg, IDC_PS_PASTE, IDC_PS_PASTELINK, 0);
+ bEnabled = FALSE;
+ }
+ StandardEnableDlgItem(hDlg, IDOK, bEnabled);
+
+ return TRUE;
+}
+
+/*
+ * FPasteSpecialInit
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the Paste Special dialog box.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+BOOL FPasteSpecialInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ // Copy the structure at lParam into our instance memory.
+ HFONT hFont;
+ LPPASTESPECIAL lpPS = (LPPASTESPECIAL)LpvStandardInit(hDlg, sizeof(PASTESPECIAL), &hFont);
+
+ // PvStandardInit sent a termination to us already.
+ if (NULL == lpPS)
+ return FALSE;
+
+ LPOLEUIPASTESPECIAL lpOPS = (LPOLEUIPASTESPECIAL)lParam;
+
+ // Copy other information from lpOPS that we might modify.
+ lpPS->lpOPS = lpOPS;
+ lpPS->nIDD = IDD_PASTESPECIAL;
+ lpPS->dwFlags = lpOPS->dwFlags;
+
+ // If we got a font, send it to the necessary controls.
+ if (NULL!=hFont)
+ {
+ SendDlgItemMessage(hDlg, IDC_PS_SOURCETEXT, WM_SETFONT, (WPARAM)hFont, 0L);
+ SendDlgItemMessage(hDlg, IDC_PS_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L);
+ }
+
+ // Hide the help button if required
+ if (!(lpPS->lpOPS->dwFlags & PSF_SHOWHELP))
+ StandardShowDlgItem(hDlg, IDC_OLEUIHELP, SW_HIDE);
+
+ // Show or hide the Change icon button
+ if (lpPS->dwFlags & PSF_HIDECHANGEICON)
+ DestroyWindow(GetDlgItem(hDlg, IDC_PS_CHANGEICON));
+
+ // Hide all DisplayAsIcon related controls if it should be disabled
+ if (lpPS->dwFlags & PSF_DISABLEDISPLAYASICON)
+ {
+ StandardShowDlgItem(hDlg, IDC_PS_DISPLAYASICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_PS_CHANGEICON, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, SW_HIDE);
+ }
+
+ // clear PSF_CHECKDISPLAYASICON -> it's an output parameter only
+ lpPS->dwFlags &= ~ PSF_CHECKDISPLAYASICON;
+
+ // Change the caption if required
+ if (NULL != lpOPS->lpszCaption)
+ SetWindowText(hDlg, lpOPS->lpszCaption);
+
+ // Load 'Unknown Source' and 'Unknown Type' strings
+ int n = LoadString(_g_hOleStdResInst, IDS_PSUNKNOWNTYPE, lpPS->szUnknownType, PS_UNKNOWNSTRLEN);
+ if (n)
+ n = LoadString(_g_hOleStdResInst, IDS_PSUNKNOWNSRC, lpPS->szUnknownSource, PS_UNKNOWNSTRLEN);
+ if (!n)
+ {
+ PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L);
+ return FALSE;
+ }
+
+ if (!FPasteSpecialReInit(hDlg, lpPS))
+ return FALSE;
+
+ // Give initial focus to the list box
+ SetFocus(GetDlgItem(hDlg, IDC_PS_DISPLAYLIST));
+
+ // Set property to handle clipboard change notifications
+ SetProp(hDlg, NEXTCBVIEWER, HWND_BROADCAST);
+ SetProp(hDlg, NEXTCBVIEWER, SetClipboardViewer(hDlg));
+
+ lpPS->fClipboardChanged = FALSE;
+
+ /*
+ * PERFORM OTHER INITIALIZATION HERE.
+ */
+
+ // Call the hook with lCustData in lParam
+ UStandardHook(lpPS, hDlg, WM_INITDIALOG, wParam, lpOPS->lCustData);
+ return TRUE;
+}
+
+/*
+ * FTogglePasteType
+ *
+ * Purpose:
+ * Toggles between Paste and Paste Link. The Paste list and PasteLink
+ * list are always invisible. The Display List is filled from either
+ * the Paste list or the PasteLink list depending on which Paste radio
+ * button is selected.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ * dwOption Paste or PasteSpecial option
+ *
+ * Return Value:
+ * BOOL Returns TRUE if the option has already been selected.
+ * Otherwise the option is selected and FALSE is returned
+ */
+BOOL FTogglePasteType(HWND hDlg, LPPASTESPECIAL lpPS, DWORD dwOption)
+{
+ DWORD dwTemp;
+ HWND hList, hListDisplay;
+ DWORD dwData;
+ int i, nItems;
+ LPTSTR lpsz;
+
+ // Skip all this if the button is already selected
+ if (lpPS->dwFlags & dwOption)
+ return TRUE;
+
+ dwTemp = PSF_SELECTPASTE | PSF_SELECTPASTELINK;
+ lpPS->dwFlags = (lpPS->dwFlags & ~dwTemp) | dwOption;
+
+ // Hide IconDisplay. This prevents flashing if the icon display is changed
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, SW_HIDE);
+
+ hListDisplay = GetDlgItem(hDlg, IDC_PS_DISPLAYLIST);
+
+ // If Paste was selected
+ if (lpPS->dwFlags & PSF_SELECTPASTE)
+ {
+ // Set the Source of the object in the clipboard
+ SetDlgItemText(hDlg, IDC_PS_SOURCETEXT, lpPS->szSourceOfDataOD);
+
+ // If an icon is available
+ if (lpPS->hMetaPictOD)
+ // Set the icon display
+ SendDlgItemMessage(hDlg, IDC_PS_ICONDISPLAY, IBXM_IMAGESET,
+ 0, (LPARAM)lpPS->hMetaPictOD);
+
+ hList = GetDlgItem(hDlg, IDC_PS_PASTELIST);
+ // We are switching from PasteLink to Paste. Remember current selection
+ // in PasteLink list so it can be restored.
+ lpPS->nPasteLinkListCurSel = (int)SendMessage(hListDisplay, LB_GETCURSEL, 0, 0L);
+ if (lpPS->nPasteLinkListCurSel == LB_ERR)
+ lpPS->nPasteLinkListCurSel = 0;
+ // Remember if user selected Paste or PasteLink
+ lpPS->fLink = FALSE;
+ }
+ else // If PasteLink was selected
+ {
+ // Set the Source of the object in the clipboard
+ SetDlgItemText(hDlg, IDC_PS_SOURCETEXT, lpPS->szSourceOfDataLSD);
+
+ // If an icon is available
+ if (lpPS->hMetaPictLSD)
+ // Set the icon display
+ SendDlgItemMessage(hDlg, IDC_PS_ICONDISPLAY, IBXM_IMAGESET,
+ 0, (LPARAM)lpPS->hMetaPictLSD);
+
+ hList = GetDlgItem(hDlg, IDC_PS_PASTELINKLIST);
+ // We are switching from Paste to PasteLink. Remember current selection
+ // in Paste list so it can be restored.
+ lpPS->nPasteListCurSel = (int)SendMessage(hListDisplay, LB_GETCURSEL, 0, 0L);
+ if (lpPS->nPasteListCurSel == LB_ERR)
+ lpPS->nPasteListCurSel = 0;
+ // Remember if user selected Paste or PasteLink
+ lpPS->fLink = TRUE;
+ }
+
+ // Turn drawing off while the Display List is being filled
+ SendMessage(hListDisplay, WM_SETREDRAW, (WPARAM)FALSE, 0L);
+
+ // Move data to Display list box
+ SendMessage(hListDisplay, LB_RESETCONTENT, 0, 0L);
+ nItems = (int) SendMessage(hList, LB_GETCOUNT, 0, 0L);
+ lpsz = (LPTSTR)GlobalLock(lpPS->hBuff);
+ for (i = 0; i < nItems; i++)
+ {
+ SendMessage(hList, LB_GETTEXT, (WPARAM)i, (LPARAM)lpsz);
+ dwData = SendMessage(hList, LB_GETITEMDATA, (WPARAM)i, 0L);
+ SendMessage(hListDisplay, LB_INSERTSTRING, (WPARAM)i, (LPARAM)lpsz);
+ SendMessage(hListDisplay, LB_SETITEMDATA, (WPARAM)i, dwData);
+ }
+ GlobalUnlock(lpPS->hBuff);
+
+ // Restore the selection in the Display List from user's last selection
+ if (lpPS->dwFlags & PSF_SELECTPASTE)
+ SendMessage(hListDisplay, LB_SETCURSEL, lpPS->nPasteListCurSel, 0L);
+ else
+ SendMessage(hListDisplay, LB_SETCURSEL, lpPS->nPasteLinkListCurSel, 0L);
+
+ // Paint Display List
+ SendMessage(hListDisplay, WM_SETREDRAW, (WPARAM)TRUE, 0L);
+ InvalidateRect(hListDisplay, NULL, TRUE);
+ UpdateWindow(hListDisplay);
+
+ // Auto give the focus to the Display List
+ if (GetForegroundWindow() == hDlg)
+ SetFocus(hListDisplay);
+
+ // Enable/Disable DisplayAsIcon and set the help result text and bitmap corresponding to
+ // the current selection
+ ChangeListSelection(hDlg, lpPS, hListDisplay);
+
+ return FALSE;
+}
+
+/*
+ * ChangeListSelection
+ *
+ * Purpose:
+ * When the user changes the selection in the list, DisplayAsIcon is enabled or disabled,
+ * Result text and bitmap are updated and the index of the arrPasteEntries[] corresponding
+ * to the current format selection is saved.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ * hList HWND of the List
+ *
+ * Return Value:
+ * No return value
+ */
+void ChangeListSelection(HWND hDlg, LPPASTESPECIAL lpPS, HWND hList)
+{
+ LPPASTELISTITEMDATA lpItemData;
+ int nCurSel;
+
+ EnableDisplayAsIcon(hDlg, lpPS);
+ SetPasteSpecialHelpResults(hDlg, lpPS);
+
+ // Remember index of arrPasteEntries[] corresponding to the current selection
+ nCurSel = (int)SendMessage(hList, LB_GETCURSEL, 0, 0L);
+ if (nCurSel == LB_ERR)
+ return;
+ lpItemData = (LPPASTELISTITEMDATA) SendMessage(hList, LB_GETITEMDATA,
+ (WPARAM)nCurSel, 0L);
+ if ((LRESULT)lpItemData == LB_ERR)
+ return;
+ lpPS->nSelectedIndex = lpItemData->nPasteEntriesIndex;
+}
+
+/*
+ * EnableDisplayAsIcon
+ *
+ * Purpose:
+ * Enable or disable the DisplayAsIcon button depending on whether
+ * the current selection can be displayed as an icon or not. The following table describes
+ * the state of DisplayAsIcon. The calling application is termed CONTAINER, the source
+ * of data on the clipboard is termed SOURCE.
+ * Y = Yes; N = No; Blank = State does not matter;
+ * =====================================================================
+ * SOURCE SOURCE CONTAINER DisplayAsIcon
+ * specifies specifies specifies Initial State
+ * DVASPECT_ICON OLEMISC_ONLYICONIC OLEUIPASTE_ENABLEICON
+ *
+ * N Unchecked&Disabled
+ * Y Y Checked&Disabled
+ * Y N Y Checked&Enabled
+ * N N Y Unchecked&Enabled
+ * =====================================================================
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ *
+ * Return Value:
+ * No return value
+ */
+void EnableDisplayAsIcon(HWND hDlg, LPPASTESPECIAL lpPS)
+{
+ int nIndex;
+ BOOL fCntrEnableIcon;
+ BOOL fSrcOnlyIconic = (lpPS->fLink) ? lpPS->fSrcOnlyIconicLSD : lpPS->fSrcOnlyIconicOD;
+ BOOL fSrcAspectIcon = (lpPS->fLink) ? lpPS->fSrcAspectIconLSD : lpPS->fSrcAspectIconOD;
+ HWND hList;
+ LPPASTELISTITEMDATA lpItemData;
+ HGLOBAL hMetaPict = (lpPS->fLink) ? lpPS->hMetaPictLSD : lpPS->hMetaPictOD;
+
+ hList = GetDlgItem(hDlg, IDC_PS_DISPLAYLIST);
+
+ // Get data corresponding to the current selection in the listbox
+ nIndex = (int)SendMessage(hList, LB_GETCURSEL, 0, 0);
+ if (nIndex != LB_ERR)
+ {
+ lpItemData = (LPPASTELISTITEMDATA) SendMessage(hList, LB_GETITEMDATA, (WPARAM)nIndex, 0L);
+ if ((LRESULT)lpItemData != LB_ERR)
+ fCntrEnableIcon = lpItemData->fCntrEnableIcon;
+ else fCntrEnableIcon = FALSE;
+ }
+ else fCntrEnableIcon = FALSE;
+
+ // If there is an icon available
+ if (hMetaPict != NULL)
+ {
+ if (!fCntrEnableIcon) // Does CONTAINER specify OLEUIPASTE_ENABLEICON?
+ {
+ // Uncheck & Disable DisplayAsIcon
+ lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON;
+ CheckDlgButton(hDlg, IDC_PS_DISPLAYASICON, FALSE);
+ StandardEnableDlgItem(hDlg, IDC_PS_DISPLAYASICON, FALSE);
+
+ // Hide IconDisplay and ChangeIcon button
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_PS_CHANGEICON, SW_HIDE);
+ }
+ else if (fSrcOnlyIconic) // Does SOURCE specify OLEMISC_ONLYICONIC?
+ {
+ // Check & Disable DisplayAsIcon
+ lpPS->dwFlags |= PSF_CHECKDISPLAYASICON;
+ CheckDlgButton(hDlg, IDC_PS_DISPLAYASICON, TRUE);
+ StandardEnableDlgItem(hDlg, IDC_PS_DISPLAYASICON, FALSE);
+
+ // Show IconDisplay and ChangeIcon button
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, SW_SHOWNORMAL);
+ StandardShowDlgItem(hDlg, IDC_PS_CHANGEICON, SW_SHOWNORMAL);
+ }
+ else if (fSrcAspectIcon) // Does SOURCE specify DVASPECT_ICON?
+ {
+ // Check & Enable DisplayAsIcon
+ lpPS->dwFlags |= PSF_CHECKDISPLAYASICON;
+ CheckDlgButton(hDlg, IDC_PS_DISPLAYASICON, TRUE);
+ StandardEnableDlgItem(hDlg, IDC_PS_DISPLAYASICON, TRUE);
+
+ // Show IconDisplay and ChangeIcon button
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, SW_SHOWNORMAL);
+ StandardShowDlgItem(hDlg, IDC_PS_CHANGEICON, SW_SHOWNORMAL);
+ }
+ else
+ {
+ //Uncheck and Enable DisplayAsIcon
+ lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON;
+ CheckDlgButton(hDlg, IDC_PS_DISPLAYASICON, FALSE);
+ StandardEnableDlgItem(hDlg, IDC_PS_DISPLAYASICON, TRUE);
+
+ // Hide IconDisplay and ChangeIcon button
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_PS_CHANGEICON, SW_HIDE);
+
+ }
+ }
+ else // No icon available
+ {
+ // Unchecked & Disabled
+ lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON;
+ CheckDlgButton(hDlg, IDC_PS_DISPLAYASICON, FALSE);
+ StandardEnableDlgItem(hDlg, IDC_PS_DISPLAYASICON, FALSE);
+
+ // Hide IconDisplay and ChangeIcon button
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, SW_HIDE);
+ StandardShowDlgItem(hDlg, IDC_PS_CHANGEICON, SW_HIDE);
+ }
+}
+
+/*
+ * ToggleDisplayAsIcon
+ *
+ * Purpose:
+ * Toggles the DisplayAsIcon button. Hides or shows the Icon Display and
+ * the ChangeIcon button and changes the help result text and bitmap.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ *
+ * Return Value:
+ * None
+ *
+ */
+void ToggleDisplayAsIcon(HWND hDlg, LPPASTESPECIAL lpPS)
+{
+ BOOL fCheck;
+ int i;
+
+ fCheck = IsDlgButtonChecked(hDlg, IDC_PS_DISPLAYASICON);
+
+ if (fCheck)
+ lpPS->dwFlags |= PSF_CHECKDISPLAYASICON;
+ else lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON;
+
+ // Set the help result text and bitmap
+ SetPasteSpecialHelpResults(hDlg, lpPS);
+
+ // Show or hide the Icon Display and ChangeIcon button depending
+ // on the check state
+ i = (fCheck) ? SW_SHOWNORMAL : SW_HIDE;
+ StandardShowDlgItem(hDlg, IDC_PS_ICONDISPLAY, i);
+ StandardShowDlgItem(hDlg, IDC_PS_CHANGEICON, i);
+}
+
+/*
+ * ChangeIcon
+ *
+ * Purpose:
+ * Brings up the ChangeIcon dialog which allows the user to change
+ * the icon and label.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ *
+ * Return Value:
+ * None
+ *
+ */
+
+void ChangeIcon(HWND hDlg, LPPASTESPECIAL lpPS)
+{
+ OLEUICHANGEICON ci;
+ UINT uRet;
+ CLSID clsid = (lpPS->fLink) ? lpPS->clsidLSD : lpPS->clsidOD;
+
+ //Initialize the structure
+ memset((LPOLEUICHANGEICON)&ci, 0, sizeof(ci));
+
+ ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, IDC_PS_ICONDISPLAY,
+ IBXM_IMAGEGET, 0, 0L);
+ ci.cbStruct = sizeof(ci);
+ ci.hWndOwner = hDlg;
+ ci.clsid = clsid;
+ ci.dwFlags = CIF_SELECTCURRENT;
+
+ // Only show help in the ChangeIcon dialog if we're showing it in this dialog.
+ if (lpPS->dwFlags & PSF_SHOWHELP)
+ ci.dwFlags |= CIF_SHOWHELP;
+
+ // Let the hook in to customize Change Icon if desired.
+ uRet = UStandardHook(lpPS, hDlg, uMsgChangeIcon, 0, (LPARAM)&ci);
+
+ if (0 == uRet)
+ uRet=(UINT)(OLEUI_OK==OleUIChangeIcon(&ci));
+
+ // Update the display if necessary.
+ if (0!=uRet)
+ {
+ /*
+ * OleUIChangeIcon will have already freed our
+ * current hMetaPict that we passed in when OK is
+ * pressed in that dialog. So we use 0L as lParam
+ * here so the IconBox doesn't try to free the
+ * metafilepict again.
+ */
+ SendDlgItemMessage(hDlg, IDC_PS_ICONDISPLAY,
+ IBXM_IMAGESET, 0, (LPARAM)ci.hMetaPict);
+ // Remember the new icon chosen by the user. Note that Paste and PasteLink have separate
+ // icons - changing one does not change the other.
+ if (lpPS->fLink)
+ lpPS->hMetaPictLSD = ci.hMetaPict;
+ else
+ lpPS->hMetaPictOD = ci.hMetaPict;
+ }
+}
+
+/*
+ *SetPasteSpecialHelpResults
+ *
+ * Purpose:
+ * Sets the help result text and bitmap according to the current
+ * list selection. The following state table indicates which ResultText
+ * and ResultImage are selected. If %s in the lpstrFormatName is present,
+ * it is assumed that an object is being pasted/paste-linked, otherwise it
+ * is assumed that data is being pasted/paste-linked.
+ * Y = Yes; N = No; Blank = State does not matter;
+ * The numbers in the the ResultText and ResultImage columns refer to the table
+ * entries that follow.
+ * =====================================================================
+ * Paste/ lpstrFormatName in DisplayAsIcon Result Result
+ * PasteLink arrPasteEntry[]contains %s checked Text Image
+ * (Is Object == Y, Is Data == N)
+ * Paste N 1 1
+ * Paste Y N 2 2
+ * Paste Y Y 3 3
+ * PasteLink N 4 4
+ * PasteLink Y N 5 4
+ * PasteLink Y Y 6 5
+ * =====================================================================
+ * Result Text:
+ *
+ * 1. "Inserts the contents of the Clipboard into your document as <native type name,
+ * and optionally an additional help sentence>"
+ * 2. "Inserts the contents of the Clipboard into your document so that you may
+ * activate it using <object app name>"
+ * 3. "Inserts the contents of the Clipboard into your document so that you may
+ * activate it using <object app name>. It will be displayed as an icon."
+ * 4. "Inserts the contents of the Clipboard into your document as <native type name>.
+ * Paste Link creates a link to the source file so that changes to the source file
+ * will be reflected in your document."
+ * 5. "Inserts a picture of the Clipboard contents into your document. Paste Link
+ * creates a link to the source file so that changes to the source file will be
+ * reflected in your document."
+ * 6. "Inserts an icon into your document which represents the Clipboard contents.
+ * Paste Link creates a link to the source file so that changes to the source file
+ * will be reflected in your document."
+ * =====================================================================
+ * Result Image:
+ *
+ * 1. Clipboard Image
+ * 2. Paste image, non-iconic.
+ * 3. Paste image, iconic.
+ * 4. Paste Link image, non-iconic
+ * 5. Paste Link image, iconic
+ * ====================================================================
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ *
+ * Return Value:
+ * No return value
+ */
+void SetPasteSpecialHelpResults(HWND hDlg, LPPASTESPECIAL lpPS)
+{
+ LPTSTR psz1, psz2, psz3, psz4;
+ UINT i, iString, iImage, cch;
+ int nPasteEntriesIndex;
+ BOOL fDisplayAsIcon;
+ BOOL fIsObject;
+ HWND hList;
+ LPPASTELISTITEMDATA lpItemData;
+ LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS;
+ LPTSTR szFullUserTypeName = (lpPS->fLink) ?
+ lpPS->szFullUserTypeNameLSD : lpPS->szFullUserTypeNameOD;
+ LPTSTR szInsert;
+
+ hList = GetDlgItem(hDlg, IDC_PS_DISPLAYLIST);
+
+ i=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L);
+ if (i != LB_ERR)
+ {
+ lpItemData = (LPPASTELISTITEMDATA)SendMessage(hList, LB_GETITEMDATA, i, 0L);
+ if ((LRESULT)lpItemData == LB_ERR) return;
+ nPasteEntriesIndex = lpItemData->nPasteEntriesIndex;
+ // Check if there is a '%s' in the lpstrFormatName, then an object is being
+ // pasted/pastelinked. Otherwise Data is being pasted-pastelinked.
+ fIsObject = FHasPercentS(lpOPS->arrPasteEntries[nPasteEntriesIndex].lpstrFormatName,
+ lpPS);
+ }
+ else
+ return;
+
+ // Is DisplayAsIcon checked?
+ fDisplayAsIcon=(0L!=(lpPS->dwFlags & PSF_CHECKDISPLAYASICON));
+
+ szInsert = szFullUserTypeName;
+
+ if (lpPS->dwFlags & PSF_SELECTPASTE) // If user selected Paste
+ {
+ if (fIsObject)
+ {
+ iString = fDisplayAsIcon ? IDS_PSPASTEOBJECTASICON : IDS_PSPASTEOBJECT;
+ iImage = fDisplayAsIcon ? RESULTIMAGE_EMBEDICON : RESULTIMAGE_EMBED;
+ szInsert = lpPS->szAppName;
+ }
+ else
+ {
+ iString = IDS_PSPASTEDATA;
+ iImage = RESULTIMAGE_PASTE;
+ }
+ }
+ else if (lpPS->dwFlags & PSF_SELECTPASTELINK) // User selected PasteLink
+ {
+ if (fIsObject)
+ {
+ iString = fDisplayAsIcon ? IDS_PSPASTELINKOBJECTASICON : IDS_PSPASTELINKOBJECT;
+ iImage = fDisplayAsIcon ? RESULTIMAGE_LINKICON : RESULTIMAGE_LINK;
+ }
+ else
+ {
+ iString = IDS_PSPASTELINKDATA;
+ iImage = RESULTIMAGE_LINK;
+ }
+
+ }
+ else // Should never occur.
+ {
+ iString = IDS_PSNONOLE;
+ iImage = RESULTIMAGE_PASTE;
+ }
+
+ // hBuff contains enough space for the 4 buffers required to build up the help
+ // result text.
+ cch = (UINT)(GlobalSize(lpPS->hBuff) / sizeof(TCHAR)) / 4;
+
+ psz1 = (LPTSTR)GlobalLock(lpPS->hBuff);
+ psz2 = psz1 + cch;
+ psz3 = psz2 + cch;
+ psz4 = psz3 + cch;
+
+ // Default is an empty string.
+ *psz1 = 0;
+
+ if (0 != LoadString(_g_hOleStdResInst, iString, psz1, cch) &&
+ nPasteEntriesIndex != -1)
+ {
+ // Insert the FullUserTypeName of the source object into the partial result text
+ // specified by the container.
+ wsprintf(psz3, lpOPS->arrPasteEntries[nPasteEntriesIndex].lpstrResultText,
+ (LPTSTR)szInsert);
+ // Insert the above partial result text into the standard result text.
+ wsprintf(psz4, psz1, (LPTSTR)psz3);
+ psz1 = psz4;
+ }
+
+ // If LoadString failed, we simply clear out the results (*psz1 = 0 above)
+ SetDlgItemText(hDlg, IDC_PS_RESULTTEXT, psz1);
+
+ GlobalUnlock(lpPS->hBuff);
+
+ // Change the result bitmap
+ SendDlgItemMessage(hDlg, IDC_PS_RESULTIMAGE, RIM_IMAGESET, iImage, 0L);
+}
+
+/*
+ * FAddPasteListItem
+ *
+ * Purpose:
+ * Adds an item to the list box
+ *
+ * Parameters:
+ * hList HWND List into which item is to be added
+ * fInsertFirst BOOL Insert in the beginning of the list?
+ * nPasteEntriesIndex int Index of Paste Entry array this list item corresponsds to
+ * lpPS Paste Special Dialog Structure
+ * lpszBuf LPSTR Scratch buffer to build up string for list entry
+ * lpszFullUserTypeName LPSTR full user type name for object entry
+ *
+ * Return Value:
+ * BOOL TRUE if sucessful.
+ * FALSE if unsucessful.
+ */
+BOOL FAddPasteListItem(
+ HWND hList, BOOL fInsertFirst, int nPasteEntriesIndex,
+ LPPASTESPECIAL lpPS, LPTSTR lpszBuf, LPTSTR lpszFullUserTypeName)
+{
+ LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS;
+ LPPASTELISTITEMDATA lpItemData;
+ int nIndex;
+
+ // Allocate memory for each list box item
+ lpItemData = (LPPASTELISTITEMDATA)OleStdMalloc(sizeof(PASTELISTITEMDATA));
+ if (NULL == lpItemData)
+ return FALSE;
+
+ // Fill data associated with each list box item
+ lpItemData->nPasteEntriesIndex = nPasteEntriesIndex;
+ lpItemData->fCntrEnableIcon = ((lpOPS->arrPasteEntries[nPasteEntriesIndex].dwFlags &
+ OLEUIPASTE_ENABLEICON) ? TRUE : FALSE);
+
+ // Build list box entry string, insert the string and add the data the corresponds to it
+ wsprintf(
+ lpszBuf,
+ lpOPS->arrPasteEntries[nPasteEntriesIndex].lpstrFormatName,
+ lpszFullUserTypeName
+ );
+
+ // only add to listbox if not a duplicate
+ if (LB_ERR!=SendMessage(hList,LB_FINDSTRING, 0, (LPARAM)lpszBuf))
+ {
+ // item is already in list; SKIP this one
+ OleStdFree((LPVOID)lpItemData);
+ return TRUE; // this is NOT an error
+ }
+
+ nIndex = (int)SendMessage(
+ hList,
+ (fInsertFirst ? LB_INSERTSTRING : LB_ADDSTRING),
+ 0,
+ (LPARAM)lpszBuf
+ );
+ SendMessage(
+ hList,
+ LB_SETITEMDATA,
+ nIndex,
+ (LPARAM)(LPPASTELISTITEMDATA)lpItemData
+ );
+ return TRUE;
+}
+
+
+/*
+ * FFillPasteList
+ *
+ * Purpose:
+ * Fills the invisible paste list with the formats offered by the clipboard object and
+ * asked for by the container.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ *
+ * Return Value:
+ * BOOL TRUE if sucessful and if formats could be found.
+ * FALSE if unsucessful or if no formats could be found.
+ */
+BOOL FFillPasteList(HWND hDlg, LPPASTESPECIAL lpPS)
+{
+ LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS;
+ HWND hList;
+ int i, j;
+ int nItems = 0;
+ int nDefFormat = -1;
+ BOOL fTryObjFmt = FALSE;
+ BOOL fInsertFirst;
+ BOOL fExclude;
+
+ hList = GetDlgItem(hDlg, IDC_PS_PASTELIST);
+ SendMessage(hList, LB_RESETCONTENT, 0, 0);
+
+ // Loop over the target's priority list of formats
+ for (i = 0; i < lpOPS->cPasteEntries; i++)
+ {
+ if (lpOPS->arrPasteEntries[i].dwFlags != OLEUIPASTE_PASTEONLY &&
+ !(lpOPS->arrPasteEntries[i].dwFlags & OLEUIPASTE_PASTE))
+ continue;
+
+ fInsertFirst = FALSE;
+
+ if (lpOPS->arrPasteEntries[i].fmtetc.cfFormat == _g_cfFileName
+ || lpOPS->arrPasteEntries[i].fmtetc.cfFormat == _g_cfEmbeddedObject
+ || lpOPS->arrPasteEntries[i].fmtetc.cfFormat == _g_cfEmbedSource)
+ {
+ if (! fTryObjFmt)
+ {
+ fTryObjFmt = TRUE; // only use 1st object format
+ fInsertFirst = TRUE; // OLE obj format should always be 1st
+
+ //Check if this CLSID is in the exclusion list.
+ fExclude=FALSE;
+
+ for (j=0; j < (int)lpOPS->cClsidExclude; j++)
+ {
+ if (IsEqualCLSID(lpPS->clsidOD, lpOPS->lpClsidExclude[j]))
+ {
+ fExclude=TRUE;
+ break;
+ }
+ }
+
+ if (fExclude)
+ continue; // don't add the object entry to list
+
+ }
+ else
+ {
+ continue; // already added an object format to list
+ }
+ }
+
+ // add to list if entry is marked TRUE
+ if (lpOPS->arrPasteEntries[i].dwScratchSpace)
+ {
+ if (nDefFormat < 0)
+ nDefFormat = (fInsertFirst ? 0 : nItems);
+ else if (fInsertFirst)
+ nDefFormat++; // adjust for obj fmt inserted 1st in list
+
+ LPTSTR lpszBuf = (LPTSTR)GlobalLock(lpPS->hBuff);
+ if (lpszBuf)
+ {
+ if (!FAddPasteListItem(hList, fInsertFirst, i, lpPS,
+ lpszBuf, lpPS->szFullUserTypeNameOD))
+ {
+ GlobalUnlock(lpPS->hBuff);
+ goto error;
+ }
+ GlobalUnlock(lpPS->hBuff);
+ }
+ nItems++;
+ }
+ }
+
+ // initialize selection to first format matched in list
+ if (nDefFormat >= 0)
+ lpPS->nPasteListCurSel = nDefFormat;
+
+ // Clean up
+
+ // If no items have been added to the list box (none of the formats
+ // offered by the source matched those acceptable to the container),
+ // return FALSE
+ if (nItems > 0)
+ return TRUE;
+ else
+ return FALSE;
+
+error:
+ FreeListData(hList);
+
+ return FALSE;
+}
+
+
+/*
+ * FFillPasteLinkList
+ *
+ * Purpose:
+ * Fills the invisible paste link list with the formats offered by the clipboard object and
+ * asked for by the container.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * lpPS Paste Special Dialog Structure
+ *
+ * Return Value:
+ * BOOL TRUE if sucessful and if formats could be found.
+ * FALSE if unsucessful or if no formats could be found.
+ */
+BOOL FFillPasteLinkList(HWND hDlg, LPPASTESPECIAL lpPS)
+{
+ LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS;
+ LPDATAOBJECT lpSrcDataObj = lpOPS->lpSrcDataObj;
+ LPENUMFORMATETC lpEnumFmtEtc = NULL;
+ OLEUIPASTEFLAG pasteFlag;
+ UINT arrLinkTypesSupported[PS_MAXLINKTYPES]; // Array of flags that
+ // indicate which link types
+ // are supported by source.
+ FORMATETC fmtetc;
+ int i, j;
+ int nItems = 0;
+ BOOL fLinkTypeSupported = FALSE;
+ HWND hList;
+ int nDefFormat = -1;
+ BOOL fTryObjFmt = FALSE;
+ BOOL fInsertFirst;
+ HRESULT hrErr;
+
+ // Remember which link type formats are offered by lpSrcDataObj.
+ memset(&fmtetc, 0, sizeof(FORMATETC));
+ for (i = 0; i < lpOPS->cLinkTypes; i++)
+ {
+ if (lpOPS->arrLinkTypes[i] == _g_cfLinkSource)
+ {
+ OLEDBG_BEGIN2(TEXT("OleQueryLinkFromData called\r\n"))
+ hrErr = OleQueryLinkFromData(lpSrcDataObj);
+ OLEDBG_END2
+ if(NOERROR == hrErr)
+ {
+ arrLinkTypesSupported[i] = 1;
+ fLinkTypeSupported = TRUE;
+ }
+ else
+ arrLinkTypesSupported[i] = 0;
+ }
+ else
+ {
+ fmtetc.cfFormat = lpOPS->arrLinkTypes[i];
+ fmtetc.dwAspect = DVASPECT_CONTENT;
+ fmtetc.tymed = 0xFFFFFFFF; // All tymed values
+ fmtetc.lindex = -1;
+ OLEDBG_BEGIN2(TEXT("IDataObject::QueryGetData called\r\n"))
+ hrErr = lpSrcDataObj->QueryGetData(&fmtetc);
+ OLEDBG_END2
+ if(NOERROR == hrErr)
+ {
+ arrLinkTypesSupported[i] = 1;
+ fLinkTypeSupported = TRUE;
+ }
+ else arrLinkTypesSupported[i] = 0;
+ }
+ }
+ // No link types are offered by lpSrcDataObj
+ if (! fLinkTypeSupported)
+ {
+ nItems = 0;
+ goto cleanup;
+ }
+
+ hList = GetDlgItem(hDlg, IDC_PS_PASTELINKLIST);
+ SendMessage(hList, LB_RESETCONTENT, 0, 0);
+
+ // Enumerate the formats acceptable to container
+ for (i = 0; i < lpOPS->cPasteEntries; i++)
+ {
+ fLinkTypeSupported = FALSE;
+
+ // If container will accept any link type offered by source object
+ if (lpOPS->arrPasteEntries[i].dwFlags & OLEUIPASTE_LINKANYTYPE)
+ fLinkTypeSupported = TRUE;
+ else
+ {
+ // Check if any of the link types offered by the source
+ // object are acceptable to the container
+ // This code depends on the LINKTYPE enum values being powers of 2
+ for (pasteFlag = OLEUIPASTE_LINKTYPE1, j = 0;
+ j < lpOPS->cLinkTypes;
+ (UINT&)pasteFlag *= 2, j++)
+ {
+ if ((lpOPS->arrPasteEntries[i].dwFlags & pasteFlag) &&
+ arrLinkTypesSupported[j])
+ {
+ fLinkTypeSupported = TRUE;
+ break;
+ }
+ }
+ }
+
+ fInsertFirst = FALSE;
+
+ if (lpOPS->arrPasteEntries[i].fmtetc.cfFormat == _g_cfFileName
+ || lpOPS->arrPasteEntries[i].fmtetc.cfFormat == _g_cfLinkSource)
+ {
+ if (! fTryObjFmt)
+ {
+ fTryObjFmt = TRUE; // only use 1st object format
+ fInsertFirst = TRUE; // OLE obj format should always be 1st
+ }
+ else
+ {
+ continue; // already added an object format to list
+ }
+ }
+
+ // add to list if entry is marked TRUE
+ if (fLinkTypeSupported && lpOPS->arrPasteEntries[i].dwScratchSpace)
+ {
+ if (nDefFormat < 0)
+ nDefFormat = (fInsertFirst ? 0 : nItems);
+ else if (fInsertFirst)
+ nDefFormat++; // adjust for obj fmt inserted 1st in list
+
+ LPTSTR lpszBuf = (LPTSTR)GlobalLock(lpPS->hBuff);
+ if (lpszBuf)
+ {
+ if (!FAddPasteListItem(hList, fInsertFirst, i, lpPS,
+ lpszBuf, lpPS->szFullUserTypeNameLSD))
+ {
+ GlobalUnlock(lpPS->hBuff);
+ goto error;
+ }
+ GlobalUnlock(lpPS->hBuff);
+ }
+ nItems++;
+ }
+ } // end FOR
+
+ nItems = (int)SendMessage(hList, LB_GETCOUNT, 0, 0L);
+
+ // initialize selection to first format matched in list
+ if (nDefFormat >= 0)
+ lpPS->nPasteLinkListCurSel = nDefFormat;
+
+cleanup:
+ // Clean up
+
+ // If no items have been added to the list box (none of the formats
+ // offered by the source matched those acceptable to the destination),
+ // return FALSE
+ if (nItems > 0)
+ return TRUE;
+ else
+ return FALSE;
+
+error:
+ FreeListData(hList);
+
+ return FALSE;
+}
+
+/*
+ * FreeListData
+ *
+ * Purpose:
+ * Free the local memory associated with each list box item
+ *
+ * Parameters:
+ * hList HWND of the list
+ *
+ * Return Value:
+ * None
+ */
+void FreeListData(HWND hList)
+{
+ int nItems, i;
+ LPPASTELISTITEMDATA lpItemData;
+
+ nItems = (int) SendMessage(hList, LB_GETCOUNT, 0, 0L);
+ for (i = 0; i < nItems; i++)
+ {
+ lpItemData = (LPPASTELISTITEMDATA)SendMessage(hList, LB_GETITEMDATA, (WPARAM)i, 0L);
+ if ((LRESULT)lpItemData != LB_ERR)
+ OleStdFree((LPVOID)lpItemData);
+ }
+}
+
+/*
+ * FHasPercentS
+ *
+ * Purpose:
+ * Determines if string contains %s.
+ *
+ * Parameters:
+ * lpsz LPCSTR string in which occurence of '%s' is looked for
+ *
+ * Return Value:
+ * BOOL TRUE if %s is found, else FALSE.
+ */
+BOOL FHasPercentS(LPCTSTR lpsz, LPPASTESPECIAL lpPS)
+{
+ int n = 0;
+ LPTSTR lpszTmp;
+
+ if (!lpsz) return FALSE;
+ // Copy input string to buffer. This allows caller to pass a
+ // code-based string. Code segments may be swapped out in low memory situations
+ // and so code-based strings need to be copied before string elements can be accessed.
+ lpszTmp = (LPTSTR)GlobalLock(lpPS->hBuff);
+ lstrcpy(lpszTmp, lpsz);
+
+ while (*lpszTmp)
+ {
+ if (*lpszTmp == '%')
+ {
+ lpszTmp = CharNext(lpszTmp);
+ if (*lpszTmp == 's') // if %s, return
+ {
+ GlobalUnlock(lpPS->hBuff);
+ return TRUE;
+ }
+ else if (*lpszTmp == '%') // if %%, skip to next character
+ lpszTmp = CharNext(lpszTmp);
+ }
+ else
+ lpszTmp = CharNext(lpszTmp);
+ }
+
+ GlobalUnlock(lpPS->hBuff);
+ return FALSE;
+}
+
+/*
+ * AllocateScratchMem
+ *
+ * Purpose:
+ * Allocates scratch memory for use by the PasteSpecial dialog. The memory is
+ * is used as the buffer for building up strings using wsprintf. Strings are built up
+ * using the buffer while inserting items into the Paste & PasteLink lists and while
+ * setting the help result text. It must be big enough to handle the string that results after
+ * replacing the %s in the lpstrFormatName and lpstrResultText in arrPasteEntries[]
+ * by the FullUserTypeName. It must also be big enough to build the dialog's result text
+ * after %s substitutions by the FullUserTypeName or the ApplicationName.
+ *
+ * Parameters:
+ * lpPS Paste Special Dialog Structure
+ *
+ * Return Value:
+ * HGLOBAL Handle to allocated global memory
+ */
+HGLOBAL AllocateScratchMem(LPPASTESPECIAL lpPS)
+{
+ LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS;
+ int nLen, i;
+ int nSubstitutedText = 0;
+ int nAlloc = 0;
+
+ // Get the maximum length of the FullUserTypeNames specified by OBJECTDESCRIPTOR
+ // and the LINKSRCDESCRIPTOR and the Application Name. Any of these may be substituted
+ // for %s in the result-text/list entries.
+ if (lpPS->szFullUserTypeNameOD)
+ nSubstitutedText = lstrlen(lpPS->szFullUserTypeNameOD);
+ if (lpPS->szFullUserTypeNameLSD)
+ nSubstitutedText = __max(nSubstitutedText, lstrlen(lpPS->szFullUserTypeNameLSD));
+ if (lpPS->szAppName)
+ nSubstitutedText = __max(nSubstitutedText, lstrlen(lpPS->szAppName));
+
+ // Get the maximum length of lpstrFormatNames & lpstrResultText in arrPasteEntries
+ nLen = 0;
+ for (i = 0; i < lpOPS->cPasteEntries; i++)
+ {
+ nLen = max(nLen, lstrlen(lpOPS->arrPasteEntries[i].lpstrFormatName));
+ nLen = max(nLen, lstrlen(lpOPS->arrPasteEntries[i].lpstrResultText));
+ }
+
+ // Get the maximum length of lpstrFormatNames and lpstrResultText after %s has
+ // been substituted (At most one %s can appear in each string).
+ // Add 1 to hold NULL terminator.
+ nAlloc = (nLen+nSubstitutedText+1)*sizeof(TCHAR);
+
+ // Allocate scratch memory to be used to build strings
+ // nAlloc is big enough to hold any of the lpstrResultText or lpstrFormatName in arrPasteEntries[]
+ // after %s substitution.
+ // We also need space to build up the help result text. 512 is the maximum length of the
+ // standard dialog help text before substitutions. 512+nAlloc is the maximum length
+ // after %s substition.
+ // SetPasteSpecialHelpResults() requires 4 such buffers to build up the result text
+ return GlobalAlloc(GHND, (DWORD)4*(512 * sizeof(TCHAR) + nAlloc));
+}
diff --git a/private/ole2ui32/precomp.h b/private/ole2ui32/precomp.h
new file mode 100644
index 000000000..40edf741d
--- /dev/null
+++ b/private/ole2ui32/precomp.h
@@ -0,0 +1,29 @@
+/*
+ * PRECOMP.H
+ *
+ * This file is used to precompile the OLEDLG.H header file
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+// only STRICT compiles are supported
+#ifndef STRICT
+#define STRICT
+#endif
+
+#include "oledlg.h"
+#include "olestd.h"
+#include "resource.h"
+#include "commctrl.h"
+#ifndef WM_NOTIFY
+
+// WM_NOTIFY is new in later versions of Win32
+#define WM_NOTIFY 0x004e
+typedef struct tagNMHDR
+{
+ HWND hwndFrom;
+ UINT idFrom;
+ UINT code;
+} NMHDR;
+#endif //!WM_NOTIFY
+
diff --git a/private/ole2ui32/res/egares.bmp b/private/ole2ui32/res/egares.bmp
new file mode 100644
index 000000000..fc28bf55c
--- /dev/null
+++ b/private/ole2ui32/res/egares.bmp
Binary files differ
diff --git a/private/ole2ui32/res/hivgares.bmp b/private/ole2ui32/res/hivgares.bmp
new file mode 100644
index 000000000..49aee5a26
--- /dev/null
+++ b/private/ole2ui32/res/hivgares.bmp
Binary files differ
diff --git a/private/ole2ui32/res/ole2ui.rc2 b/private/ole2ui32/res/ole2ui.rc2
new file mode 100644
index 000000000..ceb4878a9
--- /dev/null
+++ b/private/ole2ui32/res/ole2ui.rc2
@@ -0,0 +1,145 @@
+//
+// OLE2UI.RC2 - resources App Studio does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by App Studio
+#endif //APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+IDD_INSERTOBJECT RT_HELPINFO
+BEGIN
+ IDC_IO_CREATENEW, 0, IDC_IO_CREATENEW, IDD_INSERTOBJECT,
+ IDC_IO_CREATEFROMFILE, 0, IDC_IO_CREATEFROMFILE, IDD_INSERTOBJECT,
+ IDC_IO_LINKFILE, 0, IDC_IO_LINKFILE, IDD_INSERTOBJECT,
+ IDC_IO_FILETEXT, 0, IDC_IO_FILE, IDD_INSERTOBJECT,
+ IDC_IO_OBJECTTYPELIST, 0, IDC_IO_OBJECTTYPELIST, IDD_INSERTOBJECT,
+ IDC_IO_OBJECTTYPETEXT, 0, IDC_IO_OBJECTTYPELIST, IDD_INSERTOBJECT,
+ IDC_IO_DISPLAYASICON, 0, IDC_IO_DISPLAYASICON, IDD_INSERTOBJECT,
+ IDC_IO_CHANGEICON, 0, IDC_IO_CHANGEICON, IDD_INSERTOBJECT,
+ IDC_IO_FILE, 0, IDC_IO_FILE, IDD_INSERTOBJECT,
+ IDC_IO_FILEDISPLAY, 0, IDC_IO_FILEDISPLAY, IDD_INSERTOBJECT,
+ IDC_IO_RESULTIMAGE, 0, IDC_IO_RESULTIMAGE, IDD_INSERTOBJECT,
+ IDC_IO_RESULTTEXT, 0, IDC_IO_RESULTTEXT, IDD_INSERTOBJECT,
+ IDC_IO_ICONDISPLAY, 0, IDC_IO_ICONDISPLAY, IDD_INSERTOBJECT,
+ IDC_IO_FILETYPE, 0, IDC_IO_FILETYPE, IDD_INSERTOBJECT,
+ IDC_IO_INSERTCONTROL, 0, IDC_IO_INSERTCONTROL, IDD_INSERTOBJECT,
+ IDC_IO_ADDCONTROL, 0, IDC_IO_ADDCONTROL, IDD_INSERTOBJECT,
+ IDC_IO_CONTROLTYPELIST, 0, IDC_IO_CONTROLTYPELIST, IDD_INSERTOBJECT,
+ 0, 0, 0, 0
+END
+
+IDD_CHANGEICON RT_HELPINFO
+BEGIN
+ IDC_CI_CURRENT, 0, IDC_CI_CURRENT, IDD_CHANGEICON,
+ IDC_CI_CURRENTICON, 0, IDC_CI_CURRENTICON, IDD_CHANGEICON,
+ IDC_CI_DEFAULT, 0, IDC_CI_DEFAULT, IDD_CHANGEICON,
+ IDC_CI_DEFAULTICON, 0, IDC_CI_DEFAULTICON, IDD_CHANGEICON,
+ IDC_CI_FROMFILE, 0, IDC_CI_FROMFILE, IDD_CHANGEICON,
+ IDC_CI_FROMFILEEDIT, 0, IDC_CI_FROMFILEEDIT, IDD_CHANGEICON,
+ IDC_CI_ICONLIST, 0, IDC_CI_ICONLIST, IDD_CHANGEICON,
+ IDC_CI_LABEL, 0, IDC_CI_LABEL, IDD_CHANGEICON,
+ IDC_CI_LABELEDIT, 0, IDC_CI_LABELEDIT, IDD_CHANGEICON,
+ IDC_CI_BROWSE, 0, IDC_CI_BROWSE, IDD_CHANGEICON,
+ IDC_CI_ICONDISPLAY, 0, IDC_CI_ICONDISPLAY, IDD_CHANGEICON,
+ 0, 0, 0, 0
+END
+
+IDD_CONVERT RT_HELPINFO
+BEGIN
+ IDC_CV_OBJECTTYPE, 0, IDC_CV_OBJECTTYPE, IDD_CONVERT,
+ IDC_CV_DISPLAYASICON, 0, IDC_CV_DISPLAYASICON, IDD_CONVERT,
+ IDC_CV_CHANGEICON, 0, IDC_CV_CHANGEICON, IDD_CONVERT,
+ IDC_CV_ACTIVATELIST, 0, IDC_CV_ACTIVATELIST, IDD_CONVERT,
+ IDC_CV_CONVERTTO, 0, IDC_CV_CONVERTTO, IDD_CONVERT,
+ IDC_CV_ACTIVATEAS, 0, IDC_CV_ACTIVATEAS, IDD_CONVERT,
+ IDC_CV_RESULTTEXT, 0, IDC_CV_RESULTTEXT, IDD_CONVERT,
+ IDC_CV_CONVERTLIST, 0, IDC_CV_CONVERTLIST, IDD_CONVERT,
+ IDC_CV_ICONDISPLAY, 0, IDC_CV_ICONDISPLAY, IDD_CONVERT,
+ 0, 0, 0, 0
+END
+
+IDD_PASTESPECIAL RT_HELPINFO
+BEGIN
+ IDC_PS_PASTE, 0, IDC_PS_PASTE, IDD_PASTESPECIAL,
+ IDC_PS_PASTELINK, 0, IDC_PS_PASTELINK, IDD_PASTESPECIAL,
+ IDC_PS_SOURCETEXT, 0, IDC_PS_SOURCETEXT, IDD_PASTESPECIAL,
+ IDC_PS_DISPLAYLIST, 0, IDC_PS_DISPLAYLIST, IDD_PASTESPECIAL,
+ IDC_PS_DISPLAYASICON, 0, IDC_PS_DISPLAYASICON, IDD_PASTESPECIAL,
+ IDC_PS_ICONDISPLAY, 0, IDC_PS_ICONDISPLAY, IDD_PASTESPECIAL,
+ IDC_PS_CHANGEICON, 0, IDC_PS_CHANGEICON, IDD_PASTESPECIAL,
+ IDC_PS_RESULTIMAGE, 0, IDC_PS_RESULTIMAGE, IDD_PASTESPECIAL,
+ IDC_PS_RESULTTEXT, 0, IDC_PS_RESULTTEXT, IDD_PASTESPECIAL,
+ 0, 0, 0, 0
+END
+
+IDD_EDITLINKS RT_HELPINFO
+BEGIN
+ IDC_EL_CHANGESOURCE, 0, IDC_EL_CHANGESOURCE, IDD_EDITLINKS,
+ IDC_EL_AUTOMATIC, 0, IDC_EL_AUTOMATIC, IDD_EDITLINKS,
+ IDC_EL_CANCELLINK, 0, IDC_EL_CANCELLINK, IDD_EDITLINKS,
+ IDC_EL_UPDATENOW, 0, IDC_EL_UPDATENOW, IDD_EDITLINKS,
+ IDC_EL_OPENSOURCE, 0, IDC_EL_OPENSOURCE, IDD_EDITLINKS,
+ IDC_EL_MANUAL, 0, IDC_EL_MANUAL, IDD_EDITLINKS,
+ IDC_EL_LINKSOURCE, 0, IDC_EL_LINKSOURCE, IDD_EDITLINKS,
+ IDC_EL_LINKTYPE, 0, IDC_EL_LINKTYPE, IDD_EDITLINKS,
+ IDC_EL_LINKSLISTBOX, 0, IDC_EL_LINKSLISTBOX, IDD_EDITLINKS,
+ IDC_EL_COL1, 0, IDC_EL_LINKSLISTBOX, IDD_EDITLINKS,
+ IDC_EL_COL2, 0, IDC_EL_LINKSLISTBOX, IDD_EDITLINKS,
+ IDC_EL_COL3, 0, IDC_EL_LINKSLISTBOX, IDD_EDITLINKS,
+ 0, 0, 0, 0
+END
+
+IDD_CHANGESOURCE RT_HELPINFO
+BEGIN
+ //TODO: need to get id of the item
+ 0, 0, 0, 0
+END
+
+IDD_BUSY RT_HELPINFO
+BEGIN
+ IDC_BZ_RETRY, 0, IDC_BZ_RETRY, IDD_BUSY,
+ IDC_BZ_ICON, 0, IDC_BZ_ICON, IDD_BUSY,
+ IDC_BZ_SWITCHTO, 0, IDC_BZ_SWITCHTO, IDD_BUSY,
+ 0, 0, 0, 0
+END
+
+IDD_GNRLPROPS RT_HELPINFO
+BEGIN
+ IDC_GP_OBJECTNAME, 0, IDC_GP_OBJECTNAME, IDD_GNRLPROPS,
+ IDC_GP_OBJECTTYPE, 0, IDC_GP_OBJECTTYPE, IDD_GNRLPROPS,
+ IDC_GP_OBJECTSIZE, 0, IDC_GP_OBJECTSIZE, IDD_GNRLPROPS,
+ IDC_GP_CONVERT, 0, IDC_GP_CONVERT, IDD_GNRLPROPS,
+ IDC_GP_OBJECTLOCATION, 0, IDC_GP_OBJECTLOCATION, IDD_GNRLPROPS,
+ 0, 0, 0, 0
+END
+
+IDD_VIEWPROPS RT_HELPINFO
+BEGIN
+ IDC_VP_PERCENT, 0, IDC_VP_PERCENT, IDD_VIEWPROPS,
+ IDC_VP_CHANGEICON, 0, IDC_VP_CHANGEICON, IDD_VIEWPROPS,
+ IDC_VP_EDITABLE, 0, IDC_VP_EDITABLE, IDD_VIEWPROPS,
+ IDC_VP_ASICON, 0, IDC_VP_ASICON, IDD_VIEWPROPS,
+ IDC_VP_RELATIVE, 0, IDC_VP_RELATIVE, IDD_VIEWPROPS,
+ IDC_VP_SPIN, 0, IDC_VP_SPIN, IDD_VIEWPROPS,
+ IDC_VP_ICONDISPLAY, 0, IDC_VP_ICONDISPLAY, IDD_VIEWPROPS,
+ 0, 0, 0, 0
+END
+
+IDD_LINKPROPS RT_HELPINFO
+BEGIN
+ IDC_LP_OPENSOURCE, 0, IDC_LP_OPENSOURCE, IDD_LINKPROPS,
+ IDC_LP_UPDATENOW, 0, IDC_LP_UPDATENOW, IDD_LINKPROPS,
+ IDC_LP_BREAKLINK, 0, IDC_LP_BREAKLINK, IDD_LINKPROPS,
+ IDC_LP_LINKSOURCE, 0, IDC_LP_LINKSOURCE, IDD_LINKPROPS,
+ IDC_LP_CHANGESOURCE, 0, IDC_LP_CHANGESOURCE, IDD_LINKPROPS,
+ IDC_LP_AUTOMATIC, 0, IDC_LP_AUTOMATIC, IDD_LINKPROPS,
+ IDC_LP_MANUAL, 0, IDC_LP_MANUAL, IDD_LINKPROPS,
+ IDC_LP_DATE, 0, IDC_LP_DATE, IDD_LINKPROPS,
+ IDC_LP_TIME, 0, IDC_LP_TIME, IDD_LINKPROPS,
+ 0, 0, 0, 0
+END
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/private/ole2ui32/res/vgares.bmp b/private/ole2ui32/res/vgares.bmp
new file mode 100644
index 000000000..08e0b041b
--- /dev/null
+++ b/private/ole2ui32/res/vgares.bmp
Binary files differ
diff --git a/private/ole2ui32/resimage.cpp b/private/ole2ui32/resimage.cpp
new file mode 100644
index 000000000..4b98c4c85
--- /dev/null
+++ b/private/ole2ui32/resimage.cpp
@@ -0,0 +1,355 @@
+/*
+ * RESIMAGE.CPP
+ *
+ * Implementation of the Results Image control for OLE 2.0 UI dialogs.
+ * We need a separate control for dialogs in order to control the repaints
+ * properly and to provide a clean message interface for the dialog
+ * implementations.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "resimage.h"
+#include "uiclass.h"
+OLEDBGDATA
+
+//Reference counter indicating how many times fResultImageInitialize has been
+//successfully called
+static UINT uRegistered = 0;
+
+//Bitmap and image dimensions for result images.
+static HBITMAP hBmpResults = NULL;
+static UINT cxBmpResult;
+static UINT cyBmpResult;
+
+/*
+ * FResultImageInitialize
+ *
+ * Purpose:
+ * Attempts to load result bitmaps for the current display driver
+ * for use in OLE 2.0 UI dialogs. Also registers the ResultImage
+ * control class.
+ *
+ * Parameters:
+ * hInst HINSTANCE instance of the DLL.
+ *
+ * hPrevInst HINSTANCE of the previous instance. Used to
+ * determine whether to register window classes or not.
+ *
+ * Return Value:
+ * BOOL TRUE if all initialization succeeded, FALSE otherwise.
+ */
+
+#pragma code_seg(".text$initseg")
+
+BOOL FResultImageInitialize(HINSTANCE hInst, HINSTANCE hPrevInst)
+{
+ int cx, iBmp;
+ HDC hDC;
+ BITMAP bm;
+
+ WNDCLASS wc;
+
+ /*
+ * Determine the aspect ratio of the display we're currently
+ * running on and load the appropriate bitmap into the global
+ * hBmpResults (used from the ResultImage control only).
+ *
+ * By retrieving the logical Y extent of the display driver, you
+ * only have limited possibilities:
+ * LOGPIXELSY Display
+ * ----------------------------------------
+ * 48 CGA (unsupported)
+ * 72 EGA
+ * 96 VGA
+ * 120 8514/a (i.e. HiRes VGA)
+ */
+
+ hDC=GetDC(NULL);
+
+ if (NULL==hDC)
+ return FALSE;
+
+ cx=GetDeviceCaps(hDC, LOGPIXELSY);
+ ReleaseDC(NULL, hDC);
+
+ /*
+ * Instead of single comparisons, check ranges instead, so in case
+ * we get something funky, we'll act reasonable.
+ */
+ if (72 >=cx) iBmp=IDB_RESULTSEGA;
+ if (72 < cx && 120 > cx) iBmp=IDB_RESULTSVGA;
+ if (120 <=cx) iBmp=IDB_RESULTSHIRESVGA;
+
+ if (NULL == hBmpResults)
+ {
+ hBmpResults=LoadBitmap(hInst, MAKEINTRESOURCE(iBmp));
+
+ if (NULL==hBmpResults)
+ {
+ //On error, fail loading the DLL
+ OleDbgOut1(TEXT("FResultImageInitialize: Failed LoadBitmap.\r\n"));
+ return FALSE;
+ }
+ OleDbgOut4(TEXT("FResultImageInitialize: Loaded hBmpResults\r\n"));
+
+ // Now that we have the bitmap, calculate image dimensions
+ GetObject(hBmpResults, sizeof(BITMAP), &bm);
+ cxBmpResult = bm.bmWidth/CIMAGESX;
+ cyBmpResult = bm.bmHeight;
+ }
+
+
+ // Only register class if we're the first instance
+ if (hPrevInst)
+ uRegistered++;
+ else
+ {
+ // Static flag fRegistered guards against calling this function more
+ // than once in the same instance
+
+ if (0 == uRegistered)
+ {
+ wc.lpfnWndProc =ResultImageWndProc;
+ wc.cbClsExtra =0;
+ wc.cbWndExtra =CBRESULTIMAGEWNDEXTRA;
+ wc.hInstance =hInst;
+ wc.hIcon =NULL;
+ wc.hCursor =LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground =NULL;
+ wc.lpszMenuName =NULL;
+ wc.style =CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
+
+ wc.lpszClassName = TEXT(SZCLASSRESULTIMAGE1);
+ uRegistered = RegisterClass(&wc) ? 1 : 0;
+
+ wc.lpszClassName = TEXT(SZCLASSRESULTIMAGE2);
+ uRegistered = RegisterClass(&wc) ? 1 : 0;
+
+ wc.lpszClassName = TEXT(SZCLASSRESULTIMAGE3);
+ uRegistered = RegisterClass(&wc) ? 1 : 0;
+ }
+ else
+ uRegistered++;
+ }
+
+ return (uRegistered > 0);
+}
+
+#pragma code_seg()
+
+
+/*
+ * ResultImageUninitialize
+ *
+ * Purpose:
+ * Cleans up anything done in FResultImageInitialize, such as freeing
+ * the bitmaps. Call from WEP.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ */
+
+void ResultImageUninitialize(void)
+{
+ --uRegistered;
+ if (0 == uRegistered)
+ {
+ if (NULL != hBmpResults)
+ {
+ DeleteObject(hBmpResults);
+ hBmpResults = NULL;
+ }
+ }
+}
+
+
+/*
+ * ResultImageWndProc
+ *
+ * Purpose:
+ * Window Procedure for the ResultImage custom control. Only handles
+ * WM_CREATE, WM_PAINT, and private messages to manipulate the bitmap.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ */
+
+LONG CALLBACK ResultImageWndProc(HWND hWnd, UINT iMsg,
+ WPARAM wParam, LPARAM lParam)
+{
+ UINT iBmp;
+ PAINTSTRUCT ps;
+ HDC hDC;
+
+ //Handle standard Windows messages.
+ switch (iMsg)
+ {
+ case WM_CREATE:
+ SetWindowWord(hWnd, RIWW_IMAGEINDEX, RESULTIMAGE_NONE);
+ return 0L;
+
+ case WM_PAINT:
+ iBmp = GetWindowWord(hWnd, RIWW_IMAGEINDEX);
+ hDC = BeginPaint(hWnd, &ps);
+
+ RECT rc;
+ UINT x, y;
+ HDC hDCDlg;
+ HBRUSH hBr;
+ LOGBRUSH lb;
+ HWND hDlg;
+
+ /*
+ * Our job before using TransparentBlt is to figure out
+ * where to position the result image. We place it centered
+ * on this control, so get our rect's center and subtract
+ * half of the image dimensions.
+ */
+ GetClientRect(hWnd, &rc);
+ x = (rc.right+rc.left-cxBmpResult)/2;
+ y = (rc.bottom+rc.top-cyBmpResult)/2;
+
+ // Get the backgroup color the dialog is using.
+ hDlg=GetParent(hWnd);
+ hDCDlg=GetDC(hDlg);
+ hBr = (HBRUSH)SendMessage(hDlg,
+ WM_CTLCOLORDLG,
+ (WPARAM)hDCDlg,
+ (LPARAM)hDlg);
+ ReleaseDC(hDlg, hDCDlg);
+ GetObject(hBr, sizeof(LOGBRUSH), &lb);
+ SetBkColor(hDC, lb.lbColor);
+
+
+ if (RESULTIMAGE_NONE != iBmp)
+ {
+
+ TransparentBlt(hDC, x, y, hBmpResults, iBmp*cxBmpResult, 0,
+ cxBmpResult, cyBmpResult, RGBTRANSPARENT);
+ }
+ else
+ {
+ FillRect(hDC, &rc, hBr);
+ }
+ EndPaint(hWnd, &ps);
+ break;
+
+ case RIM_IMAGESET:
+ // wParam contains the new index.
+ iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX);
+
+ // Validate the index before changing it and repainting
+ if (RESULTIMAGE_NONE==wParam ||
+ ((RESULTIMAGE_MIN <= wParam) && (RESULTIMAGE_MAX >= wParam)))
+ {
+ SetWindowWord(hWnd, RIWW_IMAGEINDEX, (WORD)wParam);
+ InvalidateRect(hWnd, NULL, FALSE);
+ UpdateWindow(hWnd);
+ }
+ // Return the previous index.
+ return iBmp;
+
+ case RIM_IMAGEGET:
+ // Return the current index.
+ iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX);
+ return (LONG)iBmp;
+
+ default:
+ return DefWindowProc(hWnd, iMsg, wParam, lParam);
+ }
+
+ return 0L;
+}
+
+
+/*
+ * TransparentBlt
+ *
+ * Purpose:
+ * Given a DC, a bitmap, and a color to assume as transparent in that
+ * bitmap, BitBlts the bitmap to the DC letting the existing background
+ * show in place of the transparent color.
+ *
+ * Parameters:
+ * hDC HDC on which to draw.
+ * x, y UINT location at which to draw the bitmap
+ * hBmp HBITMIP to draw from
+ * xOrg, yOrg UINT coordinates from which to draw the bitamp
+ * cx, cy UINT dimensions of the bitmap to Blt.
+ * cr COLORREF to consider as transparent.
+ *
+ * Return Value:
+ * None
+ */
+
+void TransparentBlt(HDC hDC, UINT x, UINT y, HBITMAP hBmp, UINT xOrg, UINT yOrg,
+ UINT cx, UINT cy, COLORREF cr)
+{
+ HDC hDCSrc, hDCMid, hMemDC;
+ HBITMAP hBmpMono, hBmpT;
+ HBRUSH hBr, hBrT;
+ COLORREF crBack, crText;
+
+ if (NULL == hBmp)
+ return;
+
+ // Get three intermediate DC's
+ hDCSrc = CreateCompatibleDC(hDC);
+ hDCMid = CreateCompatibleDC(hDC);
+ hMemDC = CreateCompatibleDC(hDC);
+
+ SelectObject(hDCSrc, hBmp);
+
+ // Create a monochrome bitmap for masking
+ hBmpMono=CreateCompatibleBitmap(hDCMid, cx, cy);
+ SelectObject(hDCMid, hBmpMono);
+
+ // Create a middle bitmap
+ hBmpT=CreateCompatibleBitmap(hDC, cx, cy);
+ SelectObject(hMemDC, hBmpT);
+
+ // Create a monochrome mask where we have 0's in the image, 1's elsewhere.
+ crBack=SetBkColor(hDCSrc, cr);
+ BitBlt(hDCMid, 0, 0, cx, cy, hDCSrc, xOrg, yOrg, SRCCOPY);
+ SetBkColor(hDCSrc, crBack);
+
+ // Put the unmodified image in the temporary bitmap
+ BitBlt(hMemDC, 0, 0, cx, cy, hDCSrc, xOrg, yOrg, SRCCOPY);
+
+ // Create an select a brush of the background color
+ hBr = CreateSolidBrush(GetBkColor(hDC));
+ hBrT = (HBRUSH)SelectObject(hMemDC, hBr);
+
+ // Force conversion of the monochrome to stay black and white.
+ crText=SetTextColor(hMemDC, 0L);
+ crBack=SetBkColor(hMemDC, RGB(255, 255, 255));
+
+ /*
+ * Where the monochrome mask is 1, Blt the brush; where the mono mask
+ * is 0, leave the destination untouches. This results in painting
+ * around the image with the background brush. We do this first
+ * in the temporary bitmap, then put the whole thing to the screen.
+ */
+ BitBlt(hMemDC, 0, 0, cx, cy, hDCMid, 0, 0, ROP_DSPDxax);
+ BitBlt(hDC, x, y, cx, cy, hMemDC, 0, 0, SRCCOPY);
+
+ SetTextColor(hMemDC, crText);
+ SetBkColor(hMemDC, crBack);
+
+ SelectObject(hMemDC, hBrT);
+ DeleteObject(hBr);
+
+ DeleteDC(hMemDC);
+ DeleteDC(hDCSrc);
+ DeleteDC(hDCMid);
+ DeleteObject(hBmpT);
+ DeleteObject(hBmpMono);
+}
diff --git a/private/ole2ui32/resimage.h b/private/ole2ui32/resimage.h
new file mode 100644
index 000000000..57c4881b4
--- /dev/null
+++ b/private/ole2ui32/resimage.h
@@ -0,0 +1,56 @@
+/*
+ * RESIMAGE.H
+ *
+ * Structures and definitions for the ResultImage control.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+
+#ifndef _RESIMAGE_H_
+#define _RESIMAGE_H_
+
+/*
+ * Indices into the bitmaps to extract the right image. Each bitmap
+ * contains five images arranged vertically, so the offset to the correct
+ * image is (iImage*cy)
+ */
+
+#define RESULTIMAGE_NONE 0xFFFF
+#define RESULTIMAGE_PASTE 0
+#define RESULTIMAGE_EMBED 1
+#define RESULTIMAGE_EMBEDICON 2
+#define RESULTIMAGE_LINK 3
+#define RESULTIMAGE_LINKICON 4
+#define RESULTIMAGE_LINKTOLINK 5
+#define RESULTIMAGE_LINKTOLINKICON 6
+#define RESULTIMAGE_EDITABLE 7
+
+#define RESULTIMAGE_MIN 0
+#define RESULTIMAGE_MAX 7
+
+// Total number of images in each bitmap.
+#define CIMAGESX (RESULTIMAGE_MAX+1)
+
+// The color to use for transparancy (cyan)
+#define RGBTRANSPARENT RGB(0, 255, 255)
+
+// Function prototypes
+LONG CALLBACK ResultImageWndProc(HWND, UINT, WPARAM, LPARAM);
+
+BOOL FResultImageInitialize(HINSTANCE, HINSTANCE);
+void ResultImageUninitialize(void);
+void TransparentBlt(HDC, UINT, UINT, HBITMAP, UINT, UINT, UINT, UINT, COLORREF);
+
+// Window extra bytes contain the bitmap index we deal with currently.
+#define CBRESULTIMAGEWNDEXTRA sizeof(UINT)
+#define RIWW_IMAGEINDEX 0
+
+// Control messages
+#define RIM_IMAGESET (WM_USER+0)
+#define RIM_IMAGEGET (WM_USER+1)
+
+// Special ROP code for TransparentBlt.
+#define ROP_DSPDxax 0x00E20746
+
+#endif //_RESIMAGE_H_
diff --git a/private/ole2ui32/resource.h b/private/ole2ui32/resource.h
new file mode 100644
index 000000000..600e51a73
--- /dev/null
+++ b/private/ole2ui32/resource.h
@@ -0,0 +1,102 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by oledlg.rc
+//
+#define IDB_RESULTSEGA 10
+#define IDB_RESULTSVGA 11
+#define IDB_RESULTSHIRESVGA 12
+#define IDS_FILTERS 64
+#define IDS_ICONFILTERS 65
+#define IDS_BROWSE 66
+#define IDS_OCX_FILTERS 67
+#define IDS_INSERT 68
+#define IDS_CHNGSRCOKBUTTON 69
+#define IDS_IORESULTNEW 256
+#define IDS_IORESULTNEWICON 257
+#define IDS_IORESULTFROMFILE1 258
+#define IDS_IORESULTFROMFILE2 259
+#define IDS_IORESULTFROMFILEICON2 260
+#define IDS_IORESULTLINKFILE1 261
+#define IDS_IORESULTLINKFILE2 262
+#define IDS_IORESULTLINKFILEICON1 263
+#define IDS_IORESULTLINKFILEICON2 264
+#define IDS_CINOICONSINFILE 288
+#define IDS_CIINVALIDFILE 289
+#define IDS_CIFILEACCESS 290
+#define IDS_CIFILESHARE 291
+#define IDS_CIFILEOPENFAIL 292
+#define IDS_OLE2UIUNKNOWN 300
+#define IDS_OLE2UILINK 301
+#define IDS_OLE2UIOBJECT 302
+#define IDS_OLE2UIEDIT 303
+#define IDS_OLE2UICONVERT 304
+#define IDS_OLE2UIEDITLINKCMD_1VERB 305
+#define IDS_OLE2UIEDITOBJECTCMD_1VERB 306
+#define IDS_OLE2UIEDITLINKCMD_NVERB 307
+#define IDS_OLE2UIEDITOBJECTCMD_NVERB 308
+#define IDS_OLE2UIEDITNOOBJCMD 309
+#define IDS_DEFICONLABEL 310
+#define IDS_OLE2UIPASTELINKEDTYPE 311
+#define IDS_PSPASTEDATA 400
+#define IDS_PSPASTEOBJECT 401
+#define IDS_PSPASTEOBJECTASICON 402
+#define IDS_PSPASTELINKDATA 403
+#define IDS_PSPASTELINKOBJECT 404
+#define IDS_PSPASTELINKOBJECTASICON 405
+#define IDS_PSNONOLE 406
+#define IDS_PSUNKNOWNTYPE 407
+#define IDS_PSUNKNOWNSRC 408
+#define IDS_PSUNKNOWNAPP 409
+#define IDS_CVRESULTCONVERTLINK 500
+#define IDS_CVRESULTCONVERTTO 501
+#define IDS_CVRESULTNOCHANGE 502
+#define IDS_CVRESULTDISPLAYASICON 503
+#define IDS_CVRESULTACTIVATEAS 504
+#define IDS_CVRESULTACTIVATEDIFF 505
+#define IDS_BZRESULTTEXTBUSY 601
+#define IDS_BZRESULTTEXTNOTRESPONDING 602
+#define IDS_OLESTDNOCREATEFILE 700
+#define IDS_OLESTDNOOPENFILE 701
+#define IDS_OLESTDDISKFULL 702
+#define IDS_LINK_AUTO 800
+#define IDS_LINK_MANUAL 801
+#define IDS_LINK_UNKNOWN 802
+#define IDS_LINKS 803
+#define IDS_FAILED 804
+#define IDS_CHANGESOURCE 805
+#define IDS_INVALIDSOURCE 806
+#define IDS_ERR_GETLINKSOURCE 807
+#define IDS_ERR_GETLINKUPDATEOPTIONS 808
+#define IDS_ERR_ADDSTRING 809
+#define IDS_CHANGEADDITIONALLINKS 810
+#define IDS_CLOSE 811
+#define IDS_OBJECTPROPERTIES 812
+#define IDS_LINKOBJECTPROPERTIES 813
+#define IDS_LINKPROPS 814
+#define IDS_CONFIRMBREAKLINK 815
+#define IDS_BYTES 816
+#define IDS_ORDERKB 817
+#define IDS_ORDERMB 818
+#define IDS_ORDERGB 819
+#define IDS_ORDERTB 820
+#define IDS_OBJECTSIZE 821
+#define IDS_CANNOTLOADOCX 822
+#define IDS_NODLLREGISTERSERVER 823
+#define IDS_DLLREGISTERFAILED 824
+#define IDS_ADDCONTROL 825
+#define IDS_RANGEERROR 826
+#define IDS_INVALIDPERCENTAGE 827
+#define IDS_VIEWPROPS 828
+#define RT_HELPINFO 4096
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 110
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1047
+#define _APS_NEXT_SYMED_VALUE 102
+#endif
+#endif
diff --git a/private/ole2ui32/targtdev.cpp b/private/ole2ui32/targtdev.cpp
new file mode 100644
index 000000000..0dbbab08f
--- /dev/null
+++ b/private/ole2ui32/targtdev.cpp
@@ -0,0 +1,32 @@
+/*************************************************************************
+**
+** OLE 2 Standard Utilities
+**
+** olestd.c
+**
+** This file contains utilities that are useful for dealing with
+** target devices.
+**
+** (c) Copyright Microsoft Corp. 1992 All Rights Reserved
+**
+*************************************************************************/
+
+#include "precomp.h"
+
+STDAPI_(BOOL) OleStdCompareTargetDevice(
+ DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight)
+{
+ if (ptdLeft == ptdRight)
+ // same address of td; must be same (handles NULL case)
+ return TRUE;
+ else if ((ptdRight == NULL) || (ptdLeft == NULL))
+ return FALSE;
+ else if (ptdLeft->tdSize != ptdRight->tdSize)
+ // different sizes, not equal
+ return FALSE;
+ else if (memcmp(ptdLeft, ptdRight, ptdLeft->tdSize) != 0)
+ // not same target device, not equal
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/private/ole2ui32/template.cpp b/private/ole2ui32/template.cpp
new file mode 100644
index 000000000..81244dc95
--- /dev/null
+++ b/private/ole2ui32/template.cpp
@@ -0,0 +1,229 @@
+/*
+ * TEMPLATE.CPP
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ *
+ *
+ * CUSTOMIZATION INSTRUCTIONS:
+ *
+ * 1. Replace <FILE> with the uppercased filename for this file.
+ * Lowercase the <FILE>.h entry
+ *
+ * 2. Replace <NAME> with the mixed case dialog name in one word,
+ * such as InsertObject
+ *
+ * 3. Replace <FULLNAME> with the mixed case dialog name in multiple
+ * words, such as Insert Object
+ *
+ * 4. Replace <ABBREV> with the suffix for pointer variables, such
+ * as the IO in InsertObject's pIO or the CI in ChangeIcon's pCI.
+ * Check the alignment of the first variable declaration in the
+ * Dialog Proc after this. I will probably be misaligned with the
+ * rest of the variables.
+ *
+ * 5. Replace <STRUCT> with the uppercase structure name for this
+ * dialog sans OLEUI, such as INSERTOBJECT. Changes OLEUI<STRUCT>
+ * in most cases, but we also use this for IDD_<STRUCT> as the
+ * standard template resource ID.
+ *
+ * 6. Find <UFILL> fields and fill them out with whatever is appropriate.
+ *
+ * 7. Delete this header up to the start of the next comment.
+ */
+
+
+/*
+ * <FILE>.CPP
+ *
+ * Implements the OleUI<NAME> function which invokes the complete
+ * <FULLNAME> dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+
+#include "template.h"
+
+/*
+ * OleUI<NAME>
+ *
+ * Purpose:
+ * Invokes the standard OLE <FULLNAME> dialog box allowing the user
+ * to <UFILL>
+ *
+ * Parameters:
+ * lp<ABBREV> LPOLEUI<NAME> pointing to the in-out structure
+ * for this dialog.
+ *
+ * Return Value:
+ * UINT One of the following codes, indicating success or error:
+ * OLEUI_SUCCESS Success
+ * OLEUI_ERR_STRUCTSIZE The dwStructSize value is wrong
+ */
+
+STDAPI_(UINT) OleUI<NAME>(LPOLEUI<STRUCT> lp<ABBREV>)
+{
+ UINT uRet;
+ HGLOBAL hMemDlg=NULL;
+
+ uRet = UStandardValidation((LPOLEUISTANDARD)lp<ABBREV>,
+ sizeof(OLEUI<STRUCT>), &hMemDlg);
+
+ if (OLEUI_SUCCESS!=uRet)
+ return uRet;
+
+ /*
+ * PERFORM ANY STRUCTURE-SPECIFIC VALIDATION HERE!
+ * ON FAILURE:
+ * {
+ * return OLEUI_<ABBREV>ERR_<ERROR>
+ * }
+ */
+
+ //Now that we've validated everything, we can invoke the dialog.
+ uRet = UStandardInvocation(<NAME>DialogProc, (LPOLEUISTANDARD)lp<ABBREV>
+ , hMemDlg, MAKEINTRESOURCE(IDD_<STRUCT>));
+
+ /*
+ * IF YOU ARE CREATING ANYTHING BASED ON THE RESULTS, DO IT HERE.
+ */
+ <UFILL>
+
+ return uRet;
+}
+
+/*
+ * <NAME>DialogProc
+ *
+ * Purpose:
+ * Implements the OLE <FULLNAME> dialog as invoked through the
+ * OleUI<NAME> function.
+ *
+ * Parameters:
+ * Standard
+ *
+ * Return Value:
+ * Standard
+ */
+
+BOOL CALLBACK <NAME>DialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ P<STRUCT> p<ABBREV>;
+ BOOL fHook=FALSE;
+
+ //Declare Win16/Win32 compatible WM_COMMAND parameters.
+ COMMANDPARAMS(wID, wCode, hWndMsg);
+
+ //This will fail under WM_INITDIALOG, where we allocate it.
+ p<ABBREV>=(<STRUCT>)PvStandardEntry(hDlg, iMsg, wParam, lParam, &uHook);
+
+ //If the hook processed the message, we're done.
+ if (0!=uHook)
+ return (BOOL)uHook;
+
+ //Process the temination message
+ if (iMsg==uMsgEndDialog)
+ {
+ EndDialog(hDlg, wParam);
+ return TRUE;
+ }
+
+ switch (iMsg)
+ {
+ case WM_DESTROY:
+ if (p<ABBREV>)
+ {
+ //Free any specific allocations before calling StandardCleanup
+ StandardCleanup((PVOID)p<ABBREV>, hDlg);
+ }
+ break;
+ case WM_INITDIALOG:
+ F<NAME>Init(hDlg, wParam, lParam);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (wID)
+ {
+ case IDOK:
+ /*
+ * PERFORM WHATEVER FUNCTIONS ARE DEFAULT HERE.
+ */
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L);
+ break;
+
+ case IDCANCEL:
+ /*
+ * PERFORM ANY UNDOs HERE, BUT NOT CLEANUP THAT WILL
+ * ALWAYS HAPPEN WHICH SHOULD BE IN uMsgEndDialog.
+ */
+ SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
+ break;
+
+ case ID_OLEUIHELP:
+ PostMessage(p<ABBREV>->lpO<ABBREV>->hWndOwner, uMsgHelp
+ , (WPARAM)hDlg, MAKELPARAM(IDD_<STRUCT>, 0));
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+/*
+ * F<NAME>Init
+ *
+ * Purpose:
+ * WM_INITIDIALOG handler for the <FULLNAME> dialog box.
+ *
+ * Parameters:
+ * hDlg HWND of the dialog
+ * wParam WPARAM of the message
+ * lParam LPARAM of the message
+ *
+ * Return Value:
+ * BOOL Value to return for WM_INITDIALOG.
+ */
+
+BOOL F<NAME>Init(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+ P<STRUCT> p<ABBREV>;
+ LPOLEUI<STRUCT> lpO<ABBREV>;
+ HFONT hFont;
+
+ //1. Copy the structure at lParam into our instance memory.
+ p<ABBREV>=(PSTRUCT)PvStandardInit(hDlg, sizeof(<STRUCT>), TRUE, &hFont);
+
+ //PvStandardInit send a termination to us already.
+ if (NULL==p<ABBREV>)
+ return FALSE;
+
+ lpO<ABBREV>=(LPOLEUI<STRUCT>)lParam);
+
+ p<ABBREV>->lpO<ABBREV>=lpO<ABBREV>;
+
+ //Copy other information from lpO<ABBREV> that we might modify.
+ <UFILL>
+
+ //2. If we got a font, send it to the necessary controls.
+ if (NULL!=hFont)
+ {
+ //Do this for as many controls as you need it for.
+ SendDlgItemMessage(hDlg, ID_<UFILL>, WM_SETFONT, (WPARAM)hFont, 0L);
+ }
+
+ //3. Show or hide the help button
+ if (!(p<ABBREV>->lpO<ABBREV>->dwFlags & <ABBREV>F_SHOWHELP))
+ StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE);
+
+ /*
+ * PERFORM OTHER INITIALIZATION HERE. ON ANY LoadString
+ * FAILURE POST OLEUI_MSG_ENDDIALOG WITH OLEUI_ERR_LOADSTRING.
+ */
+
+ //n. Call the hook with lCustData in lParam
+ UStandardHook((PVOID)p<ABBREV>, hDlg, WM_INITDIALOG, wParam, lpO<ABBREV>->lCustData);
+ return TRUE;
+}
diff --git a/private/ole2ui32/template.h b/private/ole2ui32/template.h
new file mode 100644
index 000000000..ab2cac951
--- /dev/null
+++ b/private/ole2ui32/template.h
@@ -0,0 +1,119 @@
+/*
+ * TEMPLATE.H
+ *
+ * CUSTOMIZATION INSTRUCTIONS:
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ *
+ *
+ * 1. Replace <FILE> with the uppercased filename for this file.
+ * Lowercase the <FILE>.h entry
+ *
+ * 2. Replace <NAME> with the mixed case dialog name in one word,
+ * such as InsertObject
+ *
+ * 3. Replace <FULLNAME> with the mixed case dialog name in multiple
+ * words, such as Insert Object
+ *
+ * 4. Replace <ABBREV> with the suffix for pointer variables, such
+ * as the IO in InsertObject's pIO or the CI in ChangeIcon's pCI.
+ * Check the alignment of the first variable declaration in the
+ * Dialog Proc after this. I will probably be misaligned with the
+ * rest of the variables.
+ *
+ * 5. Replace <STRUCT> with the uppercase structure name for this
+ * dialog sans OLEUI, such as INSERTOBJECT. Changes OLEUI<STRUCT>
+ * in most cases, but we also use this for IDD_<STRUCT> as the
+ * standard template resource ID.
+ *
+ * 6. Find <UFILL> fields and fill them out with whatever is appropriate.
+ *
+ * 7. Delete this header up to the start of the next comment.
+ *
+ */
+
+
+/*
+ * <FILE>.H
+ *
+ * Internal definitions, structures, and function prototypes for the
+ * OLE 2.0 UI <FULLNAME> dialog.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+
+#ifndef <UFILL>
+#define <UFILL>
+
+// UFILL> Move from here to INTERNAL to to OLE2UI.H
+
+
+typedef struct tagOLEUI<STRUCT>
+{
+ // These IN fields are standard across all OLEUI dialog functions.
+ DWORD cbStruct; //Structure Size
+ DWORD dwFlags; //IN-OUT: Flags
+ HWND hWndOwner; //Owning window
+ LPCTSTR lpszCaption; //Dialog caption bar contents
+ LPFNOLEUIHOOK lpfnHook; //Hook callback
+ LPARAM lCustData; //Custom data to pass to hook
+ HINSTANCE hInstance; //Instance for customized template name
+ LPCTSTR lpszTemplate; //Customized template name
+ HRSRC hResource; //Customized template handle
+
+ // Specifics for OLEUI<STRUCT>. All are IN-OUT unless otherwise spec.
+} OLEUI<STRUCT>, *POLEUI<STRUCT>, FAR *LPOLEUI<STRUCT>;
+
+
+// API Prototype
+UINT FAR PASCAL OleUI<NAME>(LPOLEUI<STRUCT>);
+
+
+// <FULLNAME> flags
+#define <ABBREV>F_SHOWHELP 0x00000001L
+<UFILL>
+
+
+// <FULLNAME> specific error codes
+// DEFINE AS OLEUI_<ABBREV>ERR_<ERROR> (OLEUI_ERR_STANDARDMAX+n)
+<UFILL>
+
+
+// <FULLNAME> Dialog identifiers
+// FILL IN DIALOG IDs HERE
+<UFILL>
+
+
+
+
+
+// INTERNAL INFORMATION STARTS HERE
+
+// Internally used structure
+typedef struct tag<STRUCT>
+{
+ //Keep this item first as the Standard* functions depend on it here.
+ LPOLEUI<STRUCT> lpO<ABBREV>; //Original structure passed.
+ UINT nIDD; // IDD of dialog (used for help info)
+
+ /*
+ * What we store extra in this structure besides the original caller's
+ * pointer are those fields that we need to modify during the life of
+ * the dialog but that we don't want to change in the original structure
+ * until the user presses OK.
+ */
+
+ <UFILL>
+} <STRUCT>, *P<STRUCT>;
+
+
+// Internal function prototypes
+// <FILE>.CPP
+
+BOOL FAR PASCAL <NAME>DialogProc(HWND, UINT, WPARAM, LPARAM);
+BOOL F<NAME>Init(HWND hDlg, WPARAM, LPARAM);
+<UFILL>
+
+
+#endif //<UFILL>
diff --git a/private/ole2ui32/test/ansi/makefile b/private/ole2ui32/test/ansi/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ole2ui32/test/ansi/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ole2ui32/test/ansi/sources b/private/ole2ui32/test/ansi/sources
new file mode 100644
index 000000000..ece5f65d4
--- /dev/null
+++ b/private/ole2ui32/test/ansi/sources
@@ -0,0 +1,53 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+
+
+!ENDIF
+
+BLDCRT=1
+
+MAJORCOMP=toledlg
+MINORCOMP=
+
+TARGETPATH=obj
+C_DEFINES=-DWIN32 -DINC_OLE2
+
+TARGETNAME=toledlg
+TARGETTYPE=PROGRAM
+
+INCLUDES=$(BASEDIR)\private\cinc;..;
+GPSIZE=32
+
+386_OPTIMIZATION=/Oy-
+
+SOURCES=..\winmain.cxx \
+ ..\about.cxx \
+ ..\mwclass.cxx \
+ ..\message.cxx \
+ ..\linkcntr.cxx \
+ ..\tole2ui.rc \
+ ..\cdialog.cxx \
+ ..\cwindow.cxx \
+
+
+LINKLIBS=$(BASEDIR)\public\sdk\lib\*\ole32.lib\
+ $(BASEDIR)\public\sdk\lib\*\oledlg.lib
+
+UMTYPE=windows
+UMENTRY=winmain
diff --git a/private/ole2ui32/test/unicode/makefile b/private/ole2ui32/test/unicode/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ole2ui32/test/unicode/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ole2ui32/test/unicode/sources b/private/ole2ui32/test/unicode/sources
new file mode 100644
index 000000000..668b5a089
--- /dev/null
+++ b/private/ole2ui32/test/unicode/sources
@@ -0,0 +1,53 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+
+
+!ENDIF
+
+BLDCRT=1
+
+MAJORCOMP=toledlg
+MINORCOMP=
+
+TARGETPATH=obj
+C_DEFINES=-DWIN32 -DINC_OLE2 -DUNICODE
+
+TARGETNAME=toledlg
+TARGETTYPE=PROGRAM
+
+INCLUDES=$(BASEDIR)\private\cinc;..;
+GPSIZE=32
+
+386_OPTIMIZATION=/Oy-
+
+SOURCES=..\winmain.cxx \
+ ..\about.cxx \
+ ..\mwclass.cxx \
+ ..\message.cxx \
+ ..\linkcntr.cxx \
+ ..\tole2ui.rc \
+ ..\cdialog.cxx \
+ ..\cwindow.cxx \
+
+
+LINKLIBS=$(BASEDIR)\public\sdk\lib\*\ole32.lib\
+ $(BASEDIR)\public\sdk\lib\*\oledlg.lib
+
+UMTYPE=windows
+UMENTRY=winmain
diff --git a/private/ole2ui32/uiclass.h b/private/ole2ui32/uiclass.h
new file mode 100644
index 000000000..598c874c9
--- /dev/null
+++ b/private/ole2ui32/uiclass.h
@@ -0,0 +1,7 @@
+#define SZCLASSICONBOX1 "OLE2UIiconbox"
+#define SZCLASSICONBOX2 "MFCUIA32iconbox"
+#define SZCLASSICONBOX3 "MFCUIW32iconbox"
+#define SZCLASSRESULTIMAGE1 "OLE2UIresimage"
+#define SZCLASSRESULTIMAGE2 "MFCUIA32resimage"
+#define SZCLASSRESULTIMAGE3 "MFCUIW32resimage"
+
diff --git a/private/ole2ui32/utility.cpp b/private/ole2ui32/utility.cpp
new file mode 100644
index 000000000..3a663585d
--- /dev/null
+++ b/private/ole2ui32/utility.cpp
@@ -0,0 +1,830 @@
+/*
+ * UTILITY.CPP
+ *
+ * Utility routines for functions inside OLEDLG.DLL
+ *
+ * General:
+ * ----------------------
+ * HourGlassOn Displays the hourglass
+ * HourGlassOff Hides the hourglass
+ *
+ * Misc Tools:
+ * ----------------------
+ * Browse Displays the "File..." or "Browse..." dialog.
+ * ReplaceCharWithNull Used to form filter strings for Browse.
+ * ErrorWithFile Creates an error message with embedded filename
+ * OpenFileError Give error message for OpenFile error return
+ * ChopText Chop a file path to fit within a specified width
+ * DoesFileExist Checks if file is valid
+ *
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+#include "precomp.h"
+#include "common.h"
+#include <stdlib.h>
+#include <commdlg.h>
+#include <memory.h>
+#include <cderr.h>
+#include "utility.h"
+
+OLEDBGDATA
+
+/*
+ * HourGlassOn
+ *
+ * Purpose:
+ * Shows the hourglass cursor returning the last cursor in use.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * HCURSOR Cursor in use prior to showing the hourglass.
+ */
+
+HCURSOR WINAPI HourGlassOn(void)
+{
+ HCURSOR hCur;
+
+ hCur=SetCursor(LoadCursor(NULL, IDC_WAIT));
+ ShowCursor(TRUE);
+
+ return hCur;
+}
+
+
+/*
+ * HourGlassOff
+ *
+ * Purpose:
+ * Turns off the hourglass restoring it to a previous cursor.
+ *
+ * Parameters:
+ * hCur HCURSOR as returned from HourGlassOn
+ *
+ * Return Value:
+ * None
+ */
+
+void WINAPI HourGlassOff(HCURSOR hCur)
+{
+ ShowCursor(FALSE);
+ SetCursor(hCur);
+ return;
+}
+
+
+/*
+ * Browse
+ *
+ * Purpose:
+ * Displays the standard GetOpenFileName dialog with the title of
+ * "Browse." The types listed in this dialog are controlled through
+ * iFilterString. If it's zero, then the types are filled with "*.*"
+ * Otherwise that string is loaded from resources and used.
+ *
+ * Parameters:
+ * hWndOwner HWND owning the dialog
+ * lpszFile LPSTR specifying the initial file and the buffer in
+ * which to return the selected file. If there is no
+ * initial file the first character of this string should
+ * be NULL.
+ * lpszInitialDir LPSTR specifying the initial directory. If none is to
+ * set (ie, the cwd should be used), then this parameter
+ * should be NULL.
+ * cchFile UINT length of pszFile
+ * iFilterString UINT index into the stringtable for the filter string.
+ * dwOfnFlags DWORD flags to OR with OFN_HIDEREADONLY
+ * nBrowseID
+ * lpfnHook Callback Hook Proceedure. Set if OFN_ENABLE_HOOK is
+ * in dwOfnFlags else it should be NULL.
+ *
+ * Return Value:
+ * BOOL TRUE if the user selected a file and pressed OK.
+ * FALSE otherwise, such as on pressing Cancel.
+ */
+
+BOOL WINAPI Browse(HWND hWndOwner, LPTSTR lpszFile, LPTSTR lpszInitialDir, UINT cchFile,
+ UINT iFilterString, DWORD dwOfnFlags, UINT nBrowseID, LPOFNHOOKPROC lpfnHook)
+{
+ UINT cch;
+ TCHAR szFilters[256];
+ TCHAR szDlgTitle[128]; // that should be big enough
+
+ if (NULL == lpszFile || 0 == cchFile)
+ return FALSE;
+
+ /*
+ * Exact contents of the filter combobox is TBD. One idea
+ * is to take all the extensions in the RegDB and place them in here
+ * with the descriptive class name associate with them. This has the
+ * extra step of finding all extensions of the same class handler and
+ * building one extension string for all of them. Can get messy quick.
+ * UI demo has only *.* which we do for now.
+ */
+
+ if (0 != iFilterString)
+ {
+ cch = LoadString(_g_hOleStdResInst, iFilterString, szFilters,
+ sizeof(szFilters)/sizeof(TCHAR));
+ }
+ else
+ {
+ szFilters[0] = 0;
+ cch = 1;
+ }
+
+ if (0 == cch)
+ return FALSE;
+
+ ReplaceCharWithNull(szFilters, szFilters[cch-1]);
+
+ // Prior string must also be initialized, if there is one.
+ OPENFILENAME ofn;
+ memset(&ofn, 0, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = hWndOwner;
+ ofn.lpstrFile = lpszFile;
+ ofn.nMaxFile = cchFile;
+ ofn.lpstrFilter = szFilters;
+ ofn.nFilterIndex = 1;
+ ofn.lpfnHook = lpfnHook;
+ if (LoadString(_g_hOleStdResInst, IDS_BROWSE, szDlgTitle, sizeof(szDlgTitle)/sizeof(TCHAR)))
+ ofn.lpstrTitle = szDlgTitle;
+ ofn.hInstance = _g_hOleStdResInst;
+ if (NULL != lpszInitialDir)
+ ofn.lpstrInitialDir = lpszInitialDir;
+ ofn.Flags = OFN_HIDEREADONLY | dwOfnFlags;
+ if (bWin4)
+ ofn.Flags |= OFN_EXPLORER;
+
+ // Lastly, parent to tweak OFN parameters
+ if (hWndOwner != NULL)
+ SendMessage(hWndOwner, uMsgBrowseOFN, nBrowseID, (LPARAM)&ofn);
+
+ // On success, copy the chosen filename to the static display
+ BOOL bResult = StandardGetOpenFileName((LPOPENFILENAME)&ofn);
+ return bResult;
+}
+
+/*
+ * ReplaceCharWithNull
+ *
+ * Purpose:
+ * Walks a null-terminated string and replaces a given character
+ * with a zero. Used to turn a single string for file open/save
+ * filters into the appropriate filter string as required by the
+ * common dialog API.
+ *
+ * Parameters:
+ * psz LPTSTR to the string to process.
+ * ch int character to replace.
+ *
+ * Return Value:
+ * int Number of characters replaced. -1 if psz is NULL.
+ */
+
+int WINAPI ReplaceCharWithNull(LPTSTR psz, int ch)
+{
+ int cChanged = 0;
+
+ if (psz == NULL)
+ return -1;
+
+ while ('\0' != *psz)
+ {
+ if (ch == *psz)
+ {
+ *psz++ = '\0';
+ cChanged++;
+ continue;
+ }
+ psz = CharNext(psz);
+ }
+ return cChanged;
+}
+
+/*
+ * ErrorWithFile
+ *
+ * Purpose:
+ * Displays a message box built from a stringtable string containing
+ * one %s as a placeholder for a filename and from a string of the
+ * filename to place there.
+ *
+ * Parameters:
+ * hWnd HWND owning the message box. The caption of this
+ * window is the caption of the message box.
+ * hInst HINSTANCE from which to draw the idsErr string.
+ * idsErr UINT identifier of a stringtable string containing
+ * the error message with a %s.
+ * lpszFile LPSTR to the filename to include in the message.
+ * uFlags UINT flags to pass to MessageBox, like MB_OK.
+ *
+ * Return Value:
+ * int Return value from MessageBox.
+ */
+
+int WINAPI ErrorWithFile(HWND hWnd, HINSTANCE hInst, UINT idsErr,
+ LPTSTR pszFile, UINT uFlags)
+{
+ int iRet=0;
+ HANDLE hMem;
+ const UINT cb = (2*MAX_PATH);
+ LPTSTR psz1, psz2, psz3;
+
+ if (NULL == hInst || NULL == pszFile)
+ return iRet;
+
+ // Allocate three 2*MAX_PATH byte work buffers
+ hMem=GlobalAlloc(GHND, (DWORD)(3*cb)*sizeof(TCHAR));
+
+ if (NULL==hMem)
+ return iRet;
+
+ psz1 = (LPTSTR)GlobalLock(hMem);
+ psz2 = psz1+cb;
+ psz3 = psz2+cb;
+
+ if (0 != LoadString(hInst, idsErr, psz1, cb))
+ {
+ wsprintf(psz2, psz1, pszFile);
+
+ // Steal the caption of the dialog
+ GetWindowText(hWnd, psz3, cb);
+ iRet=MessageBox(hWnd, psz2, psz3, uFlags);
+ }
+
+ GlobalUnlock(hMem);
+ GlobalFree(hMem);
+ return iRet;
+}
+
+// returns width of line of text. this is a support routine for ChopText
+static LONG GetTextWSize(HDC hDC, LPTSTR lpsz)
+{
+ SIZE size;
+
+ if (GetTextExtentPoint(hDC, lpsz, lstrlen(lpsz), (LPSIZE)&size))
+ return size.cx;
+ else
+ return 0;
+}
+
+LPTSTR FindChar(LPTSTR lpsz, TCHAR ch)
+{
+ while (*lpsz != 0)
+ {
+ if (*lpsz == ch)
+ return lpsz;
+ lpsz = CharNext(lpsz);
+ }
+ return NULL;
+}
+
+LPTSTR FindReverseChar(LPTSTR lpsz, TCHAR ch)
+{
+ LPTSTR lpszLast = NULL;
+ while (*lpsz != 0)
+ {
+ if (*lpsz == ch)
+ lpszLast = lpsz;
+ lpsz = CharNext(lpsz);
+ }
+ return lpszLast;
+}
+
+static void WINAPI Abbreviate(HDC hdc, int nWidth, LPTSTR lpch, int nMaxChars)
+{
+ /* string is too long to fit; chop it */
+ /* set up new prefix & determine remaining space in control */
+ LPTSTR lpszFileName = NULL;
+ LPTSTR lpszCur = CharNext(CharNext(lpch));
+ lpszCur = FindChar(lpszCur, TEXT('\\'));
+
+ // algorithm will insert \... so allocate extra 4
+ LPTSTR lpszNew = (LPTSTR)OleStdMalloc((lstrlen(lpch)+5) * sizeof(TCHAR));
+ if (lpszNew == NULL)
+ return;
+
+ if (lpszCur != NULL) // at least one backslash
+ {
+ *lpszNew = (TCHAR)0;
+ *lpszCur = (TCHAR)0;
+ lstrcpy(lpszNew, lpch);
+ *lpszCur = TEXT('\\');
+ // lpszNew now contains c: or \\servername
+ lstrcat(lpszNew, TEXT("\\..."));
+ // lpszNew now contains c:\... or \\servername\...
+ LPTSTR lpszEnd = lpszNew;
+ while (*lpszEnd != (TCHAR)0)
+ lpszEnd = CharNext(lpszEnd);
+ // lpszEnd is now at the end of c:\... or \\servername\...
+
+ // move down directories until it fits or no more directories
+ while (lpszCur != NULL)
+ {
+ *lpszEnd = (TCHAR)0;
+ lstrcat(lpszEnd, lpszCur);
+ if (GetTextWSize(hdc, lpszNew) <= nWidth &&
+ lstrlen(lpszNew) < nMaxChars)
+ {
+ lstrcpyn(lpch, lpszNew, nMaxChars);
+ OleStdFree(lpszNew);
+ return;
+ }
+ lpszCur = CharNext(lpszCur); // advance past backslash
+ lpszCur = FindChar(lpszCur, TEXT('\\'));
+ }
+
+ // try just ...filename and then shortening filename
+ lpszFileName = FindReverseChar(lpch, TEXT('\\'));
+ }
+ else
+ lpszFileName = lpch;
+
+ while (*lpszFileName != (TCHAR)0)
+ {
+ lstrcpy(lpszNew, TEXT("..."));
+ lstrcat(lpszNew, lpszFileName);
+ if (GetTextWSize(hdc, lpszNew) <= nWidth && lstrlen(lpszNew) < nMaxChars)
+ {
+ lstrcpyn(lpch, lpszNew, nMaxChars);
+ OleStdFree(lpszNew);
+ return;
+ }
+ lpszFileName = CharNext(lpszFileName);
+ }
+
+ OleStdFree(lpszNew);
+
+ // not even a single character fit
+ *lpch = (TCHAR)0;
+}
+
+/*
+ * ChopText
+ *
+ * Purpose:
+ * Parse a string (pathname) and convert it to be within a specified
+ * length by chopping the least significant part
+ *
+ * Parameters:
+ * hWnd window handle in which the string resides
+ * nWidth max width of string in pixels
+ * use width of hWnd if zero
+ * lpch pointer to beginning of the string
+ * nMaxChars maximum allowable number of characters (0 ignore)
+ *
+ * Return Value:
+ * pointer to the modified string
+ */
+LPTSTR WINAPI ChopText(HWND hWnd, int nWidth, LPTSTR lpch, int nMaxChars)
+{
+ HDC hdc;
+ HFONT hfont;
+ HFONT hfontOld = NULL;
+ RECT rc;
+
+ if (!hWnd || !lpch)
+ return NULL;
+
+ if (nMaxChars == 0)
+ nMaxChars = 32768; // big number
+
+ /* Get length of static field. */
+ if (!nWidth)
+ {
+ GetClientRect(hWnd, (LPRECT)&rc);
+ nWidth = rc.right - rc.left;
+ }
+
+ /* Set up DC appropriately for the static control */
+ hdc = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL);
+ hfont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0L);
+
+ if (NULL != hfont) // WM_GETFONT returns NULL if window uses system font
+ hfontOld = (HFONT)SelectObject(hdc, hfont);
+
+ /* check horizontal extent of string */
+ if (GetTextWSize(hdc, lpch) > nWidth || lstrlen(lpch) >= nMaxChars)
+ Abbreviate(hdc, nWidth, lpch, nMaxChars);
+
+ if (NULL != hfont)
+ SelectObject(hdc, hfontOld);
+ DeleteDC(hdc);
+
+ return lpch;
+}
+
+/*
+ * OpenFileError
+ *
+ * Purpose:
+ * display message for error returned from OpenFile
+ *
+ * Parameters:
+ * hDlg HWND of the dialog.
+ * nErrCode UINT error code returned in OFSTRUCT passed to OpenFile
+ * lpszFile LPSTR file name passed to OpenFile
+ *
+ * Return Value:
+ * None
+ */
+void WINAPI OpenFileError(HWND hDlg, UINT nErrCode, LPTSTR lpszFile)
+{
+ switch (nErrCode)
+ {
+ case 0x0005: // Access denied
+ ErrorWithFile(hDlg, _g_hOleStdResInst, IDS_CIFILEACCESS, lpszFile,
+ MB_OK | MB_ICONEXCLAMATION);
+ break;
+
+ case 0x0020: // Sharing violation
+ ErrorWithFile(hDlg, _g_hOleStdResInst, IDS_CIFILESHARE, lpszFile,
+ MB_OK | MB_ICONEXCLAMATION);
+ break;
+
+ case 0x0002: // File not found
+ case 0x0003: // Path not found
+ ErrorWithFile(hDlg, _g_hOleStdResInst, IDS_CIINVALIDFILE, lpszFile,
+ MB_OK | MB_ICONEXCLAMATION);
+ break;
+
+ default:
+ ErrorWithFile(hDlg, _g_hOleStdResInst, IDS_CIFILEOPENFAIL, lpszFile,
+ MB_OK | MB_ICONEXCLAMATION);
+ break;
+ }
+}
+
+/*
+ * DoesFileExist
+ *
+ * Purpose:
+ * Determines if a file path exists
+ *
+ * Parameters:
+ * lpszFile LPTSTR - file name
+ * cchMax UINT - size of the lpszFile string buffer in characters.
+ *
+ * Return Value:
+ * BOOL TRUE if file exists, else FALSE.
+ *
+ * NOTE: lpszFile may be changed as a result of this call to match the first
+ * matching file name found by this routine.
+ *
+ */
+BOOL WINAPI DoesFileExist(LPTSTR lpszFile, UINT cchMax)
+{
+ static const TCHAR *arrIllegalNames[] =
+ {
+ TEXT("LPT1"), TEXT("LPT2"), TEXT("LPT3"),
+ TEXT("COM1"), TEXT("COM2"), TEXT("COM3"), TEXT("COM4"),
+ TEXT("CON"), TEXT("AUX"), TEXT("PRN")
+ };
+
+ // check is the name is an illegal name (eg. the name of a device)
+ for (int i = 0; i < (sizeof(arrIllegalNames)/sizeof(arrIllegalNames[0])); i++)
+ {
+ if (lstrcmpi(lpszFile, arrIllegalNames[i])==0)
+ return FALSE;
+ }
+
+ // First try to find the file with an exact match
+
+ // check the file's attributes
+ DWORD dwAttrs = GetFileAttributes(lpszFile);
+ if (dwAttrs == 0xFFFFFFFF) // file wasn't found
+ {
+ // look in path for file
+ TCHAR szTempFileName[MAX_PATH];
+ LPTSTR lpszFilePart;
+ BOOL fFound = SearchPath(NULL, lpszFile, NULL, MAX_PATH, szTempFileName, &lpszFilePart) != 0;
+ if (!fFound)
+ {
+ // File wasn't found in the search path
+ // Try to append a .* and use FindFirstFile to try for a match in the current directory
+ UINT cchFile = lstrlen(lpszFile);
+ if (cchFile + 4 < MAX_PATH)
+ {
+ WIN32_FIND_DATA sFindFileData;
+ lstrcpy(szTempFileName,lpszFile);
+ lstrcpy(&szTempFileName[cchFile], TEXT("*.*"));
+ HANDLE hFindFile = FindFirstFile(szTempFileName, &sFindFileData);
+ if (INVALID_HANDLE_VALUE != hFindFile)
+ {
+ // found something
+ while (0 != sFindFileData.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_TEMPORARY))
+ {
+ // found a directory or a temporary file try again
+ if (!FindNextFile(hFindFile, &sFindFileData))
+ {
+ // Could only match a directory or temporary file.
+ FindClose(hFindFile);
+ return(FALSE);
+ }
+ }
+ // Copy the name of the found file into the end of the path in the
+ // temporary buffer (if any).
+ // First scan back for the last file separator.
+ UINT cchPath = lstrlen(szTempFileName);
+ while (cchPath)
+ {
+ if (_T('\\') == szTempFileName[cchPath - 1]
+ || _T('/') == szTempFileName[cchPath - 1])
+ {
+ break;
+ }
+ cchPath--;
+ }
+ lstrcpyn(&szTempFileName[cchPath], sFindFileData.cFileName, MAX_PATH - cchPath);
+ fFound = TRUE;
+ FindClose(hFindFile);
+ }
+ }
+ }
+ if (fFound)
+ {
+ // copy the temporary buffer into szFile
+ lstrcpyn(lpszFile, szTempFileName, cchMax -1);
+ }
+ return(fFound);
+ }
+ else if (dwAttrs & (FILE_ATTRIBUTE_DIRECTORY|
+ FILE_ATTRIBUTE_TEMPORARY))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * FormatStrings
+ *
+ * Purpose:
+ * Simple message formatting API compatible w/ different languages
+ *
+ * Note:
+ * Shamelessly stolen/modified from MFC source code
+ *
+ */
+
+void WINAPI FormatStrings(LPTSTR lpszDest, LPCTSTR lpszFormat,
+ LPCTSTR* rglpsz, int nString)
+{
+ LPCTSTR pchSrc = lpszFormat;
+ while (*pchSrc != '\0')
+ {
+ if (pchSrc[0] == '%' && (pchSrc[1] >= '1' && pchSrc[1] <= '9'))
+ {
+ int i = pchSrc[1] - '1';
+ pchSrc += 2;
+ if (i >= nString)
+ *lpszDest++ = '?';
+ else if (rglpsz[i] != NULL)
+ {
+ lstrcpy(lpszDest, rglpsz[i]);
+ lpszDest += lstrlen(lpszDest);
+ }
+ }
+ else
+ {
+#ifndef _UNICODE
+ if (IsDBCSLeadByte(*pchSrc))
+ *lpszDest++ = *pchSrc++; // copy first of 2 bytes
+#endif
+ *lpszDest++ = *pchSrc++;
+ }
+ }
+ *lpszDest = '\0';
+}
+
+void WINAPI FormatString1(LPTSTR lpszDest, LPCTSTR lpszFormat, LPCTSTR lpsz1)
+{
+ FormatStrings(lpszDest, lpszFormat, &lpsz1, 1);
+}
+
+void WINAPI FormatString2(LPTSTR lpszDest, LPCTSTR lpszFormat, LPCTSTR lpsz1,
+ LPCTSTR lpsz2)
+{
+ LPCTSTR rglpsz[2];
+ rglpsz[0] = lpsz1;
+ rglpsz[1] = lpsz2;
+ FormatStrings(lpszDest, lpszFormat, rglpsz, 2);
+}
+
+// Replacement for stdlib atol,
+// which didn't work and doesn't take far pointers.
+// Must be tolerant of leading spaces.
+//
+//
+LONG WINAPI Atol(LPTSTR lpsz)
+{
+ signed int sign = +1;
+ UINT base = 10;
+ LONG l = 0;
+
+ if (NULL==lpsz)
+ {
+ OleDbgAssert (0);
+ return 0;
+ }
+ while (*lpsz == ' ' || *lpsz == '\t' || *lpsz == '\n')
+ lpsz++;
+
+ if (*lpsz=='-')
+ {
+ lpsz++;
+ sign = -1;
+ }
+ if (lpsz[0] == TEXT('0') && lpsz[1] == TEXT('x'))
+ {
+ base = 16;
+ lpsz+=2;
+ }
+
+ if (base == 10)
+ {
+ while (*lpsz >= '0' && *lpsz <= '9')
+ {
+ l = l * base + *lpsz - '0';
+ lpsz++;
+ }
+ }
+ else
+ {
+ OleDbgAssert(base == 16);
+ while (*lpsz >= '0' && *lpsz <= '9' ||
+ *lpsz >= 'A' && *lpsz <= 'F' ||
+ *lpsz >= 'a' && *lpsz <= 'f')
+ {
+ l = l * base;
+ if (*lpsz >= '0' && *lpsz <= '9')
+ l += *lpsz - '0';
+ else if (*lpsz >= 'a' && *lpsz <= 'f')
+ l += *lpsz - 'a' + 10;
+ else
+ l += *lpsz - 'A' + 10;
+ lpsz++;
+ }
+ }
+ return l * sign;
+}
+
+BOOL WINAPI IsValidClassID(REFCLSID clsid)
+{
+ return clsid != CLSID_NULL;
+}
+
+/* PopupMessage
+ * ------------
+ *
+ * Purpose:
+ * Popup messagebox and get some response from the user. It is the same
+ * as MessageBox() except that the title and message string are loaded
+ * from the resource file.
+ *
+ * Parameters:
+ * hwndParent parent window of message box
+ * idTitle id of title string
+ * idMessage id of message string
+ * fuStyle style of message box
+ */
+int WINAPI PopupMessage(HWND hwndParent, UINT idTitle, UINT idMessage, UINT fuStyle)
+{
+ TCHAR szTitle[256];
+ TCHAR szMsg[256];
+
+ LoadString(_g_hOleStdResInst, idTitle, szTitle, sizeof(szTitle)/sizeof(TCHAR));
+ LoadString(_g_hOleStdResInst, idMessage, szMsg, sizeof(szMsg)/sizeof(TCHAR));
+ return MessageBox(hwndParent, szMsg, szTitle, fuStyle);
+}
+
+/* DiffPrefix
+ * ----------
+ *
+ * Purpose:
+ * Compare (case-insensitive) two strings and return the prefixes of the
+ * the strings formed by removing the common suffix string from them.
+ * Integrity of tokens (directory name, filename and object names) are
+ * preserved. Note that the prefixes are converted to upper case
+ * characters.
+ *
+ * Parameters:
+ * lpsz1 string 1
+ * lpsz2 string 2
+ * lplpszPrefix1 prefix of string 1
+ * lplpszPrefix2 prefix of string 2
+ *
+ * Returns:
+ *
+ */
+void WINAPI DiffPrefix(LPCTSTR lpsz1, LPCTSTR lpsz2, TCHAR FAR* FAR* lplpszPrefix1, TCHAR FAR* FAR* lplpszPrefix2)
+{
+ LPTSTR lpstr1;
+ LPTSTR lpstr2;
+ TCHAR szTemp1[MAX_PATH];
+ TCHAR szTemp2[MAX_PATH];
+
+ OleDbgAssert(lpsz1);
+ OleDbgAssert(lpsz2);
+ OleDbgAssert(*lpsz1);
+ OleDbgAssert(*lpsz2);
+ OleDbgAssert(lplpszPrefix1);
+ OleDbgAssert(lplpszPrefix2);
+
+ // need to copy into temporary for case insensitive compare
+ lstrcpy(szTemp1, lpsz1);
+ lstrcpy(szTemp2, lpsz2);
+ CharLower(szTemp1);
+ CharLower(szTemp2);
+
+ // do comparison
+ lpstr1 = szTemp1 + lstrlen(szTemp1);
+ lpstr2 = szTemp2 + lstrlen(szTemp2);
+
+ while ((lpstr1 > szTemp1) && (lpstr2 > szTemp2))
+ {
+ lpstr1 = CharPrev(szTemp1, lpstr1);
+ lpstr2 = CharPrev(szTemp2, lpstr2);
+ if (*lpstr1 != *lpstr2)
+ {
+ lpstr1 = CharNext(lpstr1);
+ lpstr2 = CharNext(lpstr2);
+ break;
+ }
+ }
+
+ // scan forward to first delimiter
+ while (*lpstr1 && *lpstr1 != '\\' && *lpstr1 != '!')
+ lpstr1 = CharNext(lpstr1);
+ while (*lpstr2 && *lpstr2 != '\\' && *lpstr2 != '!')
+ lpstr2 = CharNext(lpstr2);
+
+ *lpstr1 = '\0';
+ *lpstr2 = '\0';
+
+ // initialize in case of failure
+ *lplpszPrefix1 = NULL;
+ *lplpszPrefix2 = NULL;
+
+ // allocate memory for the result
+ *lplpszPrefix1 = (LPTSTR)OleStdMalloc((lstrlen(lpsz1)+1) * sizeof(TCHAR));
+ if (!*lplpszPrefix1)
+ return;
+
+ *lplpszPrefix2 = (LPTSTR)OleStdMalloc((lstrlen(lpsz2)+1) * sizeof(TCHAR));
+ if (!*lplpszPrefix2)
+ {
+ OleStdFree(*lplpszPrefix1);
+ *lplpszPrefix1 = NULL;
+ return;
+ }
+
+ // copy result
+ lstrcpyn(*lplpszPrefix1, lpsz1, lstrlen(szTemp1)+1);
+ lstrcpyn(*lplpszPrefix2, lpsz2, lstrlen(szTemp2)+1);
+}
+
+UINT WINAPI GetFileName(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax)
+{
+ // always capture the complete file name including extension (if present)
+ LPTSTR lpszTemp = (LPTSTR)lpszPathName;
+ for (LPCTSTR lpsz = lpszPathName; *lpsz != '\0'; lpsz = CharNext(lpsz))
+ {
+ // remember last directory/drive separator
+ if (*lpsz == '\\' || *lpsz == '/' || *lpsz == ':')
+ lpszTemp = CharNext(lpsz);
+ }
+
+ // lpszTitle can be NULL which just returns the number of bytes
+ if (lpszTitle == NULL)
+ return lstrlen(lpszTemp)+1;
+
+ // otherwise copy it into the buffer provided
+ lstrcpyn(lpszTitle, lpszTemp, nMax);
+ return 0;
+}
+
+BOOL WINAPI IsValidMetaPict(HGLOBAL hMetaPict)
+{
+ BOOL fReturn = FALSE;
+ LPMETAFILEPICT pMF = (LPMETAFILEPICT) GlobalLock(hMetaPict);
+ if (pMF != NULL)
+ {
+ if (!IsBadReadPtr( pMF, sizeof(METAFILEPICT)))
+ {
+ if (GetMetaFileBitsEx(pMF->hMF, 0, 0))
+ {
+ fReturn = TRUE;
+ }
+ }
+ GlobalUnlock(hMetaPict);
+ }
+ return(fReturn);
+}
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/private/ole2ui32/utility.h b/private/ole2ui32/utility.h
new file mode 100644
index 000000000..e3bbe183a
--- /dev/null
+++ b/private/ole2ui32/utility.h
@@ -0,0 +1,66 @@
+/*
+ * UTILITY.H
+ *
+ * Miscellaneous prototypes and definitions for OLE UI dialogs.
+ *
+ * Copyright (c)1992 Microsoft Corporation, All Right Reserved
+ */
+
+
+#ifndef _UTILITY_H_
+#define _UTILITY_H_
+
+#define CF_CLIPBOARDMIN 0xc000
+#define CF_CLIPBOARDMAX 0xffff
+
+// Function prototypes
+// UTILITY.CPP
+HCURSOR WINAPI HourGlassOn(void);
+void WINAPI HourGlassOff(HCURSOR);
+
+BOOL WINAPI Browse(HWND, LPTSTR, LPTSTR, UINT, UINT, DWORD, UINT, LPOFNHOOKPROC);
+int WINAPI ReplaceCharWithNull(LPTSTR, int);
+int WINAPI ErrorWithFile(HWND, HINSTANCE, UINT, LPTSTR, UINT);
+BOOL WINAPI DoesFileExist(LPTSTR lpszFile, UINT cchMax);
+LONG WINAPI Atol(LPTSTR lpsz);
+BOOL WINAPI IsValidClassID(REFCLSID);
+UINT WINAPI GetFileName(LPCTSTR, LPTSTR, UINT);
+BOOL WINAPI IsValidMetaPict(HGLOBAL hMetaPict);
+
+LPTSTR FindChar(LPTSTR lpsz, TCHAR ch);
+LPTSTR FindReverseChar(LPTSTR lpsz, TCHAR ch);
+
+LPTSTR FAR PASCAL PointerToNthField(LPTSTR, int, TCHAR);
+BOOL FAR PASCAL GetAssociatedExecutable(LPTSTR, LPTSTR);
+LPTSTR WINAPI ChopText(HWND hwndStatic, int nWidth, LPTSTR lpch,
+ int nMaxChars);
+void WINAPI OpenFileError(HWND hDlg, UINT nErrCode, LPTSTR lpszFile);
+int WINAPI PopupMessage(HWND hwndParent, UINT idTitle, UINT idMessage, UINT fuStyle);
+void WINAPI DiffPrefix(LPCTSTR lpsz1, LPCTSTR lpsz2, TCHAR FAR* FAR* lplpszPrefix1, TCHAR FAR* FAR* lplpszPrefix2);
+
+// string formatting APIs
+void WINAPI FormatStrings(LPTSTR, LPCTSTR, LPCTSTR*, int);
+void WINAPI FormatString1(LPTSTR, LPCTSTR, LPCTSTR);
+void WINAPI FormatString2(LPTSTR, LPCTSTR, LPCTSTR, LPCTSTR);
+
+// global instance to load strings/resources from
+extern HINSTANCE _g_hOleStdInst;
+extern HINSTANCE _g_hOleStdResInst;
+
+// standard OLE 2.0 clipboard formats
+extern UINT _g_cfObjectDescriptor;
+extern UINT _g_cfLinkSrcDescriptor;
+extern UINT _g_cfEmbedSource;
+extern UINT _g_cfEmbeddedObject;
+extern UINT _g_cfLinkSource;
+extern UINT _g_cfOwnerLink;
+extern UINT _g_cfFileName;
+
+// Metafile utility functions
+STDAPI_(void) OleUIMetafilePictIconFree(HGLOBAL);
+STDAPI_(BOOL) OleUIMetafilePictIconDraw(HDC, LPCRECT, HGLOBAL, BOOL);
+STDAPI_(UINT) OleUIMetafilePictExtractLabel(HGLOBAL, LPTSTR, UINT, LPDWORD);
+STDAPI_(HICON) OleUIMetafilePictExtractIcon(HGLOBAL);
+STDAPI_(BOOL) OleUIMetafilePictExtractIconSource(HGLOBAL, LPTSTR, UINT FAR *);
+
+#endif //_UTILITY_H_
diff --git a/private/ole2ui32/win32s/makefile b/private/ole2ui32/win32s/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ole2ui32/win32s/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ole2ui32/win32s/oledlg.def b/private/ole2ui32/win32s/oledlg.def
new file mode 100644
index 000000000..3165d10db
--- /dev/null
+++ b/private/ole2ui32/win32s/oledlg.def
@@ -0,0 +1,46 @@
+;///////////////////////////////////////////////////////////////////////////
+;
+; ole2ui.def
+;
+; Definition file for oledlg.dll
+; c) Copyright Microsoft Corp. 1992 - 1994 All Rights Reserved
+;
+
+DESCRIPTION 'OLEDLG - OLE 2 Common Dialog Support Library.'
+EXPORTS
+
+; Narrow APIs:
+
+; OLE Menu APIs
+OleUIAddVerbMenuA @1
+OleUICanConvertOrActivateAs @2
+
+; OLE Common Dialog APIs
+OleUIInsertObjectA @3
+OleUIPasteSpecialA @4
+OleUIEditLinksA @5
+OleUIChangeIconA @6
+OleUIConvertA @7
+OleUIBusyA @8
+OleUIUpdateLinksA @9
+OleUIPromptUserA @10
+OleUIObjectPropertiesA @11
+OleUIChangeSourceA @12
+
+; Wide APIs:
+
+; OLE Menu APIs
+OleUIAddVerbMenuW
+
+; OLE Common Dialog APIs
+OleUIInsertObjectW=ReturnError
+OleUIPasteSpecialW=ReturnError
+OleUIEditLinksW=ReturnError
+OleUIChangeIconW=ReturnError
+OleUIConvertW=ReturnError
+OleUIBusyW=ReturnError
+OleUIUpdateLinksW
+OleUIPromptUserW
+OleUIObjectPropertiesW=ReturnError
+OleUIChangeSourceW=ReturnError
+
diff --git a/private/ole2ui32/win32s/sources b/private/ole2ui32/win32s/sources
new file mode 100644
index 000000000..7e4402456
--- /dev/null
+++ b/private/ole2ui32/win32s/sources
@@ -0,0 +1,78 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+
+
+!ENDIF
+
+
+DLLENTRY=DllMain
+
+DLLDEF=obj\*\oledlg.def
+
+MAJORCOMP=oledlg
+MINORCOMP=
+
+TARGETNAME=oledlg
+TARGETPATH=obj
+C_DEFINES=-DWIN32 -DWINVER=0x400
+TARGETTYPE=DYNLINK
+
+UMTYPE=windows
+
+INCLUDES=..
+
+PRECOMPILED_INCLUDE=..\precomp.h
+PRECOMPILED_PCH=precomp.pch
+PRECOMPILED_OBJ=precomp.obj
+
+
+386_OPTIMIZATION=/Oy-
+
+SOURCES= ..\chngsrc.cpp \
+ ..\objprop.cpp \
+ ..\busy.cpp \
+ ..\common.cpp \
+ ..\convert.cpp \
+ ..\drawicon.cpp \
+ ..\icon.cpp \
+ ..\iconbox.cpp \
+ ..\insobj.cpp \
+ ..\links.cpp \
+ ..\ole2ui.cpp \
+ ..\olestd.cpp \
+ ..\pastespl.cpp \
+ ..\targtdev.cpp \
+ ..\oleutl.cpp \
+ ..\resimage.cpp \
+ ..\utility.cpp \
+ ..\dllfuncs.cpp \
+ ..\geticon.cpp \
+ ..\wrapstub.cpp \
+ ..\ole2ui.rc
+
+USE_CRTDLL=1
+
+LINKLIBS= \
+ $(BASEDIR)\public\sdk\lib\*\kernel32.lib \
+ $(BASEDIR)\public\sdk\lib\*\user32.lib \
+ $(BASEDIR)\public\sdk\lib\*\gdi32.lib \
+ $(BASEDIR)\public\sdk\lib\*\advapi32.lib \
+ $(BASEDIR)\public\sdk\lib\*\ole32.lib \
+ $(BASEDIR)\public\sdk\lib\*\uuid.lib
+
diff --git a/private/ole2ui32/winres.h b/private/ole2ui32/winres.h
new file mode 100644
index 000000000..42eee2602
--- /dev/null
+++ b/private/ole2ui32/winres.h
@@ -0,0 +1,300 @@
+// Microsoft Foundation Classes C++ library.
+// Copyright (C) 1992 Microsoft Corporation,
+// All rights reserved.
+
+// This source code is only intended as a supplement to the
+// Microsoft Foundation Classes Reference and Microsoft
+// QuickHelp and/or WinHelp documentation provided with the library.
+// See these sources for detailed information regarding the
+// Microsoft Foundation Classes product.
+
+// winres.h - Windows resource definitions
+// extracted from WINDOWS.H
+// Version 3.10
+// Copyright (c) 1985-1992, Microsoft Corp. All rights reserved.
+//
+
+#define VS_VERSION_INFO 1
+
+#ifdef APSTUDIO_INVOKED
+#define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols
+#endif
+
+#define OBM_CLOSE 32754
+#define OBM_UPARROW 32753
+#define OBM_DNARROW 32752
+#define OBM_RGARROW 32751
+#define OBM_LFARROW 32750
+#define OBM_REDUCE 32749
+#define OBM_ZOOM 32748
+#define OBM_RESTORE 32747
+#define OBM_REDUCED 32746
+#define OBM_ZOOMD 32745
+#define OBM_RESTORED 32744
+#define OBM_UPARROWD 32743
+#define OBM_DNARROWD 32742
+#define OBM_RGARROWD 32741
+#define OBM_LFARROWD 32740
+#define OBM_MNARROW 32739
+#define OBM_COMBO 32738
+#define OBM_UPARROWI 32737
+#define OBM_DNARROWI 32736
+#define OBM_RGARROWI 32735
+#define OBM_LFARROWI 32734
+#define OBM_OLD_CLOSE 32767
+#define OBM_SIZE 32766
+#define OBM_OLD_UPARROW 32765
+#define OBM_OLD_DNARROW 32764
+#define OBM_OLD_RGARROW 32763
+#define OBM_OLD_LFARROW 32762
+#define OBM_BTSIZE 32761
+#define OBM_CHECK 32760
+#define OBM_CHECKBOXES 32759
+#define OBM_BTNCORNERS 32758
+#define OBM_OLD_REDUCE 32757
+#define OBM_OLD_ZOOM 32756
+#define OBM_OLD_RESTORE 32755
+#define OCR_NORMAL 32512
+#define OCR_IBEAM 32513
+#define OCR_WAIT 32514
+#define OCR_CROSS 32515
+#define OCR_UP 32516
+#define OCR_SIZE 32640
+#define OCR_ICON 32641
+#define OCR_SIZENWSE 32642
+#define OCR_SIZENESW 32643
+#define OCR_SIZEWE 32644
+#define OCR_SIZENS 32645
+#define OCR_SIZEALL 32646
+#define OCR_ICOCUR 32647
+#define OIC_SAMPLE 32512
+#define OIC_HAND 32513
+#define OIC_QUES 32514
+#define OIC_BANG 32515
+#define OIC_NOTE 32516
+
+#define WS_OVERLAPPED 0x00000000L
+#define WS_POPUP 0x80000000L
+#define WS_CHILD 0x40000000L
+#define WS_CLIPSIBLINGS 0x04000000L
+#define WS_CLIPCHILDREN 0x02000000L
+#define WS_VISIBLE 0x10000000L
+#define WS_DISABLED 0x08000000L
+#define WS_MINIMIZE 0x20000000L
+#define WS_MAXIMIZE 0x01000000L
+#define WS_CAPTION 0x00C00000L
+#define WS_BORDER 0x00800000L
+#define WS_DLGFRAME 0x00400000L
+#define WS_VSCROLL 0x00200000L
+#define WS_HSCROLL 0x00100000L
+#define WS_SYSMENU 0x00080000L
+#define WS_THICKFRAME 0x00040000L
+#define WS_MINIMIZEBOX 0x00020000L
+#define WS_MAXIMIZEBOX 0x00010000L
+#define WS_GROUP 0x00020000L
+#define WS_TABSTOP 0x00010000L
+
+// other aliases
+#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
+#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
+#define WS_CHILDWINDOW (WS_CHILD)
+#define WS_TILED WS_OVERLAPPED
+#define WS_ICONIC WS_MINIMIZE
+#define WS_SIZEBOX WS_THICKFRAME
+#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
+
+#define VK_LBUTTON 0x01
+#define VK_RBUTTON 0x02
+#define VK_CANCEL 0x03
+#define VK_MBUTTON 0x04
+#define VK_BACK 0x08
+#define VK_TAB 0x09
+#define VK_CLEAR 0x0C
+#define VK_RETURN 0x0D
+#define VK_SHIFT 0x10
+#define VK_CONTROL 0x11
+#define VK_MENU 0x12
+#define VK_PAUSE 0x13
+#define VK_CAPITAL 0x14
+#define VK_ESCAPE 0x1B
+#define VK_SPACE 0x20
+#define VK_PRIOR 0x21
+#define VK_NEXT 0x22
+#define VK_END 0x23
+#define VK_HOME 0x24
+#define VK_LEFT 0x25
+#define VK_UP 0x26
+#define VK_RIGHT 0x27
+#define VK_DOWN 0x28
+#define VK_SELECT 0x29
+#define VK_PRINT 0x2A
+#define VK_EXECUTE 0x2B
+#define VK_SNAPSHOT 0x2C
+#define VK_INSERT 0x2D
+#define VK_DELETE 0x2E
+#define VK_HELP 0x2F
+#define VK_NUMPAD0 0x60
+#define VK_NUMPAD1 0x61
+#define VK_NUMPAD2 0x62
+#define VK_NUMPAD3 0x63
+#define VK_NUMPAD4 0x64
+#define VK_NUMPAD5 0x65
+#define VK_NUMPAD6 0x66
+#define VK_NUMPAD7 0x67
+#define VK_NUMPAD8 0x68
+#define VK_NUMPAD9 0x69
+#define VK_MULTIPLY 0x6A
+#define VK_ADD 0x6B
+#define VK_SEPARATOR 0x6C
+#define VK_SUBTRACT 0x6D
+#define VK_DECIMAL 0x6E
+#define VK_DIVIDE 0x6F
+#define VK_F1 0x70
+#define VK_F2 0x71
+#define VK_F3 0x72
+#define VK_F4 0x73
+#define VK_F5 0x74
+#define VK_F6 0x75
+#define VK_F7 0x76
+#define VK_F8 0x77
+#define VK_F9 0x78
+#define VK_F10 0x79
+#define VK_F11 0x7A
+#define VK_F12 0x7B
+#define VK_F13 0x7C
+#define VK_F14 0x7D
+#define VK_F15 0x7E
+#define VK_F16 0x7F
+#define VK_F17 0x80
+#define VK_F18 0x81
+#define VK_F19 0x82
+#define VK_F20 0x83
+#define VK_F21 0x84
+#define VK_F22 0x85
+#define VK_F23 0x86
+#define VK_F24 0x87
+#define VK_NUMLOCK 0x90
+#define VK_SCROLL 0x91
+
+#define SC_SIZE 0xF000
+#define SC_MOVE 0xF010
+#define SC_MINIMIZE 0xF020
+#define SC_MAXIMIZE 0xF030
+#define SC_NEXTWINDOW 0xF040
+#define SC_PREVWINDOW 0xF050
+#define SC_CLOSE 0xF060
+#define SC_VSCROLL 0xF070
+#define SC_HSCROLL 0xF080
+#define SC_MOUSEMENU 0xF090
+#define SC_KEYMENU 0xF100
+#define SC_ARRANGE 0xF110
+#define SC_RESTORE 0xF120
+#define SC_TASKLIST 0xF130
+#define SC_SCREENSAVE 0xF140
+#define SC_HOTKEY 0xF150
+
+#define DS_ABSALIGN 0x01L
+#define DS_SYSMODAL 0x02L
+#define DS_LOCALEDIT 0x20L
+#define DS_SETFONT 0x40L
+#define DS_MODALFRAME 0x80L
+#define DS_NOIDLEMSG 0x100L
+
+#ifdef _MAC
+#define DS_WINDOWSUI 0x8000L
+#endif
+
+#define SS_LEFT 0x00000000L
+#define SS_CENTER 0x00000001L
+#define SS_RIGHT 0x00000002L
+#define SS_ICON 0x00000003L
+#define SS_BLACKRECT 0x00000004L
+#define SS_GRAYRECT 0x00000005L
+#define SS_WHITERECT 0x00000006L
+#define SS_BLACKFRAME 0x00000007L
+#define SS_GRAYFRAME 0x00000008L
+#define SS_WHITEFRAME 0x00000009L
+#define SS_SIMPLE 0x0000000BL
+#define SS_LEFTNOWORDWRAP 0x0000000CL
+#define SS_NOPREFIX 0x00000080L
+
+#define BS_PUSHBUTTON 0x00000000L
+#define BS_DEFPUSHBUTTON 0x00000001L
+#define BS_CHECKBOX 0x00000002L
+#define BS_AUTOCHECKBOX 0x00000003L
+#define BS_RADIOBUTTON 0x00000004L
+#define BS_3STATE 0x00000005L
+#define BS_AUTO3STATE 0x00000006L
+#define BS_GROUPBOX 0x00000007L
+#define BS_USERBUTTON 0x00000008L
+#define BS_AUTORADIOBUTTON 0x00000009L
+#define BS_OWNERDRAW 0x0000000BL
+#define BS_LEFTTEXT 0x00000020L
+
+#define ES_LEFT 0x00000000L
+#define ES_CENTER 0x00000001L
+#define ES_RIGHT 0x00000002L
+#define ES_MULTILINE 0x00000004L
+#define ES_UPPERCASE 0x00000008L
+#define ES_LOWERCASE 0x00000010L
+#define ES_PASSWORD 0x00000020L
+#define ES_AUTOVSCROLL 0x00000040L
+#define ES_AUTOHSCROLL 0x00000080L
+#define ES_NOHIDESEL 0x00000100L
+#define ES_OEMCONVERT 0x00000400L
+#define ES_READONLY 0x00000800L
+#define ES_WANTRETURN 0x00001000L
+
+#define SBS_HORZ 0x0000L
+#define SBS_VERT 0x0001L
+#define SBS_TOPALIGN 0x0002L
+#define SBS_LEFTALIGN 0x0002L
+#define SBS_BOTTOMALIGN 0x0004L
+#define SBS_RIGHTALIGN 0x0004L
+#define SBS_SIZEBOXTOPLEFTALIGN 0x0002L
+#define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L
+#define SBS_SIZEBOX 0x0008L
+
+#define LBS_NOTIFY 0x0001L
+#define LBS_SORT 0x0002L
+#define LBS_NOREDRAW 0x0004L
+#define LBS_MULTIPLESEL 0x0008L
+#define LBS_OWNERDRAWFIXED 0x0010L
+#define LBS_OWNERDRAWVARIABLE 0x0020L
+#define LBS_HASSTRINGS 0x0040L
+#define LBS_USETABSTOPS 0x0080L
+#define LBS_NOINTEGRALHEIGHT 0x0100L
+#define LBS_MULTICOLUMN 0x0200L
+#define LBS_WANTKEYBOARDINPUT 0x0400L
+#define LBS_EXTENDEDSEL 0x0800L
+#define LBS_DISABLENOSCROLL 0x1000L
+#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
+
+#define CBS_SIMPLE 0x0001L
+#define CBS_DROPDOWN 0x0002L
+#define CBS_DROPDOWNLIST 0x0003L
+#define CBS_OWNERDRAWFIXED 0x0010L
+#define CBS_OWNERDRAWVARIABLE 0x0020L
+#define CBS_AUTOHSCROLL 0x0040L
+#define CBS_OEMCONVERT 0x0080L
+#define CBS_SORT 0x0100L
+#define CBS_HASSTRINGS 0x0200L
+#define CBS_NOINTEGRALHEIGHT 0x0400L
+#define CBS_DISABLENOSCROLL 0x0800L
+
+// operation messages sent to DLGINIT
+#define WM_USER 0x0400
+#define LB_ADDSTRING (WM_USER+1)
+#define CB_ADDSTRING (WM_USER+3)
+
+#ifdef APSTUDIO_INVOKED
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#endif
+
+#define IDOK 1
+#define IDCANCEL 2
+#define IDABORT 3
+#define IDRETRY 4
+#define IDIGNORE 5
+#define IDYES 6
+#define IDNO 7
diff --git a/private/ole2ui32/wrapstub.cpp b/private/ole2ui32/wrapstub.cpp
new file mode 100644
index 000000000..fdcf69ccb
--- /dev/null
+++ b/private/ole2ui32/wrapstub.cpp
@@ -0,0 +1,1777 @@
+//+---------------------------------------------------------------------------
+//
+// Microsoft Windows
+// Copyright (C) Microsoft Corporation, 1992 - 1994.
+//
+// File: wrapstub.cpp
+//
+// Contents: ANSI to Unicode wrappers and Unicode stubs
+//
+// Classes: WrappedIOleUILinkContainer
+// WrappedIOleUIObjInfo
+// WrappedIOleUILinkInfo
+//
+// Functions:
+#ifdef UNICODE
+// OleUIAddVerbMenuA
+// OleUIInsertObjectA
+// OleUIPasteSpecialA
+// OleUIEditLinksA
+// OleUIChangeIconA
+// OleUIConvertA
+// OleUIBusyA
+// OleUIUpdateLinksA
+// OleUIObjectPropertiesA
+// OleUIChangeSourceA
+// OleUIPromptUserA
+#else
+// OleUIAddVerbMenuW
+// OleUIInsertObjectW
+// OleUIPasteSpecialW
+// OleUIEditLinksW
+// OleUIChangeIconW
+// OleUIConvertW
+// OleUIBusyW
+// OleUIUpdateLinksW
+// OleUIObjectPropertiesW
+// OleUIChangeSourceW
+// OleUIPromptUserW
+#endif
+//
+// History: 11-02-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+#include "precomp.h"
+#include "common.h"
+
+#ifdef UNICODE
+// ANSI to Unicode Wrappers
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIAddVerbMenuA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [lpOleObj] -
+// [lpszShortType] - [in] on heap
+// [hMenu] -
+// [uPos] -
+// [uIDVerbMin] -
+// [uIDVerbMax] -
+// [bAddConvert] -
+// [idConvert] -
+// [lphMenu] -
+//
+// History: 11-04-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(BOOL) OleUIAddVerbMenuA(LPOLEOBJECT lpOleObj, LPCSTR lpszShortType,
+ HMENU hMenu, UINT uPos, UINT uIDVerbMin, UINT uIDVerbMax,
+ BOOL bAddConvert, UINT idConvert, HMENU FAR *lphMenu)
+{
+ LPWSTR lpwszShortType = NULL;
+ if (lpszShortType && !IsBadReadPtr(lpszShortType, 1))
+ {
+ UINT uSize = ATOWLEN(lpszShortType);
+ lpwszShortType = (LPWSTR)OleStdMalloc(sizeof(WCHAR) * uSize);
+ if (lpwszShortType)
+ {
+ ATOW(lpwszShortType, lpszShortType, uSize);
+ }
+ }
+
+ // NOTE - if OleStdMalloc fails, this routine must still go ahead and
+ // succeed as best as it can since there is no way to report failure.
+
+ BOOL fReturn = OleUIAddVerbMenuW(lpOleObj, lpwszShortType, hMenu, uPos,
+ uIDVerbMin, uIDVerbMax, bAddConvert, idConvert, lphMenu);
+
+ if (lpwszShortType)
+ OleStdFree((LPVOID)lpwszShortType);
+
+ return(fReturn);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIInsertObjectA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpszCaption [in] on stack
+// lpszTemplate [in] on stack
+// lpszFile [in, out] on stack
+// dwFlags [out]
+// clsid [out]
+// lpIStorage [out]
+// ppvObj [out]
+// sc [out]
+// hMetaPict [out]
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) OleUIInsertObjectA(LPOLEUIINSERTOBJECTA psA)
+{
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)psA, sizeof(*psA), NULL);
+
+ // If the caller is using a private template, UStandardValidation will
+ // always return OLEUI_ERR_FINDTEMPLATEFAILURE here. This is because we
+ // haven't converted the template name to UNICODE yet, so the
+ // FindResource call in UStandardValidation won't find the caller's
+ // template. This is OK for two reasons: (1) it's the last thing that
+ // UStandardValidation checks so by this time it's basically done its
+ // job, and (2) UStandardValidation will be called again when we forward
+ // this call on to the Unicode version.
+ if (OLEUI_SUCCESS != uRet && OLEUI_ERR_FINDTEMPLATEFAILURE != uRet)
+ return uRet;
+
+ if (NULL != psA->lpszFile &&
+ (psA->cchFile <= 0 || psA->cchFile > MAX_PATH))
+ {
+ return(OLEUI_IOERR_CCHFILEINVALID);
+ }
+
+ // NULL is NOT valid for lpszFile
+ if (psA->lpszFile == NULL)
+ {
+ return(OLEUI_IOERR_LPSZFILEINVALID);
+ }
+
+ if (IsBadWritePtr(psA->lpszFile, psA->cchFile*sizeof(char)))
+ return(OLEUI_IOERR_LPSZFILEINVALID);
+
+ OLEUIINSERTOBJECTW sW;
+ WCHAR szCaption[MAX_PATH], szTemplate[MAX_PATH], szFile[MAX_PATH];
+
+ memcpy(&sW, psA, sizeof(OLEUIINSERTOBJECTW));
+ if (psA->lpszCaption)
+ {
+ ATOW(szCaption, psA->lpszCaption, MAX_PATH);
+ sW.lpszCaption = szCaption;
+ }
+ if (0 != HIWORD(psA->lpszTemplate))
+ {
+ ATOW(szTemplate, psA->lpszTemplate, MAX_PATH);
+ sW.lpszTemplate = szTemplate;
+ }
+ if (psA->lpszFile)
+ {
+ ATOW(szFile, psA->lpszFile, MAX_PATH);
+ sW.lpszFile = szFile;
+ }
+
+ uRet = OleUIInsertObjectW(&sW);
+
+ if (psA->lpszFile)
+ {
+ WTOA(psA->lpszFile, sW.lpszFile, psA->cchFile);
+ }
+ memcpy(&psA->clsid, &sW.clsid, sizeof(CLSID));
+ psA->dwFlags = sW.dwFlags;
+ psA->lpIStorage = sW.lpIStorage;
+ psA->ppvObj = sW.ppvObj;
+ psA->sc = sW.sc;
+ psA->hMetaPict = sW.hMetaPict;
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIPasteSpecialA
+//
+// Synopsis: convers call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpszCaption [in] on stack
+// lpszTemplate [in] on stack
+// arrPasteEntries [in] on heap
+// arrPasteEntries[n].lpstrFormatName [in] on heap
+// dwFlags [out]
+// nSelectedIndex [out]
+// fLink [out]
+// hMetaPict [out]
+// sizel [out]
+//
+//----------------------------------------------------------------------------
+
+
+STDAPI_(UINT) OleUIPasteSpecialA(LPOLEUIPASTESPECIALA psA)
+{
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)psA, sizeof(*psA), NULL);
+
+ // If the caller is using a private template, UStandardValidation will
+ // always return OLEUI_ERR_FINDTEMPLATEFAILURE here. This is because we
+ // haven't converted the template name to UNICODE yet, so the
+ // FindResource call in UStandardValidation won't find the caller's
+ // template. This is OK for two reasons: (1) it's the last thing that
+ // UStandardValidation checks so by this time it's basically done its
+ // job, and (2) UStandardValidation will be called again when we forward
+ // this call on to the Unicode version.
+ if (OLEUI_SUCCESS != uRet && OLEUI_ERR_FINDTEMPLATEFAILURE != uRet)
+ return uRet;
+
+ // Validate PasteSpecial specific fields
+ if (NULL == psA->arrPasteEntries || IsBadReadPtr(psA->arrPasteEntries, psA->cPasteEntries * sizeof(OLEUIPASTEENTRYA)))
+ return(OLEUI_IOERR_ARRPASTEENTRIESINVALID);
+
+ OLEUIPASTESPECIALW sW;
+ WCHAR szCaption[MAX_PATH], szTemplate[MAX_PATH];
+ uRet = OLEUI_ERR_LOCALMEMALLOC;
+ UINT uIndex;
+
+ memcpy(&sW, psA, sizeof(OLEUIPASTESPECIALW));
+
+ if (psA->lpszCaption)
+ {
+ ATOW(szCaption, psA->lpszCaption, MAX_PATH);
+ sW.lpszCaption = szCaption;
+ }
+ if (0 != HIWORD(psA->lpszTemplate))
+ {
+ ATOW(szTemplate, psA->lpszTemplate, MAX_PATH);
+ sW.lpszTemplate = szTemplate;
+ }
+ if (psA->cPasteEntries)
+ {
+ sW.arrPasteEntries = new OLEUIPASTEENTRYW[psA->cPasteEntries];
+ if (NULL == sW.arrPasteEntries)
+ {
+ return(uRet);
+ }
+ for (uIndex = psA->cPasteEntries; uIndex--;)
+ {
+ sW.arrPasteEntries[uIndex].lpstrFormatName = NULL;
+ sW.arrPasteEntries[uIndex].lpstrResultText = NULL;
+ }
+ for (uIndex = psA->cPasteEntries; uIndex--;)
+ {
+ sW.arrPasteEntries[uIndex].fmtetc = psA->arrPasteEntries[uIndex].fmtetc;
+ sW.arrPasteEntries[uIndex].dwFlags = psA->arrPasteEntries[uIndex].dwFlags;
+ sW.arrPasteEntries[uIndex].dwScratchSpace = psA->arrPasteEntries[uIndex].dwScratchSpace;
+ if (psA->arrPasteEntries[uIndex].lpstrFormatName)
+ {
+ UINT uLength = ATOWLEN(psA->arrPasteEntries[uIndex].lpstrFormatName);
+ sW.arrPasteEntries[uIndex].lpstrFormatName = new WCHAR[uLength];
+ if (NULL == sW.arrPasteEntries[uIndex].lpstrFormatName)
+ {
+ goto oom_error;
+ }
+ ATOW((WCHAR *)sW.arrPasteEntries[uIndex].lpstrFormatName,
+ psA->arrPasteEntries[uIndex].lpstrFormatName,
+ uLength);
+ }
+ if (psA->arrPasteEntries[uIndex].lpstrResultText)
+ {
+ UINT uLength = ATOWLEN(psA->arrPasteEntries[uIndex].lpstrResultText);
+ sW.arrPasteEntries[uIndex].lpstrResultText = new WCHAR[uLength];
+ if (NULL == sW.arrPasteEntries[uIndex].lpstrResultText)
+ {
+ goto oom_error;
+ }
+ ATOW((WCHAR *)sW.arrPasteEntries[uIndex].lpstrResultText,
+ psA->arrPasteEntries[uIndex].lpstrResultText,
+ uLength);
+ }
+ }
+ }
+
+ uRet = OleUIPasteSpecialW(&sW);
+ psA->lpSrcDataObj = sW.lpSrcDataObj;
+ psA->dwFlags = sW.dwFlags;
+ psA->nSelectedIndex = sW.nSelectedIndex;
+ psA->fLink = sW.fLink;
+ psA->hMetaPict = sW.hMetaPict;
+ psA->sizel = sW.sizel;
+
+oom_error:
+ for (uIndex = psA->cPasteEntries; uIndex--;)
+ {
+ if (sW.arrPasteEntries[uIndex].lpstrFormatName)
+ {
+ delete[] (WCHAR*)sW.arrPasteEntries[uIndex].lpstrFormatName;
+ }
+ if (sW.arrPasteEntries[uIndex].lpstrResultText)
+ {
+ delete[] (WCHAR *)sW.arrPasteEntries[uIndex].lpstrResultText;
+ }
+ }
+ delete[] sW.arrPasteEntries;
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Class: WrappedIOleUILinkContainer
+//
+// Purpose: Wraps IOleUILinkContainerA with IOleUILinkContainerW methods
+// so it can be passed on to Unicode methods within OLE2UI32.
+//
+// Interface: QueryInterface --
+// AddRef --
+// Release --
+// GetNextLink --
+// SetLinkUpdateOptions --
+// GetLinkUpdateOptions --
+// SetLinkSource -- requires string conversion
+// GetLinkSource -- requires string conversion
+// OpenLinkSource --
+// UpdateLink --
+// CancelLink --
+// WrappedIOleUILinkContainer -- constructor
+// ~WrappedIOleUILinkContainer -- destructor
+//
+// History: 11-04-94 stevebl Created
+//
+// Notes: This is a private interface wrapper. QueryInterface is not
+// supported and the wrapped interface may not be used outside
+// of the OLE2UI32 code.
+//
+//----------------------------------------------------------------------------
+
+class WrappedIOleUILinkContainer: public IOleUILinkContainerW
+{
+public:
+ // *** IUnknown methods *** //
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj);
+ STDMETHOD_(ULONG,AddRef) (THIS);
+ STDMETHOD_(ULONG,Release) (THIS);
+
+ // *** IOleUILinkContainer *** //
+ STDMETHOD_(DWORD,GetNextLink) (THIS_ DWORD dwLink);
+ STDMETHOD(SetLinkUpdateOptions) (THIS_ DWORD dwLink,
+ DWORD dwUpdateOpt);
+ STDMETHOD(GetLinkUpdateOptions) (THIS_ DWORD dwLink,
+ DWORD FAR* lpdwUpdateOpt);
+ STDMETHOD(SetLinkSource) (THIS_ DWORD dwLink, LPWSTR lpszDisplayName,
+ ULONG lenFileName, ULONG FAR* pchEaten, BOOL fValidateSource);
+ STDMETHOD(GetLinkSource) (THIS_ DWORD dwLink,
+ LPWSTR FAR* lplpszDisplayName, ULONG FAR* lplenFileName,
+ LPWSTR FAR* lplpszFullLinkType, LPWSTR FAR* lplpszShortLinkType,
+ BOOL FAR* lpfSourceAvailable, BOOL FAR* lpfIsSelected);
+ STDMETHOD(OpenLinkSource) (THIS_ DWORD dwLink);
+ STDMETHOD(UpdateLink) (THIS_ DWORD dwLink,
+ BOOL fErrorMessage, BOOL fErrorAction);
+ STDMETHOD(CancelLink) (THIS_ DWORD dwLink);
+
+ // *** Constructor and Destructor *** //
+ WrappedIOleUILinkContainer(IOleUILinkContainerA *pilc);
+ ~WrappedIOleUILinkContainer();
+private:
+ IOleUILinkContainerA * m_pilc;
+ ULONG m_uRefCount;
+};
+
+// *** IUnknown methods *** //
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::QueryInterface(THIS_ REFIID riid, LPVOID FAR* ppvObj)
+{
+ return(E_NOTIMPL);
+}
+
+ULONG STDMETHODCALLTYPE WrappedIOleUILinkContainer::AddRef()
+{
+ return(m_uRefCount++);
+}
+
+ULONG STDMETHODCALLTYPE WrappedIOleUILinkContainer::Release()
+{
+ ULONG uRet = --m_uRefCount;
+ if (0 == uRet)
+ {
+ delete(this);
+ }
+ return(uRet);
+}
+
+// *** IOleUILinkContainer *** //
+DWORD STDMETHODCALLTYPE WrappedIOleUILinkContainer::GetNextLink(DWORD dwLink)
+{
+ return(m_pilc->GetNextLink(dwLink));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::SetLinkUpdateOptions (DWORD dwLink,
+ DWORD dwUpdateOpt)
+{
+ return(m_pilc->SetLinkUpdateOptions(dwLink, dwUpdateOpt));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::GetLinkUpdateOptions (DWORD dwLink,
+ DWORD FAR* lpdwUpdateOpt)
+{
+ return(m_pilc->GetLinkUpdateOptions(dwLink, lpdwUpdateOpt));
+}
+
+//+---------------------------------------------------------------------------
+//
+// Member: WrappedIOleUILinkContainer::SetLinkSource
+//
+// Synopsis: forwards Unicode method call on to the ANSI version
+//
+// Arguments: [dwLink] -
+// [lpszDisplayName] - [in] converted on stack
+// [lenFileName] -
+// [pchEaten] -
+// [fValidateSource] -
+//
+// History: 11-04-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::SetLinkSource (DWORD dwLink, LPWSTR lpszDisplayName,
+ ULONG lenFileName, ULONG FAR* pchEaten, BOOL fValidateSource)
+{
+ char szDisplayName[MAX_PATH];
+ char * lpszDisplayNameA;
+ if (lpszDisplayName)
+ {
+ WTOA(szDisplayName, lpszDisplayName, MAX_PATH);
+ lpszDisplayNameA = szDisplayName;
+ }
+ else
+ lpszDisplayNameA = NULL;
+
+ return(m_pilc->SetLinkSource(dwLink, lpszDisplayNameA, lenFileName, pchEaten, fValidateSource));
+}
+
+//+---------------------------------------------------------------------------
+//
+// Member: WrappedIOleUILinkContainer::GetLinkSource
+//
+// Synopsis: forwards Unicode method call on to the ANSI version
+//
+// Arguments: [dwLink] -
+// [lplpszDisplayName] - [out] converted on heap
+// [lplenFileName] -
+// [lplpszFullLinkType] - [out] converted on heap
+// [lplpszShortLinkType] - [out] converted on heap
+// [lpfSourceAvailable] -
+// [lpfIsSelected] -
+//
+// History: 11-04-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::GetLinkSource (DWORD dwLink,
+ LPWSTR FAR* lplpszDisplayName, ULONG FAR* lplenFileName,
+ LPWSTR FAR* lplpszFullLinkType, LPWSTR FAR* lplpszShortLinkType,
+ BOOL FAR* lpfSourceAvailable, BOOL FAR* lpfIsSelected)
+{
+ LPSTR lpszDisplayName = NULL;
+ LPSTR lpszFullLinkType = NULL;
+ LPSTR lpszShortLinkType = NULL;
+ LPSTR * lplpszDisplayNameA = NULL;
+ LPSTR * lplpszFullLinkTypeA = NULL;
+ LPSTR * lplpszShortLinkTypeA = NULL;
+ if (lplpszDisplayName)
+ {
+ lplpszDisplayNameA = &lpszDisplayName;
+ }
+ if (lplpszFullLinkType)
+ {
+ lplpszFullLinkTypeA = &lpszFullLinkType;
+ }
+ if (lplpszShortLinkType)
+ {
+ lplpszShortLinkTypeA = &lpszShortLinkType;
+ }
+ HRESULT hrReturn = m_pilc->GetLinkSource(dwLink,
+ lplpszDisplayNameA,
+ lplenFileName,
+ lplpszFullLinkTypeA,
+ lplpszShortLinkTypeA,
+ lpfSourceAvailable,
+ lpfIsSelected);
+ if (lplpszDisplayName)
+ {
+ *lplpszDisplayName = NULL;
+ if (lpszDisplayName)
+ {
+ UINT uLen = ATOWLEN(lpszDisplayName);
+ *lplpszDisplayName = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszDisplayName)
+ {
+ ATOW(*lplpszDisplayName, lpszDisplayName, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszDisplayName);
+ }
+ }
+ if (lplpszFullLinkType)
+ {
+ *lplpszFullLinkType = NULL;
+ if (lpszFullLinkType)
+ {
+ UINT uLen = ATOWLEN(lpszFullLinkType);
+ *lplpszFullLinkType = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszFullLinkType)
+ {
+ ATOW(*lplpszFullLinkType, lpszFullLinkType, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszFullLinkType);
+ }
+ }
+ if (lplpszShortLinkType)
+ {
+ *lplpszShortLinkType = NULL;
+ if (lpszShortLinkType)
+ {
+ UINT uLen = ATOWLEN(lpszShortLinkType);
+ *lplpszShortLinkType = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszShortLinkType)
+ {
+ ATOW(*lplpszShortLinkType, lpszShortLinkType, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszShortLinkType);
+ }
+ }
+ return(hrReturn);
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::OpenLinkSource (DWORD dwLink)
+{
+ return(m_pilc->OpenLinkSource(dwLink));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::UpdateLink (DWORD dwLink,
+ BOOL fErrorMessage, BOOL fErrorAction)
+{
+ return(m_pilc->UpdateLink(dwLink, fErrorMessage, fErrorAction));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkContainer::CancelLink (DWORD dwLink)
+{
+ return(m_pilc->CancelLink(dwLink));
+}
+
+WrappedIOleUILinkContainer::WrappedIOleUILinkContainer(IOleUILinkContainerA *pilc)
+{
+ m_pilc = pilc;
+ m_pilc->AddRef();
+ m_uRefCount=1;
+}
+
+WrappedIOleUILinkContainer::~WrappedIOleUILinkContainer()
+{
+ m_pilc->Release();
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIEditLinksA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Notes: Uses the WrappedIOleUILinkContainer interface wrapper.
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpszCaption [in] on stack
+// lpszTemplate [in] on stack
+// dwFlags [out]
+// lpOleUILinkContainer [in] wrapped interface
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) OleUIEditLinksA(LPOLEUIEDITLINKSA psA)
+{
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)psA, sizeof(*psA), NULL);
+
+ // If the caller is using a private template, UStandardValidation will
+ // always return OLEUI_ERR_FINDTEMPLATEFAILURE here. This is because we
+ // haven't converted the template name to UNICODE yet, so the
+ // FindResource call in UStandardValidation won't find the caller's
+ // template. This is OK for two reasons: (1) it's the last thing that
+ // UStandardValidation checks so by this time it's basically done its
+ // job, and (2) UStandardValidation will be called again when we forward
+ // this call on to the Unicode version.
+ if (OLEUI_SUCCESS != uRet && OLEUI_ERR_FINDTEMPLATEFAILURE != uRet)
+ return uRet;
+
+ uRet = OLEUI_SUCCESS;
+
+ // Validate interface.
+ if (NULL == psA->lpOleUILinkContainer)
+ {
+ uRet = OLEUI_ELERR_LINKCNTRNULL;
+ }
+ else if(IsBadReadPtr(psA->lpOleUILinkContainer, sizeof(IOleUILinkContainerA)))
+ {
+ uRet = OLEUI_ELERR_LINKCNTRINVALID;
+ }
+
+ if (OLEUI_SUCCESS != uRet)
+ {
+ return(uRet);
+ }
+
+
+ OLEUIEDITLINKSW sW;
+ WCHAR szCaption[MAX_PATH], szTemplate[MAX_PATH];
+ uRet = OLEUI_ERR_LOCALMEMALLOC;
+
+ memcpy(&sW, psA, sizeof(OLEUIEDITLINKSW));
+ if (psA->lpszCaption)
+ {
+ ATOW(szCaption, psA->lpszCaption, MAX_PATH);
+ sW.lpszCaption = szCaption;
+ }
+ if (0 != HIWORD(psA->lpszTemplate))
+ {
+ ATOW(szTemplate, psA->lpszTemplate, MAX_PATH);
+ sW.lpszTemplate = szTemplate;
+ }
+
+ sW.lpOleUILinkContainer = new WrappedIOleUILinkContainer(psA->lpOleUILinkContainer);
+ if (NULL == sW.lpOleUILinkContainer)
+ {
+ return(uRet);
+ }
+
+ uRet = OleUIEditLinksW(&sW);
+
+ psA->dwFlags = sW.dwFlags;
+ sW.lpOleUILinkContainer->Release();
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIChangeIconA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpszCaption [in] on stack
+// lpszTemplate [in] on stack
+// szIconExe [in] array embedded in structure
+// dwFlags [out]
+// hMetaPict [out]
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) OleUIChangeIconA(LPOLEUICHANGEICONA psA)
+{
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)psA, sizeof(*psA), NULL);
+
+ // If the caller is using a private template, UStandardValidation will
+ // always return OLEUI_ERR_FINDTEMPLATEFAILURE here. This is because we
+ // haven't converted the template name to UNICODE yet, so the
+ // FindResource call in UStandardValidation won't find the caller's
+ // template. This is OK for two reasons: (1) it's the last thing that
+ // UStandardValidation checks so by this time it's basically done its
+ // job, and (2) UStandardValidation will be called again when we forward
+ // this call on to the Unicode version.
+ if (OLEUI_SUCCESS != uRet && OLEUI_ERR_FINDTEMPLATEFAILURE != uRet)
+ return uRet;
+
+ OLEUICHANGEICONW sW;
+ WCHAR szCaption[MAX_PATH], szTemplate[MAX_PATH];
+
+ memcpy(&sW, psA, sizeof(OLEUICHANGEICONA));
+
+ sW.cbStruct = sizeof(OLEUICHANGEICONW);
+
+ if (psA->lpszCaption)
+ {
+ ATOW(szCaption, psA->lpszCaption, MAX_PATH);
+ sW.lpszCaption = szCaption;
+ }
+ if (0 != HIWORD(psA->lpszTemplate))
+ {
+ ATOW(szTemplate, psA->lpszTemplate, MAX_PATH);
+ sW.lpszTemplate = szTemplate;
+ }
+ ATOW(sW.szIconExe, psA->szIconExe, MAX_PATH);
+ sW.cchIconExe = psA->cchIconExe;
+
+
+ uRet = OleUIChangeIconW(&sW);
+
+ psA->dwFlags = sW.dwFlags;
+ psA->hMetaPict = sW.hMetaPict;
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIConvertA
+//
+// Synopsis: converts a call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpszCaption [in] on stack
+// lpszTemplate [in] on stack
+// lpszUserType [in] on heap
+// [out] always freed and returned as NULL
+// lpszDefLabel [in] on heap
+// lpszDefLabel [out] always freed and returned as NULL
+// dwFlags [out]
+// clsidNew [out]
+// dvAspect [out]
+// hMetaPict [out]
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) OleUIConvertA(LPOLEUICONVERTA psA)
+{
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)psA, sizeof(*psA), NULL);
+
+ // If the caller is using a private template, UStandardValidation will
+ // always return OLEUI_ERR_FINDTEMPLATEFAILURE here. This is because we
+ // haven't converted the template name to UNICODE yet, so the
+ // FindResource call in UStandardValidation won't find the caller's
+ // template. This is OK for two reasons: (1) it's the last thing that
+ // UStandardValidation checks so by this time it's basically done its
+ // job, and (2) UStandardValidation will be called again when we forward
+ // this call on to the Unicode version.
+ if (OLEUI_SUCCESS != uRet && OLEUI_ERR_FINDTEMPLATEFAILURE != uRet)
+ return uRet;
+
+ if ((NULL != psA->lpszUserType)
+ && (IsBadReadPtr(psA->lpszUserType, 1)))
+ return(OLEUI_CTERR_STRINGINVALID);
+
+ if ( (NULL != psA->lpszDefLabel)
+ && (IsBadReadPtr(psA->lpszDefLabel, 1)) )
+ return(OLEUI_CTERR_STRINGINVALID);
+
+ OLEUICONVERTW sW;
+ WCHAR szCaption[MAX_PATH], szTemplate[MAX_PATH];
+ uRet = OLEUI_ERR_LOCALMEMALLOC;
+
+ memcpy(&sW, psA, sizeof(OLEUICONVERTW));
+ if (psA->lpszCaption)
+ {
+ ATOW(szCaption, psA->lpszCaption, MAX_PATH);
+ sW.lpszCaption = szCaption;
+ }
+ if (0 != HIWORD(psA->lpszTemplate))
+ {
+ ATOW(szTemplate, psA->lpszTemplate, MAX_PATH);
+ sW.lpszTemplate = szTemplate;
+ }
+ sW.lpszUserType = sW.lpszDefLabel = NULL;
+ if (psA->lpszUserType)
+ {
+ UINT uLen = ATOWLEN(psA->lpszUserType);
+ sW.lpszUserType = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (!sW.lpszUserType)
+ {
+ goto oom_error;
+ }
+ ATOW(sW.lpszUserType, psA->lpszUserType, uLen);
+ }
+ if (psA->lpszDefLabel)
+ {
+ UINT uLen = ATOWLEN(psA->lpszDefLabel);
+ sW.lpszDefLabel = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (!sW.lpszDefLabel)
+ {
+ goto oom_error;
+ }
+ ATOW(sW.lpszDefLabel, psA->lpszDefLabel, uLen);
+ }
+
+ uRet = OleUIConvertW(&sW);
+
+ psA->dwFlags = sW.dwFlags;
+ memcpy(&psA->clsidNew, &sW.clsidNew, sizeof(CLSID));
+ psA->dvAspect = sW.dvAspect;
+ psA->hMetaPict = sW.hMetaPict;
+ psA->fObjectsIconChanged = sW.fObjectsIconChanged;
+oom_error:
+ if (sW.lpszUserType)
+ {
+ OleStdFree((LPVOID)sW.lpszUserType);
+ }
+ if (sW.lpszDefLabel)
+ {
+ OleStdFree((LPVOID)sW.lpszDefLabel);
+ }
+ if (psA->lpszUserType)
+ {
+ OleStdFree((LPVOID)psA->lpszUserType);
+ psA->lpszUserType = NULL;
+ }
+ if (psA->lpszDefLabel)
+ {
+ OleStdFree((LPVOID)psA->lpszDefLabel);
+ psA->lpszDefLabel = NULL;
+ }
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIBusyA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpszCaption [in] on stack
+// lpszTemplate [in] on stack
+// dwFlags [out]
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) OleUIBusyA(LPOLEUIBUSYA psA)
+{
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)psA, sizeof(*psA), NULL);
+
+ // If the caller is using a private template, UStandardValidation will
+ // always return OLEUI_ERR_FINDTEMPLATEFAILURE here. This is because we
+ // haven't converted the template name to UNICODE yet, so the
+ // FindResource call in UStandardValidation won't find the caller's
+ // template. This is OK for two reasons: (1) it's the last thing that
+ // UStandardValidation checks so by this time it's basically done its
+ // job, and (2) UStandardValidation will be called again when we forward
+ // this call on to the Unicode version.
+ if (OLEUI_SUCCESS != uRet && OLEUI_ERR_FINDTEMPLATEFAILURE != uRet)
+ return uRet;
+
+ OLEUIBUSYW sW;
+ WCHAR szCaption[MAX_PATH], szTemplate[MAX_PATH];
+
+ memcpy(&sW, psA, sizeof(OLEUIBUSYW));
+ if (psA->lpszCaption)
+ {
+ ATOW(szCaption, psA->lpszCaption, MAX_PATH);
+ sW.lpszCaption = szCaption;
+ }
+ if (0 != HIWORD(psA->lpszTemplate))
+ {
+ ATOW(szTemplate, psA->lpszTemplate, MAX_PATH);
+ sW.lpszTemplate = szTemplate;
+ }
+ uRet = OleUIBusyW(&sW);
+
+ psA->dwFlags = sW.dwFlags;
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIUpdateLinksA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [lpOleUILinkCntr] - [in] wrapped with Unicode version
+// [hwndParent] -
+// [lpszTitle] - [in] on stack
+// [cLinks] -
+//
+// History: 11-04-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(BOOL) OleUIUpdateLinksA(LPOLEUILINKCONTAINERA lpOleUILinkCntr,
+ HWND hwndParent, LPSTR lpszTitle, int cLinks)
+{
+ WrappedIOleUILinkContainer * lpWrappedOleUILinkCntr = NULL;
+
+ if (NULL != lpszTitle && IsBadReadPtr(lpszTitle, 1))
+ return(FALSE);
+
+ if (NULL == lpOleUILinkCntr || IsBadReadPtr(lpOleUILinkCntr, sizeof(IOleUILinkContainerA)))
+ return(FALSE);
+
+ lpWrappedOleUILinkCntr = new WrappedIOleUILinkContainer(lpOleUILinkCntr);
+ if (NULL == lpWrappedOleUILinkCntr)
+ return(FALSE); // ran out of memory
+
+ WCHAR wszTitle[MAX_PATH];
+ WCHAR *lpwszTitle;
+ if (lpszTitle)
+ {
+ ATOW(wszTitle, lpszTitle, MAX_PATH);
+ lpwszTitle = wszTitle;
+ }
+ else
+ lpwszTitle = NULL;
+ BOOL fReturn = OleUIUpdateLinksW(lpWrappedOleUILinkCntr, hwndParent, lpwszTitle, cLinks);
+
+ lpWrappedOleUILinkCntr->Release();
+
+ return(fReturn);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Class: WrappedIOleUIObjInfo
+//
+// Purpose: Wraps IOleUIObjInfoA with IOleUIObjInfoW methods
+// so it can be passed on to Unicode methods within OLE2UI32.
+//
+// Interface: QueryInterface --
+// AddRef --
+// Release --
+// GetObjectInfo -- requires string conversion
+// GetConvertInfo --
+// ConvertObject --
+// GetViewInfo --
+// SetViewInfo --
+// WrappedIOleUIObjInfo -- constructor
+// ~WrappedIOleUIObjInfo -- destructor
+//
+// History: 11-08-94 stevebl Created
+//
+// Notes: This is a private interface wrapper. QueryInterface is not
+// supported and the wrapped interface may not be used outside
+// of the OLE2UI32 code.
+//
+//----------------------------------------------------------------------------
+
+class WrappedIOleUIObjInfo: public IOleUIObjInfoW
+{
+public:
+ // *** IUnknown methods *** //
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj);
+ STDMETHOD_(ULONG,AddRef) (THIS);
+ STDMETHOD_(ULONG,Release) (THIS);
+
+ // *** extra for General Properties *** //
+ STDMETHOD(GetObjectInfo) (THIS_ DWORD dwObject,
+ DWORD FAR* lpdwObjSize, LPWSTR FAR* lplpszLabel,
+ LPWSTR FAR* lplpszType, LPWSTR FAR* lplpszShortType,
+ LPWSTR FAR* lplpszLocation);
+ STDMETHOD(GetConvertInfo) (THIS_ DWORD dwObject,
+ CLSID FAR* lpClassID, WORD FAR* lpwFormat,
+ CLSID FAR* lpConvertDefaultClassID,
+ LPCLSID FAR* lplpClsidExclude, UINT FAR* lpcClsidExclude);
+ STDMETHOD(ConvertObject) (THIS_ DWORD dwObject, REFCLSID clsidNew);
+
+ // *** extra for View Properties *** //
+ STDMETHOD(GetViewInfo) (THIS_ DWORD dwObject,
+ HGLOBAL FAR* phMetaPict, DWORD* pdvAspect, int* pnCurrentScale);
+ STDMETHOD(SetViewInfo) (THIS_ DWORD dwObject,
+ HGLOBAL hMetaPict, DWORD dvAspect,
+ int nCurrentScale, BOOL bRelativeToOrig);
+ // *** Constructor and Destructor *** //
+ WrappedIOleUIObjInfo(IOleUIObjInfoA * pioi);
+ ~WrappedIOleUIObjInfo();
+private:
+ IOleUIObjInfoA * m_pioi;
+ ULONG m_uRefCount;
+};
+
+// *** IUnknown methods *** //
+HRESULT STDMETHODCALLTYPE WrappedIOleUIObjInfo::QueryInterface(THIS_ REFIID riid, LPVOID FAR* ppvObj)
+{
+ return(E_NOTIMPL);
+}
+
+ULONG STDMETHODCALLTYPE WrappedIOleUIObjInfo::AddRef()
+{
+ return(m_uRefCount++);
+}
+
+ULONG STDMETHODCALLTYPE WrappedIOleUIObjInfo::Release()
+{
+ ULONG uRet = --m_uRefCount;
+ if (0 == uRet)
+ {
+ delete(this);
+ }
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Member: WrappedIOleUIObjInfo::GetObjectInfo
+//
+// Synopsis: forwards Unicode method call on to the ANSI version
+//
+// Arguments: [dwObject] -
+// [lpdwObjSize] -
+// [lplpszLabel] - [out] converted on heap
+// [lplpszType] - [out] converted on heap
+// [lplpszShortType] - [out] converted on heap
+// [lplpszLocation] - [out] converted on heap
+//
+// History: 11-09-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUIObjInfo::GetObjectInfo(DWORD dwObject,
+ DWORD FAR* lpdwObjSize, LPWSTR FAR* lplpszLabel,
+ LPWSTR FAR* lplpszType, LPWSTR FAR* lplpszShortType,
+ LPWSTR FAR* lplpszLocation)
+{
+ LPSTR lpszLabel = NULL;
+ LPSTR lpszType = NULL;
+ LPSTR lpszShortType = NULL;
+ LPSTR lpszLocation = NULL;
+ LPSTR * lplpszLabelA = NULL;
+ LPSTR * lplpszTypeA = NULL;
+ LPSTR * lplpszShortTypeA = NULL;
+ LPSTR * lplpszLocationA = NULL;
+ if (lplpszLabel)
+ {
+ lplpszLabelA = &lpszLabel;
+ }
+ if (lplpszType)
+ {
+ lplpszTypeA = &lpszType;
+ }
+ if (lplpszShortType)
+ {
+ lplpszShortTypeA = &lpszShortType;
+ }
+ if (lplpszLocation)
+ {
+ lplpszLocationA = &lpszLocation;
+ }
+ HRESULT hrReturn = m_pioi->GetObjectInfo(dwObject,
+ lpdwObjSize,
+ lplpszLabelA,
+ lplpszTypeA,
+ lplpszShortTypeA,
+ lplpszLocationA);
+ if (lplpszLabel)
+ {
+ *lplpszLabel = NULL;
+ if (lpszLabel)
+ {
+ UINT uLen = ATOWLEN(lpszLabel);
+ *lplpszLabel = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszLabel)
+ {
+ ATOW(*lplpszLabel, lpszLabel, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszLabel);
+ }
+ }
+ if (lplpszType)
+ {
+ *lplpszType = NULL;
+ if (lpszType)
+ {
+ UINT uLen = ATOWLEN(lpszType);
+ *lplpszType = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszType)
+ {
+ ATOW(*lplpszType, lpszType, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszType);
+ }
+ }
+ if (lplpszShortType)
+ {
+ *lplpszShortType = NULL;
+ if (lpszShortType)
+ {
+ UINT uLen = ATOWLEN(lpszShortType);
+ *lplpszShortType = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszShortType)
+ {
+ ATOW(*lplpszShortType, lpszShortType, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszShortType);
+ }
+ }
+ if (lplpszLocation)
+ {
+ *lplpszLocation = NULL;
+ if (lpszLocation)
+ {
+ UINT uLen = ATOWLEN(lpszLocation);
+ *lplpszLocation = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszLocation)
+ {
+ ATOW(*lplpszLocation, lpszLocation, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszLocation);
+ }
+ }
+ return(hrReturn);
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUIObjInfo::GetConvertInfo(DWORD dwObject,
+ CLSID FAR* lpClassID, WORD FAR* lpwFormat,
+ CLSID FAR* lpConvertDefaultClassID,
+ LPCLSID FAR* lplpClsidExclude, UINT FAR* lpcClsidExclude)
+{
+ return(m_pioi->GetConvertInfo(dwObject,
+ lpClassID,
+ lpwFormat,
+ lpConvertDefaultClassID,
+ lplpClsidExclude,
+ lpcClsidExclude));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUIObjInfo::ConvertObject(DWORD dwObject, REFCLSID clsidNew)
+{
+ return(m_pioi->ConvertObject(dwObject, clsidNew));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUIObjInfo::GetViewInfo(DWORD dwObject,
+ HGLOBAL FAR* phMetaPict, DWORD* pdvAspect, int* pnCurrentScale)
+{
+ return(m_pioi->GetViewInfo(dwObject, phMetaPict, pdvAspect, pnCurrentScale));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUIObjInfo::SetViewInfo(DWORD dwObject,
+ HGLOBAL hMetaPict, DWORD dvAspect,
+ int nCurrentScale, BOOL bRelativeToOrig)
+{
+ return(m_pioi->SetViewInfo(dwObject, hMetaPict, dvAspect, nCurrentScale, bRelativeToOrig));
+}
+
+WrappedIOleUIObjInfo::WrappedIOleUIObjInfo(IOleUIObjInfoA *pioi)
+{
+ m_pioi = pioi;
+ m_pioi->AddRef();
+ m_uRefCount=1;
+}
+
+WrappedIOleUIObjInfo::~WrappedIOleUIObjInfo()
+{
+ m_pioi->Release();
+}
+
+
+//+---------------------------------------------------------------------------
+//
+// Class: WrappedIOleUILinkInfo
+//
+// Purpose: Wraps IOleUILinkInfoA with IOleUILinkInfoW methods
+// so it can be passed on to Unicode methods within OLE2UI32.
+//
+// Interface: QueryInterface --
+// AddRef --
+// Release --
+// GetNextLink --
+// SetLinkUpdateOptions --
+// GetLinkUpdateOptions --
+// SetLinkSource -- requires string conversion
+// GetLinkSource -- requires string conversion
+// OpenLinkSource --
+// UpdateLink --
+// CancelLink --
+// GetLastUpdate --
+// WrappedIOleUILinkInfo -- constructor
+// ~WrappedIOleUILinkInfo -- destructor
+//
+// History: 11-08-94 stevebl Created
+//
+// Notes: This is a private interface wrapper. QueryInterface is not
+// supported and the wrapped interface may not be used outside
+// of the OLE2UI32 code.
+//
+//----------------------------------------------------------------------------
+
+class WrappedIOleUILinkInfo: public IOleUILinkInfoW
+{
+public:
+ // *** IUnknown methods *** //
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj);
+ STDMETHOD_(ULONG,AddRef) (THIS);
+ STDMETHOD_(ULONG,Release) (THIS);
+
+ // *** IOleUILinkContainer *** //
+ STDMETHOD_(DWORD,GetNextLink) (THIS_ DWORD dwLink);
+ STDMETHOD(SetLinkUpdateOptions) (THIS_ DWORD dwLink,
+ DWORD dwUpdateOpt);
+ STDMETHOD(GetLinkUpdateOptions) (THIS_ DWORD dwLink,
+ DWORD FAR* lpdwUpdateOpt);
+ STDMETHOD(SetLinkSource) (THIS_ DWORD dwLink, LPWSTR lpszDisplayName,
+ ULONG lenFileName, ULONG FAR* pchEaten, BOOL fValidateSource);
+ STDMETHOD(GetLinkSource) (THIS_ DWORD dwLink,
+ LPWSTR FAR* lplpszDisplayName, ULONG FAR* lplenFileName,
+ LPWSTR FAR* lplpszFullLinkType, LPWSTR FAR* lplpszShortLinkType,
+ BOOL FAR* lpfSourceAvailable, BOOL FAR* lpfIsSelected);
+ STDMETHOD(OpenLinkSource) (THIS_ DWORD dwLink);
+ STDMETHOD(UpdateLink) (THIS_ DWORD dwLink,
+ BOOL fErrorMessage, BOOL fErrorAction);
+ STDMETHOD(CancelLink) (THIS_ DWORD dwLink);
+
+ // *** extra for Link Properties ***//
+ STDMETHOD(GetLastUpdate) (THIS_ DWORD dwLink,
+ FILETIME FAR* lpLastUpdate);
+
+ // *** Constructor and Destructor *** //
+ WrappedIOleUILinkInfo(IOleUILinkInfoA *pili);
+ ~WrappedIOleUILinkInfo();
+private:
+ IOleUILinkInfoA * m_pili;
+ ULONG m_uRefCount;
+};
+
+// *** IUnknown methods *** //
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::QueryInterface(THIS_ REFIID riid, LPVOID FAR* ppvObj)
+{
+ return(E_NOTIMPL);
+}
+
+ULONG STDMETHODCALLTYPE WrappedIOleUILinkInfo::AddRef()
+{
+ return(m_uRefCount++);
+}
+
+ULONG STDMETHODCALLTYPE WrappedIOleUILinkInfo::Release()
+{
+ ULONG uRet = --m_uRefCount;
+ if (0 == uRet)
+ {
+ delete(this);
+ }
+ return(uRet);
+}
+
+// *** IOleUILinkInfo *** //
+DWORD STDMETHODCALLTYPE WrappedIOleUILinkInfo::GetNextLink(DWORD dwLink)
+{
+ return(m_pili->GetNextLink(dwLink));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::SetLinkUpdateOptions (DWORD dwLink,
+ DWORD dwUpdateOpt)
+{
+ return(m_pili->SetLinkUpdateOptions(dwLink, dwUpdateOpt));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::GetLinkUpdateOptions (DWORD dwLink,
+ DWORD FAR* lpdwUpdateOpt)
+{
+ return(m_pili->GetLinkUpdateOptions(dwLink, lpdwUpdateOpt));
+}
+
+//+---------------------------------------------------------------------------
+//
+// Member: WrappedIOleUILinkInfo::SetLinkSource
+//
+// Synopsis: forwards Unicode method call on to the ANSI version
+//
+// Arguments: [dwLink] -
+// [lpszDisplayName] - [in] converted on stack
+// [lenFileName] -
+// [pchEaten] -
+// [fValidateSource] -
+//
+// History: 11-04-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::SetLinkSource (DWORD dwLink, LPWSTR lpszDisplayName,
+ ULONG lenFileName, ULONG FAR* pchEaten, BOOL fValidateSource)
+{
+ char szDisplayName[MAX_PATH];
+ char * lpszDisplayNameA;
+ if (lpszDisplayName)
+ {
+ WTOA(szDisplayName, lpszDisplayName, MAX_PATH);
+ lpszDisplayNameA = szDisplayName;
+ }
+ else
+ lpszDisplayNameA = NULL;
+
+ return(m_pili->SetLinkSource(dwLink, lpszDisplayNameA, lenFileName, pchEaten, fValidateSource));
+}
+
+//+---------------------------------------------------------------------------
+//
+// Member: WrappedIOleUILinkInfo::GetLinkSource
+//
+// Synopsis: forwards Unicode method call on to the ANSI version
+//
+// Arguments: [dwLink] -
+// [lplpszDisplayName] - [out] converted on heap
+// [lplenFileName] -
+// [lplpszFullLinkType] - [out] converted on heap
+// [lplpszShortLinkType] - [out] converted on heap
+// [lpfSourceAvailable] -
+// [lpfIsSelected] -
+//
+// History: 11-04-94 stevebl Created
+//
+//----------------------------------------------------------------------------
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::GetLinkSource (DWORD dwLink,
+ LPWSTR FAR* lplpszDisplayName, ULONG FAR* lplenFileName,
+ LPWSTR FAR* lplpszFullLinkType, LPWSTR FAR* lplpszShortLinkType,
+ BOOL FAR* lpfSourceAvailable, BOOL FAR* lpfIsSelected)
+{
+ LPSTR lpszDisplayName = NULL;
+ LPSTR lpszFullLinkType = NULL;
+ LPSTR lpszShortLinkType = NULL;
+ LPSTR * lplpszDisplayNameA = NULL;
+ LPSTR * lplpszFullLinkTypeA = NULL;
+ LPSTR * lplpszShortLinkTypeA = NULL;
+ if (lplpszDisplayName)
+ {
+ lplpszDisplayNameA = &lpszDisplayName;
+ }
+ if (lplpszFullLinkType)
+ {
+ lplpszFullLinkTypeA = &lpszFullLinkType;
+ }
+ if (lplpszShortLinkType)
+ {
+ lplpszShortLinkTypeA = &lpszShortLinkType;
+ }
+ HRESULT hrReturn = m_pili->GetLinkSource(dwLink,
+ lplpszDisplayNameA,
+ lplenFileName,
+ lplpszFullLinkTypeA,
+ lplpszShortLinkTypeA,
+ lpfSourceAvailable,
+ lpfIsSelected);
+ if (lplpszDisplayName)
+ {
+ *lplpszDisplayName = NULL;
+ if (lpszDisplayName)
+ {
+ UINT uLen = ATOWLEN(lpszDisplayName);
+ *lplpszDisplayName = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszDisplayName)
+ {
+ ATOW(*lplpszDisplayName, lpszDisplayName, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszDisplayName);
+ }
+ }
+ if (lplpszFullLinkType)
+ {
+ *lplpszFullLinkType = NULL;
+ if (lpszFullLinkType)
+ {
+ UINT uLen = ATOWLEN(lpszFullLinkType);
+ *lplpszFullLinkType = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszFullLinkType)
+ {
+ ATOW(*lplpszFullLinkType, lpszFullLinkType, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszFullLinkType);
+ }
+ }
+ if (lplpszShortLinkType)
+ {
+ *lplpszShortLinkType = NULL;
+ if (lpszShortLinkType)
+ {
+ UINT uLen = ATOWLEN(lpszShortLinkType);
+ *lplpszShortLinkType = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (*lplpszShortLinkType)
+ {
+ ATOW(*lplpszShortLinkType, lpszShortLinkType, uLen);
+ }
+ else
+ hrReturn = E_OUTOFMEMORY;
+ OleStdFree((LPVOID)lpszShortLinkType);
+ }
+ }
+ return(hrReturn);
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::OpenLinkSource (DWORD dwLink)
+{
+ return(m_pili->OpenLinkSource(dwLink));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::UpdateLink (DWORD dwLink,
+ BOOL fErrorMessage, BOOL fErrorAction)
+{
+ return(m_pili->UpdateLink(dwLink, fErrorMessage, fErrorAction));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::CancelLink (DWORD dwLink)
+{
+ return(m_pili->CancelLink(dwLink));
+}
+
+HRESULT STDMETHODCALLTYPE WrappedIOleUILinkInfo::GetLastUpdate (DWORD dwLink,
+ FILETIME FAR* lpLastUpdate)
+{
+ return(m_pili->GetLastUpdate(dwLink, lpLastUpdate));
+}
+
+WrappedIOleUILinkInfo::WrappedIOleUILinkInfo(IOleUILinkInfoA *pili)
+{
+ m_pili = pili;
+ m_pili->AddRef();
+ m_uRefCount=1;
+}
+
+WrappedIOleUILinkInfo::~WrappedIOleUILinkInfo()
+{
+ m_pili->Release();
+}
+
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIObjectPropertiesA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpPS [in]
+// lpObjInfo [in] wrapped with Unicode interface
+// lpLinkInfo [in] wrapped with Unicode interface
+// lpGP [in] (no data conversion, only type conversion)
+// lpVP [in] (no data conversion, only type conversion)
+// lpLP [in] (no data conversion, only type conversion)
+//
+// dwFlags [out]
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) OleUIObjectPropertiesA(LPOLEUIOBJECTPROPSA psA)
+{
+ if (NULL == psA)
+ {
+ return(OLEUI_ERR_STRUCTURENULL);
+ }
+
+ if (IsBadWritePtr(psA, sizeof(OLEUIOBJECTPROPSA)))
+ return OLEUI_ERR_STRUCTUREINVALID;
+
+ LPOLEUIOBJECTPROPSW psW;
+ UINT uRet = OLEUI_ERR_LOCALMEMALLOC;
+
+ if (NULL == psA->lpObjInfo)
+ {
+ return(OLEUI_OPERR_OBJINFOINVALID);
+ }
+
+ if (IsBadReadPtr(psA->lpObjInfo, sizeof(IOleUIObjInfoA)))
+ {
+ return(OLEUI_OPERR_OBJINFOINVALID);
+ }
+
+ if (psA->dwFlags & OPF_OBJECTISLINK)
+ {
+ if (NULL == psA->lpLinkInfo)
+ {
+ return(OLEUI_OPERR_LINKINFOINVALID);
+ }
+
+ if (IsBadReadPtr(psA->lpLinkInfo, sizeof(IOleUILinkInfoA)))
+ {
+ return(OLEUI_OPERR_LINKINFOINVALID);
+ }
+ }
+
+ BOOL fWrappedIOleUILinkInfo = FALSE;
+ psW = (LPOLEUIOBJECTPROPSW) OleStdMalloc(sizeof(OLEUIOBJECTPROPSW));
+ if (NULL != psW)
+ {
+ memcpy(psW, psA, sizeof(OLEUIOBJECTPROPSW));
+ psW->lpObjInfo = new WrappedIOleUIObjInfo(psA->lpObjInfo);
+ if (NULL == psW->lpObjInfo)
+ {
+ OleStdFree(psW);
+ return(uRet);
+ }
+ if (psW->dwFlags & OPF_OBJECTISLINK)
+ {
+ psW->lpLinkInfo = new WrappedIOleUILinkInfo(psA->lpLinkInfo);
+ if (NULL == psW->lpLinkInfo)
+ {
+ psW->lpObjInfo->Release();
+ OleStdFree(psW);
+ return(uRet);
+ }
+ fWrappedIOleUILinkInfo = TRUE;
+ }
+ uRet = InternalObjectProperties(psW, FALSE);
+ psA->dwFlags = psW->dwFlags;
+ psW->lpObjInfo->Release();
+ if (fWrappedIOleUILinkInfo)
+ {
+ psW->lpLinkInfo->Release();
+ }
+ OleStdFree(psW);
+ }
+ return(uRet);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIChangeSourceA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [psA] - ANSI structure
+//
+// History: 11-04-94 stevebl Created
+//
+// Structure members converted or passed back out (everything is passed in):
+// lpszCaption [in] on stack
+// lpszTemplate [in] on stack
+// lpszDisplayName [in, out] on heap
+// lpszFrom [out] on heap
+// lpszTo [out] on heap
+// lpOleUILinkContainer [in] wrapped interface
+// dwFlags [out]
+// nFileLength [out]
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) OleUIChangeSourceA(LPOLEUICHANGESOURCEA psA)
+{
+ UINT uRet = UStandardValidation((LPOLEUISTANDARD)psA, sizeof(*psA), NULL);
+
+ // If the caller is using a private template, UStandardValidation will
+ // always return OLEUI_ERR_FINDTEMPLATEFAILURE here. This is because we
+ // haven't converted the template name to UNICODE yet, so the
+ // FindResource call in UStandardValidation won't find the caller's
+ // template. This is OK for two reasons: (1) it's the last thing that
+ // UStandardValidation checks so by this time it's basically done its
+ // job, and (2) UStandardValidation will be called again when we forward
+ // this call on to the Unicode version.
+ if (OLEUI_SUCCESS != uRet && OLEUI_ERR_FINDTEMPLATEFAILURE != uRet)
+ return uRet;
+
+ // lpszFrom and lpszTo must be NULL (they are out only)
+ if (psA->lpszFrom != NULL)
+ {
+ return(OLEUI_CSERR_FROMNOTNULL);
+ }
+ if (psA->lpszTo != NULL)
+ {
+ return(OLEUI_CSERR_TONOTNULL);
+ }
+
+ // lpszDisplayName must be valid or NULL
+ if (psA->lpszDisplayName != NULL &&
+ IsBadReadPtr(psA->lpszDisplayName, 1))
+ {
+ return(OLEUI_CSERR_SOURCEINVALID);
+ }
+
+ OLEUICHANGESOURCEW sW;
+ WCHAR szCaption[MAX_PATH], szTemplate[MAX_PATH];
+ uRet = OLEUI_ERR_LOCALMEMALLOC;
+
+ memcpy(&sW, psA, sizeof(OLEUICHANGESOURCEW));
+ if (psA->lpszCaption != NULL)
+ {
+ ATOW(szCaption, psA->lpszCaption, MAX_PATH);
+ sW.lpszCaption = szCaption;
+ }
+ if (0 != HIWORD(psA->lpszTemplate))
+ {
+ ATOW(szTemplate, psA->lpszTemplate, MAX_PATH);
+ sW.lpszTemplate = szTemplate;
+ }
+ if (psA->lpszDisplayName)
+ {
+ UINT uLen = ATOWLEN(psA->lpszDisplayName);
+ sW.lpszDisplayName = (LPWSTR)OleStdMalloc(uLen * sizeof(WCHAR));
+ if (!sW.lpszDisplayName)
+ {
+ return(uRet);
+ }
+ ATOW(sW.lpszDisplayName, psA->lpszDisplayName, uLen);
+ }
+ if (NULL != psA->lpOleUILinkContainer)
+ {
+ if (IsBadReadPtr(psA->lpOleUILinkContainer, sizeof(IOleUILinkContainerA)))
+ {
+ return(OLEUI_CSERR_LINKCNTRINVALID);
+ }
+ sW.lpOleUILinkContainer = new WrappedIOleUILinkContainer(psA->lpOleUILinkContainer);
+ if (NULL == sW.lpOleUILinkContainer)
+ {
+ return(uRet);
+ }
+ }
+
+ uRet = OleUIChangeSourceW(&sW);
+ if (psA->lpszDisplayName)
+ {
+ OleStdFree((LPVOID)psA->lpszDisplayName);
+ psA->lpszDisplayName = NULL;
+ }
+ if (sW.lpszDisplayName)
+ {
+ UINT uLen = WTOALEN(sW.lpszDisplayName);
+ psA->lpszDisplayName = (LPSTR)OleStdMalloc(uLen * sizeof(char));
+ if (!psA->lpszDisplayName)
+ {
+ uRet = OLEUI_ERR_LOCALMEMALLOC;
+ }
+ else
+ {
+ WTOA(psA->lpszDisplayName, sW.lpszDisplayName, uLen);
+ }
+ OleStdFree((LPVOID)sW.lpszDisplayName);
+ }
+ if (sW.lpszFrom)
+ {
+ UINT uLen = WTOALEN(sW.lpszFrom);
+ psA->lpszFrom = (LPSTR)OleStdMalloc(uLen * sizeof(char));
+ if (!psA->lpszFrom)
+ {
+ uRet = OLEUI_ERR_LOCALMEMALLOC;
+ }
+ else
+ {
+ WTOA(psA->lpszFrom, sW.lpszFrom, uLen);
+ }
+ OleStdFree((LPVOID)sW.lpszFrom);
+ }
+ if (sW.lpszTo)
+ {
+ UINT uLen = WTOALEN(sW.lpszTo);
+ psA->lpszTo = (LPSTR)OleStdMalloc(uLen * sizeof(char));
+ if (!psA->lpszTo)
+ {
+ uRet = OLEUI_ERR_LOCALMEMALLOC;
+ }
+ else
+ {
+ WTOA(psA->lpszTo, sW.lpszTo, uLen);
+ }
+ OleStdFree((LPVOID)sW.lpszTo);
+ }
+ psA->dwFlags = sW.dwFlags;
+ psA->nFileLength = sW.nFileLength;
+ if (NULL != sW.lpOleUILinkContainer)
+ {
+ sW.lpOleUILinkContainer->Release();
+ }
+ return(uRet);
+}
+
+int OleUIPromptUserInternal(int nTemplate, HWND hwndParent, LPTSTR szTitle, va_list arglist);
+
+//+---------------------------------------------------------------------------
+//
+// Function: OleUIPromptUserA
+//
+// Synopsis: converts call to ANSI version into call to Unicode version
+//
+// Arguments: [nTemplate] - template ID
+// [hwndParent] - parent's HWND
+// [lpszTitle] - title of the window
+// [...] - variable argument list
+//
+// History: 11-30-94 stevebl Created
+//
+// Notes: The first parameter passed in by this function is always the
+// title for the dialog. It must be converted to Unicode before
+// forwarding the call. The other parameters do not need to
+// be converted because the template ID will indicate the dialog
+// that contains the correct wsprintf formatting string for
+// converting the other ANSI parameters to Unicode when the
+// function calls wsprintf to build it's text.
+//
+//----------------------------------------------------------------------------
+
+int FAR CDECL OleUIPromptUserA(int nTemplate, HWND hwndParent, ...)
+{
+ WCHAR wszTemp[MAX_PATH];
+ WCHAR * wszTitle = NULL;
+ va_list arglist;
+ va_start(arglist, hwndParent);
+ LPSTR szTitle = va_arg(arglist, LPSTR);
+ if (szTitle != NULL)
+ {
+ ATOW(wszTemp, szTitle, MAX_PATH);
+ wszTitle = wszTemp;
+ }
+ int nRet = OleUIPromptUserInternal(nTemplate, hwndParent, wszTitle, arglist);
+ va_end(arglist);
+
+ return(nRet);
+}
+
+#else // UNICODE not defined
+// Stubbed out Wide entry points
+
+STDAPI_(BOOL) OleUIAddVerbMenuW(LPOLEOBJECT lpOleObj, LPCWSTR lpszShortType,
+ HMENU hMenu, UINT uPos, UINT uIDVerbMin, UINT uIDVerbMax,
+ BOOL bAddConvert, UINT idConvert, HMENU FAR *lphMenu)
+{
+ // BUGBUG - there is really no way to specify an error return code
+ return(FALSE);
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: ReturnError
+//
+// Synopsis: Used to stub out the following entry points:
+// OleUIInsertObjectW
+// OleUIPasteSpecialW
+// OleUIEditLinksW
+// OleUIChangeIconW
+// OleUIConvertW
+// OleUIBusyW
+// OleUIObjectPropertiesW
+// OleUIChangeSourceW
+//
+// Returns: OLEUI_ERR_DIALOGFAILURE
+//
+// History: 12-29-94 stevebl Created
+//
+// Notes: The entry points listed above are all mapped to this function
+// in the Chicago version of OLEDLG.DEF.
+//
+//----------------------------------------------------------------------------
+
+STDAPI_(UINT) ReturnError(void * p)
+{
+ return(OLEUI_ERR_DIALOGFAILURE);
+}
+
+STDAPI_(BOOL) OleUIUpdateLinksW(LPOLEUILINKCONTAINERW lpOleUILinkCntr,
+ HWND hwndParent, LPWSTR lpszTitle, int cLinks)
+{
+ return(FALSE);
+}
+
+int FAR CDECL OleUIPromptUserW(int nTemplate, HWND hwndParent, LPWSTR lpszTitle, ...)
+{
+ return(2); // same as if user had cancelled the dialog
+}
+#endif // UNICODE