diff options
Diffstat (limited to 'private/oleutest/letest/ole2ui')
90 files changed, 31959 insertions, 0 deletions
diff --git a/private/oleutest/letest/ole2ui/bang.ico b/private/oleutest/letest/ole2ui/bang.ico Binary files differnew file mode 100644 index 000000000..90fe0f220 --- /dev/null +++ b/private/oleutest/letest/ole2ui/bang.ico diff --git a/private/oleutest/letest/ole2ui/busy.c b/private/oleutest/letest/ole2ui/busy.c new file mode 100644 index 000000000..7be5c7414 --- /dev/null +++ b/private/oleutest/letest/ole2ui/busy.c @@ -0,0 +1,551 @@ +/* + * BUSY.C + * + * Implements the OleUIBusy function which invokes the "Server Busy" + * dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "common.h" +#include "utility.h" +#include "busy.h" +#include <ctype.h> // for tolower() and toupper() + +#ifndef WIN32 +#include <toolhelp.h> +#endif + + +/* + * 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) + { + UINT uRet = 0; + HGLOBAL hMemDlg=NULL; + +#if !defined( WIN32 ) +// BUGBUG32: this is not yet ported to NT + + uRet=UStandardValidation((LPOLEUISTANDARD)lpOBZ, sizeof(OLEUIBUSY) + , &hMemDlg); + + // Error out if the standard validation failed + if (OLEUI_SUCCESS!=uRet) + return uRet; + + // Validate HTASK + if (!IsTask(lpOBZ->hTask)) + uRet = OLEUI_BZERR_HTASKINVALID; + + // Error out if our secondary validation failed + if (OLEUI_ERR_STANDARDMIN <= uRet) + { + if (NULL!=hMemDlg) + FreeResource(hMemDlg); + + return uRet; + } + + // Invoke the dialog. + uRet=UStandardInvocation(BusyDialogProc, (LPOLEUISTANDARD)lpOBZ, + hMemDlg, MAKEINTRESOURCE(IDD_BUSY)); +#endif + + return uRet; +} + + +/* + * BusyDialogProc + * + * Purpose: + * Implements the OLE Busy dialog as invoked through the OleUIBusy function. + * + * Parameters: + * Standard + * + * Return Value: + * Standard + * + */ + +BOOL CALLBACK EXPORT BusyDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) + { + LPBUSY lpBZ; + UINT uRet = 0; + + //Declare Win16/Win32 compatible WM_COMMAND parameters. + COMMANDPARAMS(wID, wCode, hWndMsg); + + //This will fail under WM_INITDIALOG, where we allocate it. + 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) + { + BusyCleanup(hDlg); + StandardCleanup(lpBZ, hDlg); + 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_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 IDBZ_SWITCHTO: + { + BOOL fNotRespondingDlg = + (BOOL)(lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG); + + // If user selects "Switch To...", switch activation + // directly to the window which is causing the problem. + if (IsWindow(lpBZ->hWndBlocked)) + MakeWindowActive(lpBZ->hWndBlocked); + else + StartTaskManager(); // Fail safe: Start Task Manager + + // 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) + SendMessage(hDlg, uMsgEndDialog, OLEUI_BZ_SWITCHTOSELECTED, 0L); + break; + } + case IDBZ_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) + { + LPBUSY lpBZ; + LPOLEUIBUSY lpOBZ; + HFONT hFont; + LPTSTR lpTaskName; + LPTSTR lpWindowName; + HICON hIcon; + + lpBZ=(LPBUSY)LpvStandardInit(hDlg, sizeof(OLEUIBUSY), TRUE, &hFont); + + // PvStandardInit sent a termination to us already. + if (NULL==lpBZ) + return FALSE; + + // Our original structure is in lParam + lpOBZ = (LPOLEUIBUSY)lParam; + + // Copy it to our instance of the structure (in lpBZ) + lpBZ->lpOBZ=lpOBZ; + + //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((VOID FAR *)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 + + if (GetTaskInfo(hDlg, lpOBZ->hTask, &lpTaskName, &lpWindowName, &lpBZ->hWndBlocked)) + { + // Build string to present to user, place in IDBZ_MESSAGE1 control + BuildBusyDialogString(hDlg, lpBZ->dwFlags, IDBZ_MESSAGE1, lpTaskName, lpWindowName); + OleStdFree(lpTaskName); + OleStdFree(lpWindowName); + } + + // Update icon with the system "exclamation" icon + hIcon = LoadIcon(NULL, IDI_EXCLAMATION); + SendDlgItemMessage(hDlg, IDBZ_ICON, STM_SETICON, (WPARAM)hIcon, 0L); + + // Disable/Enable controls + if ((lpBZ->dwFlags & BZ_DISABLECANCELBUTTON) || + (lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG)) // Disable cancel for "not responding" dialog + EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE); + + if (lpBZ->dwFlags & BZ_DISABLESWITCHTOBUTTON) + EnableWindow(GetDlgItem(hDlg, IDBZ_SWITCHTO), FALSE); + + if (lpBZ->dwFlags & BZ_DISABLERETRYBUTTON) + EnableWindow(GetDlgItem(hDlg, IDBZ_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) + && lpBZ->lpOBZ->lpszCaption[0] != '\0') + 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 lpTaskName, LPTSTR lpWindowName) +{ + LPTSTR pszT, psz1, psz2, psz3; + UINT cch; + LPTSTR pszDot, pszSlash; + UINT uiStringNum; + + /* + * We need scratch memory for loading the stringtable string, + * the task name, 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. + */ + cch=512; + + // Use OLE-supplied allocation + if ((pszT = OleStdMalloc((ULONG)(3*cch))) == NULL) + return; + + psz1=pszT; + psz2=psz1+cch; + psz3=psz2+cch; + + // Parse base name out of path name, use psz2 for the task + // name to display + // In Win32, _fstrcpy is mapped to handle UNICODE stuff + _fstrcpy(psz2, lpTaskName); + pszDot = _fstrrchr(psz2, TEXT('.')); + pszSlash = _fstrrchr(psz2, TEXT('\\')); // Find last backslash in path + + if (pszDot != NULL) +#ifdef UNICODE + *pszDot = TEXT('\0'); // Null terminate at the DOT +#else + *pszDot = '\0'; // Null terminate at the DOT +#endif + + if (pszSlash != NULL) + psz2 = pszSlash + 1; // Nuke everything up to this point + +#ifdef LOWERCASE_NAME + // Compile this with /DLOWERCASE_NAME if you want the lower-case + // module name to be displayed in the dialog rather than the + // all-caps name. + { + int i,l; + + // Now, lowercase all letters except first one + l = _fstrlen(psz2); + for(i=0;i<l;i++) + psz2[i] = tolower(psz2[i]); + + psz2[0] = toupper(psz2[0]); + } +#endif + + // Check size of lpWindowName. We can reasonably fit about 80 + // characters into the text control, so truncate more than 80 chars + if (_fstrlen(lpWindowName)> 80) +#ifdef UNICODE + lpWindowName[80] = TEXT('\0'); +#else + lpWindowName[80] = '\0'; +#endif + + // Load the format string out of stringtable, choose a different + // string depending on what flags are passed in to the dialog + if (dwFlags & BZ_NOTRESPONDINGDIALOG) + uiStringNum = IDS_BZRESULTTEXTNOTRESPONDING; + else + uiStringNum = IDS_BZRESULTTEXTBUSY; + + if (LoadString(ghInst, uiStringNum, psz1, cch) == 0) + return; + + // Build the string. The format string looks like this: + // "This action cannot be completed because the '%s' application + // (%s) is [busy | not responding]. Choose \"Switch To\" to activate '%s' and + // correct the problem." + + wsprintf(psz3, psz1, (LPSTR)psz2, (LPTSTR)lpWindowName, (LPTSTR)psz2); + SetDlgItemText(hDlg, iControl, (LPTSTR)psz3); + OleStdFree(pszT); + + return; +} + + + +/* + * BusyCleanup + * + * Purpose: + * Performs busy-specific cleanup before termination. + * + * Parameters: + * hDlg HWND of the dialog box so we can access controls. + * + * Return Value: + * None + */ +void BusyCleanup(HWND hDlg) +{ + return; +} + + + +/* + * 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 FAR* lplpszTaskName, LPTSTR FAR*lplpszWindowName, HWND FAR*lphWnd) +{ + BOOL fRet = FALSE; +#if !defined( WIN32 ) + TASKENTRY te; +#endif + HWND hwndNext; + LPTSTR lpszTN = NULL; + LPTSTR lpszWN = NULL; + HWND hwndFind = NULL; + + // Clear out return values in case of error + *lplpszTaskName = NULL; + *lplpszWindowName = NULL; + +#if !defined( WIN32 ) + te.dwSize = sizeof(TASKENTRY); + if (TaskFindHandle(&te, htask)) +#endif + { + // Now, enumerate top-level windows in system + 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. + // + // REVIEW: Will this filter hold true for InProcServer DLL-created + // windows? + // + if ((hwndNext != hWnd) && +#if !defined( WIN32 ) + (GetWindowWord(hwndNext, GWW_HINSTANCE) == (WORD)te.hInst) && +#else + ((HTASK) GetWindowThreadProcessId(hwndNext,NULL) == htask) && +#endif + (IsWindowVisible(hwndNext)) && + !GetWindow(hwndNext, GW_OWNER)) + { + // We found our window! Alloc space for new strings + if ((lpszTN = OleStdMalloc(OLEUI_CCHPATHMAX_SIZE)) == NULL) + return TRUE; // continue task window enumeration + + if ((lpszWN = OleStdMalloc(OLEUI_CCHPATHMAX_SIZE)) == NULL) + return TRUE; // continue task window enumeration + + // We found the window we were looking for, copy info to + // local vars + GetWindowText(hwndNext, lpszWN, OLEUI_CCHPATHMAX); +#if !defined( WIN32 ) + LSTRCPYN(lpszTN, te.szModule, OLEUI_CCHPATHMAX); +#else + /* WIN32 NOTE: we are not able to get a module name + ** given a thread process id on WIN32. the best we + ** can do is use the window title as the module/app + ** name. + */ + LSTRCPYN(lpszTN, lpszWN, OLEUI_CCHPATHMAX); +#endif + hwndFind = hwndNext; + + fRet = TRUE; + goto OKDone; + } + + hwndNext = GetWindow(hwndNext, GW_HWNDNEXT); + } + } + +OKDone: + + // OK, everything was successful. Set string pointers to point to + // our data. + + *lplpszTaskName = lpszTN; + *lplpszWindowName = lpszWN; + *lphWnd = hwndFind; + + return fRet; +} + + +/* + * StartTaskManager() + * + * Purpose: Starts Task Manager. Used to bring up task manager to + * assist in switching to a given blocked task. + * + */ + +StartTaskManager() +{ + WinExec("taskman.exe", SW_SHOW); + return TRUE; +} + + + +/* + * MakeWindowActive() + * + * Purpose: Makes specified window the active window. + * + */ + +void MakeWindowActive(HWND hWndSwitchTo) +{ + // Move the new window to the top of the Z-order + SetWindowPos(hWndSwitchTo, HWND_TOP, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE); + + // If it's iconic, we need to restore it. + if (IsIconic(hWndSwitchTo)) + ShowWindow(hWndSwitchTo, SW_RESTORE); +} diff --git a/private/oleutest/letest/ole2ui/busy.dlg b/private/oleutest/letest/ole2ui/busy.dlg new file mode 100644 index 000000000..c2151956c --- /dev/null +++ b/private/oleutest/letest/ole2ui/busy.dlg @@ -0,0 +1,13 @@ +IDD_BUSY DIALOG DISCARDABLE 0, 0, 214, 76 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Server Busy" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "&Switch To...", IDBZ_SWITCHTO, 33, 55, 53, 15 + PUSHBUTTON "&Cancel", IDCANCEL, 152, 55, 53, 15 + PUSHBUTTON "&Retry", IDBZ_RETRY, 92, 55, 53, 15 + LTEXT "This action cannot be completed because the other application is busy. Choose 'Switch To' to activate the busy application and correct the problem.", IDBZ_MESSAGE1, 35, 11, 167, 35 + ICON "", IDBZ_ICON, 8, 18, 18, 20 +END + + diff --git a/private/oleutest/letest/ole2ui/busy.h b/private/oleutest/letest/ole2ui/busy.h new file mode 100644 index 000000000..3656aecf6 --- /dev/null +++ b/private/oleutest/letest/ole2ui/busy.h @@ -0,0 +1,45 @@ +/* + * BUSY.H + * + * Internal definitions, structures, and function prototypes for the + * OLE 2.0 UI Busy dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#ifndef _BUSY_H_ +#define _BUSY_H_ + +//Internally used structure +typedef struct tagBUSY + { + //Keep this item first as the Standard* functions depend on it here. + LPOLEUIBUSY lpOBZ; //Original structure passed. + + /* + * 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 +BOOL GetTaskInfo(HWND hWnd, HTASK htask, LPTSTR FAR* lplpszTaskName, LPTSTR FAR*lplpszWindowName, HWND FAR*lphWnd); +void BuildBusyDialogString(HWND, DWORD, int, LPTSTR, LPTSTR); +BOOL CALLBACK EXPORT BusyDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); +void BusyCleanup(HWND hDlg); +BOOL FBusyInit(HWND hDlg, WPARAM wParam, LPARAM lParam); +BOOL InitEnumeration(void); +void UnInitEnumeration(void); + StartTaskManager(void); +void MakeWindowActive(HWND hWndSwitchTo); + +#endif //_BUSY_H_ + + + + diff --git a/private/oleutest/letest/ole2ui/common.c b/private/oleutest/letest/ole2ui/common.c new file mode 100644 index 000000000..40f450c72 --- /dev/null +++ b/private/oleutest/letest/ole2ui/common.c @@ -0,0 +1,423 @@ +/* + * COMMON.C + * + * Standardized (and centralized) pieces of each OLE2UI dialog function: + * UStandardValidation Validates standard fields in each dialog structure + * UStandardInvocation Invokes a dialog through DialogBoxIndirectParam + * LpvStandardInit Common WM_INITDIALOG processing + * LpvStandardEntry Common code to execute on dialog proc entry. + * FStandardHook Centralized hook calling function. + * StandardCleanup Common exit/cleanup code. + * OleUIShowDlgItem Show-Enable/Hide-Disable dialog item + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "common.h" +#include "utility.h" +#include <malloc.h> + + +/* + * UStandardValidation + * + * Purpose: + * Performs validation on the standard pieces of any dialog structure, + * that is, the fields defined in the OLEUISTANDARD structure. + * + * Parameters: + * lpUI const LPOLEUISTANDARD pointing to the shared data of + * all structs. + * cbExpect const UINT structure size desired by the caller. + * phDlgMem const HGLOBAL FAR * in which to store a loaded customized + * template, if one exists. + * + * Return Value: + * UINT OLEUI_SUCCESS if all validation succeeded. Otherwise + * it will be one of the standard error codes. + */ + +UINT WINAPI UStandardValidation(const LPOLEUISTANDARD lpUI, const UINT cbExpect + , const HGLOBAL FAR *phMemDlg) + { + HRSRC hRes=NULL; + HGLOBAL hMem=NULL; + + + /* + * 1. Validate non-NULL pointer parameter. Note: We don't validate + * phDlg since it's not passed from an external source. + */ + if (NULL==lpUI) + return OLEUI_ERR_STRUCTURENULL; + + //2. Validate that the structure is readable and writable. + if (IsBadReadPtr(lpUI, cbExpect) || IsBadWritePtr(lpUI, cbExpect)) + return OLEUI_ERR_STRUCTUREINVALID; + + //3. Validate the structure size + if (cbExpect!=lpUI->cbStruct) + return OLEUI_ERR_CBSTRUCTINCORRECT; + + //4. Validate owner-window handle. NULL is considered valid. + if (NULL!=lpUI->hWndOwner && !IsWindow(lpUI->hWndOwner)) + return OLEUI_ERR_HWNDOWNERINVALID; + + //5. Validate the dialog caption. NULL is considered valid. + if (NULL!=lpUI->lpszCaption && IsBadReadPtr(lpUI->lpszCaption, 1)) + return OLEUI_ERR_LPSZCAPTIONINVALID; + + //6. Validate the hook pointer. NULL is considered valid. + if ((LPFNOLEUIHOOK)NULL!=lpUI->lpfnHook + && IsBadCodePtr((FARPROC)lpUI->lpfnHook)) + return OLEUI_ERR_LPFNHOOKINVALID; + + /* + * 7. If hInstance is non-NULL, we have to also check lpszTemplate. + * Otherwise, lpszTemplate is not used and requires no validation. + * lpszTemplate cannot be NULL if used. + */ + if (NULL!=lpUI->hInstance) + { + //Best we can try is one character + if (NULL==lpUI->lpszTemplate || IsBadReadPtr(lpUI->lpszTemplate, 1)) + return OLEUI_ERR_LPSZTEMPLATEINVALID; + + hRes=FindResource(lpUI->hInstance, lpUI->lpszTemplate, RT_DIALOG); + + //This is the only thing that catches invalid non-NULL hInstance + if (NULL==hRes) + return OLEUI_ERR_FINDTEMPLATEFAILURE; + + hMem=LoadResource(lpUI->hInstance, hRes); + + if (NULL==hMem) + return OLEUI_ERR_LOADTEMPLATEFAILURE; + } + + + //8. If hResource is non-NULL, be sure we can lock it. + if (NULL!=lpUI->hResource) + { + if ((LPSTR)NULL==GlobalLock(lpUI->hResource)) + return OLEUI_ERR_HRESOURCEINVALID; + + GlobalUnlock(lpUI->hResource); + } + + /* + * Here we have hMem==NULL if we should use the standard template + * or the one in lpUI->hResource. If hMem is non-NULL, then we + * loaded one from the calling application's resources which the + * caller of this function has to free if it sees any other error. + */ + *(HGLOBAL FAR *)phMemDlg=hMem; + return OLEUI_SUCCESS; + } + + + + + +/* + * UStandardInvocation + * + * Purpose: + * Provides standard template loading and calling on DialogBoxIndirectParam + * for all the OLE UI dialogs. + * + * Parameters: + * lpDlgProc DLGPROC of the dialog function. + * lpUI LPOLEUISTANDARD containing the dialog structure. + * hMemDlg HGLOBAL containing the dialog template. If this + * is NULL and lpUI->hResource is NULL, then we load + * the standard template given the name in lpszStdTemplate + * lpszStdTemplate LPCSTR standard template to load if hMemDlg is NULL + * and lpUI->hResource is NULL. + * + * Return Value: + * UINT OLEUI_SUCCESS if all is well, otherwise and error + * code. + */ + +UINT WINAPI UStandardInvocation +#ifdef WIN32 +(DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPTSTR lpszStdTemplate) +#else +(DLGPROC lpDlgProc, LPOLEUISTANDARD lpUI, HGLOBAL hMemDlg, LPCTSTR lpszStdTemplate) +#endif + { + HGLOBAL hTemplate=hMemDlg; + HRSRC hRes; + int iRet; + + //Make sure we have a template, then lock it down + if (NULL==hTemplate) + hTemplate=lpUI->hResource; + + if (NULL==hTemplate) + { + hRes=FindResource(ghInst, (LPCTSTR) lpszStdTemplate, RT_DIALOG); + + if (NULL==hRes) + { + return OLEUI_ERR_FINDTEMPLATEFAILURE; + } + + hTemplate=LoadResource(ghInst, hRes); + + if (NULL==hTemplate) + { + return OLEUI_ERR_LOADTEMPLATEFAILURE; + } + } + + /* + * hTemplate has the template to use, so now we can invoke the dialog. + * Since we have exported all of our dialog procedures using the + * _export keyword, we do not need to call MakeProcInstance, + * we can ue the dialog procedure address directly. + */ + + iRet=DialogBoxIndirectParam(ghInst, hTemplate, lpUI->hWndOwner + , lpDlgProc, (LPARAM)lpUI); + + /* + * Cleanup the template if we explicitly loaded it. Caller is + * responsible for already loaded template resources. + */ + if (hTemplate!=lpUI->hResource) + FreeResource(hTemplate); + + if (-1==iRet) + return OLEUI_ERR_DIALOGFAILURE; + + //Return the code from EndDialog, generally OLEUI_OK or OLEUI_CANCEL + return (UINT)iRet; + } + + + + + + +/* + * LpvStandardInit + * + * Purpose: + * Default actions for WM_INITDIALOG handling in the dialog, allocating + * a dialog-specific structure, setting that memory as a dialog property, + * and creating a small font if necessary setting that font as a property. + * + * Parameters: + * hDlg HWND of the dialog + * cbStruct UINT size of dialog-specific structure to allocate. + * fCreateFont BOOL indicating if we need to create a small Helv + * font for this dialog. + * phFont HFONT FAR * in which to place a created font. Can be + * NULL if fCreateFont is FALSE. + * + * Return Value: + * LPVOID Pointer to global memory allocated for the dialog. + * The memory will have been set as a dialog property + * using the STRUCTUREPROP label. + */ + +LPVOID WINAPI LpvStandardInit(HWND hDlg, UINT cbStruct, BOOL fCreateFont, HFONT FAR * phFont) + { + LPVOID lpv; + HFONT hFont; + LOGFONT lf; + HGLOBAL gh; + + //Must have at least sizeof(OLEUISTANDARD) bytes in cbStruct + if (sizeof(OLEUISTANDARD) > cbStruct || (fCreateFont && NULL==phFont)) + { + PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L); + return NULL; + } + + gh=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, cbStruct); + + if (NULL==gh) + { + PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L); + return NULL; + } + lpv = GlobalLock(gh); + SetProp(hDlg, STRUCTUREPROP, gh); + + if (fCreateFont) { + //Create the non-bold font for result and file texts. We call + hFont=(HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L); + GetObject(hFont, sizeof(LOGFONT), &lf); + lf.lfWeight=FW_NORMAL; + + //Attempt to create the font. If this fails, then we return no font. + *phFont=CreateFontIndirect(&lf); + + //If we couldn't create the font, we'll do with the default. + if (NULL!=*phFont) + SetProp(hDlg, FONTPROP, (HANDLE)*phFont); + } + + return lpv; + } + + + + + +/* + * LpvStandardEntry + * + * Purpose: + * Retrieves the dialog's structure property and calls the hook + * as necessary. This should be called on entry into all dialog + * procedures. + * + * Parameters: + * hDlg HWND of the dialog + * iMsg UINT message to the dialog + * wParam, lParam WPARAM, LPARAM message parameters + * puHookResult UINT FAR * in which this function stores the return value + * from the hook if it is called. If no hook is available, + * this will be FALSE. + * + * Return Value: + * LPVOID Pointer to the dialog's extra structure held in the + * STRUCTUREPROP property. + */ + +LPVOID WINAPI LpvStandardEntry(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam + , UINT FAR * puHookResult) + { + LPVOID lpv = NULL; + HGLOBAL gh; + + // This will fail under WM_INITDIALOG, where we allocate using StandardInit + gh = GetProp(hDlg, STRUCTUREPROP); + + if (NULL!=puHookResult && NULL!=gh) + { + *puHookResult=0; + + // gh was locked previously, lock and unlock to get lpv + lpv = GlobalLock(gh); + GlobalUnlock(gh); + + //Call the hook for all messages except WM_INITDIALOG + if (NULL!=lpv && WM_INITDIALOG!=iMsg) + *puHookResult=UStandardHook(lpv, hDlg, iMsg, wParam, lParam); + } + + return lpv; + } + + + + +/* + * UStandardHook + * + * Purpose: + * Provides a generic hook calling function assuming that all private + * dialog structures have a far pointer to their assocated public + * structure as the first field, and that the first part of the public + * structure matches an OLEUISTANDARD. + * + * Parameters: + * pv PVOID to the dialog structure. + * hDlg HWND to send with the call to the hook. + * iMsg UINT message to send to the hook. + * wParam, lParam WPARAM, LPARAM message parameters + * + * Return Value: + * UINT Return value from the hook, zero to indicate that + * default action should occur, nonzero to specify + * that the hook did process the message. In some + * circumstances it will be important for the hook to + * return a non-trivial non-zero value here, such as + * a brush from WM_CTLCOLOR, in which case the caller + * should return that value from the dialog procedure. + */ + +UINT WINAPI UStandardHook(LPVOID lpv, HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) + { + LPOLEUISTANDARD lpUI; + UINT uRet=0; + + lpUI=*((LPOLEUISTANDARD FAR *)lpv); + + if (NULL!=lpUI && NULL!=lpUI->lpfnHook) + { + /* + * In order for the hook to have the proper DS, they should be + * compiling with -GA -GEs so and usin __export to get everything + * set up properly. + */ + uRet=(*lpUI->lpfnHook)(hDlg, iMsg, wParam, lParam); + } + + return uRet; + } + + + + + +/* + * StandardCleanup + * + * Purpose: + * Removes properties and reverses any other standard initiazation + * done through StandardSetup. + * + * Parameters: + * lpv LPVOID containing the private dialog structure. + * hDlg HWND of the dialog closing. + * + * Return Value: + * None + */ + +void WINAPI StandardCleanup(LPVOID lpv, HWND hDlg) + { + HFONT hFont; + HGLOBAL gh; + + hFont=(HFONT)GetProp(hDlg, FONTPROP); + + if (NULL!=hFont) + DeleteObject(hFont); + + RemoveProp(hDlg, FONTPROP); + + gh = RemoveProp(hDlg, STRUCTUREPROP); + if (gh) + { + GlobalUnlock(gh); + GlobalFree(gh); + } + return; + } + + +/* StandardShowDlgItem +** ------------------- +** Show & Enable or Hide & Disable a dialog item as appropriate. +** it is NOT sufficient to simply hide the item; it must be disabled +** too or the keyboard accelerator still functions. +*/ +void WINAPI StandardShowDlgItem(HWND hDlg, int idControl, int nCmdShow) +{ + if (SW_HIDE == nCmdShow) { + ShowWindow(GetDlgItem(hDlg, idControl), SW_HIDE); + EnableWindow(GetDlgItem(hDlg, idControl), FALSE); + } else { + ShowWindow(GetDlgItem(hDlg, idControl), SW_SHOWNORMAL); + EnableWindow(GetDlgItem(hDlg, idControl), TRUE); + } +} diff --git a/private/oleutest/letest/ole2ui/common.h b/private/oleutest/letest/ole2ui/common.h new file mode 100644 index 000000000..00466661f --- /dev/null +++ b/private/oleutest/letest/ole2ui/common.h @@ -0,0 +1,166 @@ +/* + * 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 +#ifdef WIN32 + +#ifndef COMMANDPARAMS +#define COMMANDPARAMS(wID, wCode, hWndMsg) \ + WORD wID = LOWORD(wParam); \ + WORD wCode = HIWORD(wParam); \ + HWND hWndMsg = (HWND)(UINT)lParam; +#endif //COMMANDPARAMS + +#ifndef SendCommand +#define SendCommand(hWnd, wID, wCode, hControl) \ + SendMessage(hWnd, WM_COMMAND, MAKELONG(wID, wCode) \ + , (LPARAM)hControl) +#endif //SendCommand + +#else //Start !WIN32 + +#ifndef COMMANDPARAMS +#define COMMANDPARAMS(wID, wCode, hWndMsg) \ + WORD wID = LOWORD(wParam); \ + WORD wCode = HIWORD(lParam); \ + HWND hWndMsg = (HWND)(UINT)lParam; +#endif //COMMANDPARAMS + +#ifndef SendCommand +#define SendCommand(hWnd, wID, wCode, hControl) \ + SendMessage(hWnd, WM_COMMAND, wID \ + , MAKELONG(hControl, wCode)) +#endif //SendCommand + +#endif //!WIN32 + + + +//Property labels used to store dialog structures and fonts +#define STRUCTUREPROP TEXT("Structure") +#define FONTPROP TEXT("Font") + + +/* + * 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.C +UINT WINAPI UStandardValidation(const LPOLEUISTANDARD, const UINT, const HGLOBAL FAR *); + +#ifdef WIN32 +UINT WINAPI UStandardInvocation(DLGPROC, LPOLEUISTANDARD, HGLOBAL, LPTSTR); +#else +UINT WINAPI UStandardInvocation(DLGPROC, LPOLEUISTANDARD, HGLOBAL, LPCTSTR); +#endif + +LPVOID WINAPI LpvStandardInit(HWND, UINT, BOOL, HFONT FAR *); +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); + + +//DRAWICON.C + +//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 EXPORT EnumMetafileIconDraw(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPARAM); +int CALLBACK EXPORT EnumMetafileExtractLabel(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPLABELEXTRACT); +int CALLBACK EXPORT EnumMetafileExtractIcon(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPICONEXTRACT); +int CALLBACK EXPORT EnumMetafileExtractIconSource(HDC, HANDLETABLE FAR *, METARECORD FAR *, int, LPLABELEXTRACT); + + +//Shared globals: our instance, registered messages used from all dialogs and clipboard +// formats used by the PasteSpecial dialog +extern HINSTANCE ghInst; + +extern UINT uMsgHelp; +extern UINT uMsgEndDialog; +extern UINT uMsgBrowse; +extern UINT uMsgChangeIcon; +extern UINT uMsgFileOKString; +extern UINT uMsgCloseBusyDlg; + +extern UINT cfObjectDescriptor; +extern UINT cfLinkSrcDescriptor; +extern UINT cfEmbedSource; +extern UINT cfEmbeddedObject; +extern UINT cfLinkSource; +extern UINT cfOwnerLink; +extern UINT cfFileName; + +//Standard control identifiers +#define ID_NULL 98 + +#endif //_COMMON_H_ diff --git a/private/oleutest/letest/ole2ui/convert.c b/private/oleutest/letest/ole2ui/convert.c new file mode 100644 index 000000000..e5ca54131 --- /dev/null +++ b/private/oleutest/letest/ole2ui/convert.c @@ -0,0 +1,1802 @@ +/* + * CONVERT.C + * + * Implements the OleUIConvert function which invokes the complete + * Convert dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include <stdlib.h> +#include "common.h" +#include "utility.h" +#include "geticon.h" +#include "regdb.h" +#include "convert.h" + +#define CF_CLIPBOARDMIN 0xc000 +#define CF_CLIPBOARDMAX 0xffff + +#define AUXUSERTYPE_SHORTNAME USERCLASSTYPE_SHORT // short name + +static TCHAR szOLE2DLL[] = TEXT("ole2.dll"); // name of OLE 2.0 library + +static TCHAR szVanillaDocIcon[] = TEXT("DefIcon"); + +/* + * 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) + { + UINT uRet; + HGLOBAL hMemDlg=NULL; + + uRet=UStandardValidation((LPOLEUISTANDARD)lpCV, sizeof(OLEUICONVERT) + , &hMemDlg); + + if (OLEUI_SUCCESS!=uRet) + return uRet; + + // Validate structure members passed in. +#if defined( OBSOLETE ) + if (!IsValidClassID(lpCV->clsid)) + uRet = OLEUI_CTERR_CLASSIDINVALID; +#endif + + 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, (LPTSTR)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) + { + if (NULL!=lpCV->lpClsidExclude && IsBadReadPtr(lpCV->lpClsidExclude + , lpCV->cClsidExclude*sizeof(CLSID))) + uRet=OLEUI_IOERR_LPCLSIDEXCLUDEINVALID; + } + + + if (OLEUI_ERR_STANDARDMIN <= uRet) + { + if (NULL!=hMemDlg) + FreeResource(hMemDlg); + + return uRet; + } + + //Now that we've validated everything, we can invoke the dialog. + uRet=UStandardInvocation(ConvertDialogProc, (LPOLEUISTANDARD)lpCV, + hMemDlg, MAKEINTRESOURCE(IDD_CONVERT)); + + return uRet; + } + + + + + +/* + * ConvertDialogProc + * + * Purpose: + * Implements the OLE Convert dialog as invoked through the + * OleUIConvert function. + * + * Parameters: + * Standard + * + * Return Value: + * Standard + * + */ + +BOOL CALLBACK EXPORT ConvertDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) + { + LPCONVERT lpCV; + UINT uRet = 0; + OLEUICHANGEICON ci; + + //Declare Win16/Win32 compatible WM_COMMAND parameters. + COMMANDPARAMS(wID, wCode, hWndMsg); + + //This will fail under WM_INITDIALOG, where we allocate it. + lpCV=(LPCONVERT)LpvStandardEntry(hDlg, iMsg, wParam, lParam, (UINT FAR *)&uRet); + + //If the hook processed the message, we're done. + if (0!=uRet) + return (BOOL)uRet; + + //Process the temination message + if (iMsg==uMsgEndDialog) + { + ConvertCleanup(hDlg, lpCV); + StandardCleanup(lpCV, hDlg); + 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_INITDIALOG: + FConvertInit(hDlg, wParam, lParam); + return TRUE; + + case WM_COMMAND: + switch (wID) + { + case IDCV_ACTIVATELIST: + case IDCV_CONVERTLIST: + switch (wCode) + { + case LBN_SELCHANGE: + + // Change "Results" window to reflect current selection + SetConvertResults(hDlg, lpCV); + + // Update the icon we display, if we are indeed + // displaying an icon. + if ( (lpCV->dwFlags & CF_SELECTCONVERTTO) + && (lpCV->dvAspect == DVASPECT_ICON) + && (!lpCV->fCustomIcon) ) + UpdateCVClassIcon(hDlg, lpCV, hWndMsg); + + break; + + case LBN_DBLCLK: + //Same as pressing OK. + SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg); + break; + } + break; + + case IDCV_CONVERTTO: + case IDCV_ACTIVATEAS: + { + HWND hList, hListInvisible; + LRESULT lRetVal; + BOOL fState; + + hList = lpCV->hListVisible; + hListInvisible = lpCV->hListInvisible; + + + if (IDCV_CONVERTTO == wParam) + { + + // User just click on the button again - it was + // already selected. + if (lpCV->dwFlags & CF_SELECTCONVERTTO) + break; + + + // Turn painting updates off. + SendMessage(hDlg, WM_SETREDRAW, FALSE, 0L); + + + // 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; + + // Turn painting updates off. + SendMessage(hDlg, WM_SETREDRAW, FALSE, 0L); + + 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; + } + + + 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, IDCV_OBJECTTYPE, (LPTSTR)szCurrentObject, 40); + SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)(LPTSTR)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)) + UpdateCVClassIcon(hDlg, lpCV, lpCV->hListVisible); + + // Hide the icon stuff when Activate is selected...show + // it again when Convert is selected. + + fState = ((lpCV->dwFlags & CF_SELECTACTIVATEAS) || + (lpCV->dwFlags & CF_DISABLEDISPLAYASICON)) ? + SW_HIDE : SW_SHOW; + + StandardShowDlgItem(hDlg, IDCV_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, IDCV_CHANGEICON, fState); + StandardShowDlgItem(hDlg, IDCV_ICON, fState); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL1, fState); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL2, fState); + + SetConvertResults(hDlg, lpCV); + + } + break; + + + case IDOK: + { + + LRESULT iCurSel; + LPTSTR lpszCLSID; + TCHAR szBuffer[256]; + + // Set OUT parameters + + // + // 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 + // + iCurSel = SendMessage(lpCV->hListVisible, LB_GETCURSEL, 0, 0); + SendMessage(lpCV->hListVisible, LB_GETTEXT, iCurSel, (LPARAM)szBuffer); + + lpszCLSID = PointerToNthField((LPTSTR)szBuffer, 2, TEXT('\t')); + + CLSIDFromStringA(lpszCLSID, (&(lpCV->lpOCV->clsidNew))); + + // Free the hMetaPict we got in. + OleUIMetafilePictIconFree(lpCV->lpOCV->hMetaPict); + + // + // Get the hMetaPict (if display as icon is checked) + // + if (DVASPECT_ICON == lpCV->dvAspect) + { + HICON hIcon; + TCHAR szLabel[OLEUI_CCHLABELMAX]; + INT Index; + + + // Create the hMetaPict here from icon, label, + // index, and path + + hIcon = (HICON)SendDlgItemMessage(hDlg, IDCV_ICON, STM_GETICON, 0, 0L); + + // the combined length of the 2 label lines won't ever be more than + // OLEUI_CCHLABELMAX. + Index = (INT)SendDlgItemMessage(hDlg, IDCV_ICONLABEL1, + WM_GETTEXT, OLEUI_CCHLABELMAX, (LPARAM)szLabel); + + if (Index < OLEUI_CCHLABELMAX) + { + LPTSTR lpszSecondLine = szLabel + Index; + + + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, WM_GETTEXT, + OLEUI_CCHLABELMAX-Index, + (LPARAM)lpszSecondLine); + } + +#ifdef OLE201 + lpCV->lpOCV->hMetaPict = + OleUIMetafilePictFromIconAndLabel(hIcon, + (LPTSTR)szLabel, + lpCV->lpszIconSource, + lpCV->IconIndex); +#endif + + } + else + lpCV->lpOCV->hMetaPict = (HGLOBAL)NULL; + + + // + // End the dialog + // + SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L); + } + break; + + case IDCANCEL: + SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L); + break; + + + case ID_OLEUIHELP: + PostMessage(lpCV->lpOCV->hWndOwner, + uMsgHelp, (WPARAM)hDlg, MAKELPARAM(IDD_CONVERT, 0)); + break; + + case IDCV_DISPLAYASICON: + { + + int i; + BOOL fCheck; + + fCheck=IsDlgButtonChecked(hDlg, wID); + + if (fCheck) + lpCV->dvAspect = DVASPECT_ICON; + else + lpCV->dvAspect = DVASPECT_CONTENT; + + if (fCheck && (!lpCV->fCustomIcon)) + UpdateCVClassIcon(hDlg, lpCV, lpCV->hListVisible); + + //Show or hide the icon depending on the check state. + + i=(fCheck) ? SW_SHOWNORMAL : SW_HIDE; + + StandardShowDlgItem(hDlg, IDCV_CHANGEICON, i); + StandardShowDlgItem(hDlg, IDCV_ICON, i); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL1, i); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL2, i); + + SetConvertResults(hDlg, lpCV); + + } + break; + + case IDCV_CHANGEICON: + { + LPMALLOC pIMalloc; + LPTSTR pszString, pszCLSID; + INT iSel; + HICON hIcon; + TCHAR szLabel[OLEUI_CCHLABELMAX]; + INT Index; + + + //Initialize the structure for the hook. + _fmemset((LPOLEUICHANGEICON)&ci, 0, sizeof(ci)); + + // Create the hMetaPict here from icon, label, + // index, and path + + hIcon = (HICON)SendDlgItemMessage(hDlg, IDCV_ICON, STM_GETICON, 0, 0L); + + // the combined length of the 2 label lines won't ever be more than + // OLEUI_CCHLABELMAX. + + Index = (INT)SendDlgItemMessage(hDlg, IDCV_ICONLABEL1, WM_GETTEXT, + OLEUI_CCHLABELMAX, (LPARAM)szLabel); + + if (Index < OLEUI_CCHLABELMAX) + { + LPTSTR lpszSecondLine; + + lpszSecondLine = szLabel + Index; + + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, WM_GETTEXT, + OLEUI_CCHLABELMAX-Index, + (LPARAM)lpszSecondLine); + } + +#ifdef OLE201 + ci.hMetaPict = + OleUIMetafilePictFromIconAndLabel(hIcon, + szLabel, + lpCV->lpszIconSource, + lpCV->IconIndex); +#endif + + 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; + + iSel = (INT)SendMessage(lpCV->hListVisible, LB_GETCURSEL, 0, 0L); + + CoGetMalloc(MEMCTX_TASK, &pIMalloc); + + pszString = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, + OLEUI_CCHLABELMAX_SIZE + + OLEUI_CCHCLSIDSTRING_SIZE); + + // Get whole string + SendMessage(lpCV->hListVisible, LB_GETTEXT, iSel, (LONG)pszString); + + // Set pointer to CLSID (string) + pszCLSID = PointerToNthField(pszString, 2, TEXT('\t')); + + // Get the clsid to pass to change icon. + CLSIDFromStringA(pszCLSID, &(ci.clsid)); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszString); + pIMalloc->lpVtbl->Release(pIMalloc); + + //Let the hook in to customize Change Icon if desired. + uRet=UStandardHook(lpCV, hDlg, uMsgChangeIcon + , 0, (LONG)(LPTSTR)&ci); + + if (0==uRet) + uRet=(UINT)(OLEUI_OK==OleUIChangeIcon((LPOLEUICHANGEICON)&ci)); + + //Update the display if necessary. + if (0!=uRet) + { + HICON hIcon; + TCHAR szLabel[OLEUI_CCHLABELMAX]; + DWORD dwWrapIndex; + + + hIcon = OleUIMetafilePictExtractIcon(ci.hMetaPict); + + SendDlgItemMessage(hDlg, IDCV_ICON, STM_SETICON, (WPARAM)hIcon, 0L); + + OleUIMetafilePictExtractIconSource(ci.hMetaPict, lpCV->lpszIconSource, &(lpCV->IconIndex)); + + OleUIMetafilePictExtractLabel(ci.hMetaPict, szLabel, OLEUI_CCHLABELMAX, &dwWrapIndex); + + if (0 == dwWrapIndex) // no second line + { + SendDlgItemMessage(hDlg, IDCV_ICONLABEL1, WM_SETTEXT, 0, (LPARAM)(LPTSTR)szLabel); + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, WM_SETTEXT, 0, (LPARAM)(LPTSTR)TEXT("")); + } + else + { + + LPTSTR lpszSecondLine; + + lpszSecondLine = szLabel + dwWrapIndex; + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, + WM_SETTEXT, 0, (LPARAM)lpszSecondLine); + + *lpszSecondLine = TEXT('\0'); + SendDlgItemMessage(hDlg, IDCV_ICONLABEL1, + WM_SETTEXT, 0, (LPARAM)(LPTSTR)szLabel); + } + + + // 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) + { + LPCONVERT lpCV; + LPOLEUICONVERT lpOCV; + LPMALLOC pIMalloc; + HFONT hFont; // non-bold version of dialog's font + RECT rc; + DWORD dw; + INT cItemsActivate; + HKEY hKey; + LONG lRet; + UINT nRet; + + + //Copy the structure at lParam into our instance memory. + lpCV=(LPCONVERT)LpvStandardInit(hDlg, sizeof(CONVERT), TRUE, (HFONT FAR *)&hFont); + + //PvStandardInit send a termination to us already. + if (NULL==lpCV) + return FALSE; + + lpOCV=(LPOLEUICONVERT)lParam; + + lpCV->lpOCV=lpOCV; + + 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, IDCV_ACTIVATELIST); + lpCV->hListInvisible = GetDlgItem(hDlg, IDCV_CONVERTLIST); + lpCV->lpszCurrentObject = lpOCV->lpszUserType; + + lpOCV->clsidNew = CLSID_NULL; + + lpOCV->fObjectsIconChanged = FALSE; + + //Allocate space for our strings + if (NOERROR != CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return FALSE; + + lpCV->lpszConvertDefault = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHLABELMAX_SIZE); + lpCV->lpszActivateDefault = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHLABELMAX_SIZE); + lpCV->lpszIconSource = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHPATHMAX_SIZE); + pIMalloc->lpVtbl->Release(pIMalloc); + + //If we got a font, send it to the necessary controls. + if (NULL!=hFont) + { + SendDlgItemMessage(hDlg, IDCV_OBJECTTYPE, WM_SETFONT, (WPARAM)hFont, 0L); + SendDlgItemMessage(hDlg, IDCV_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L); + SendDlgItemMessage(hDlg, IDCV_ICONLABEL1, WM_SETFONT, (WPARAM)hFont, 0L); + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, WM_SETFONT, (WPARAM)hFont, 0L); + } + + //Hide the help button if necessary + if (!(lpCV->dwFlags & CF_SHOWHELPBUTTON)) + StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE); + + //Fill the Object Type listbox with entries from the reg DB. + nRet = FillClassList(lpOCV->clsid, + lpCV->hListVisible, + lpCV->hListInvisible, + &(lpCV->lpszCurrentObject), + lpOCV->fIsLinkedObject, + lpOCV->wFormat, + lpOCV->cClsidExclude, + lpOCV->lpClsidExclude); + + 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, IDCV_OBJECTTYPE, (LPTSTR)lpCV->lpszCurrentObject); + + // Disable the "Activate As" button if the Activate list doesn't + // have any objects in it. + + cItemsActivate = (INT)SendMessage(lpCV->hListVisible, LB_GETCOUNT, 0, 0L); + + if (1 >= cItemsActivate || (lpCV->dwFlags & CF_DISABLEACTIVATEAS)) + EnableWindow(GetDlgItem(hDlg, IDCV_ACTIVATEAS), FALSE); + + //Set the tab width in the list to push all the tabs off the side. + GetClientRect(lpCV->hListVisible, (LPRECT)&rc); + dw=GetDialogBaseUnits(); + rc.right =(8*rc.right)/LOWORD(dw); //Convert pixels to 2x dlg units. + SendMessage(lpCV->hListVisible, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)(&rc.right)); + SendMessage(lpCV->hListInvisible, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)(&rc.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, IDCV_CONVERTTO, IDCV_ACTIVATEAS, IDCV_ACTIVATEAS); + + // Hide the icon stuff when Activate is selected...it gets shown + // again when Convert is selected. + + StandardShowDlgItem(hDlg, IDCV_DISPLAYASICON, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_CHANGEICON, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICON, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL1, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL2, 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, IDCV_DISPLAYASICON, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_CHANGEICON, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICON, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL1, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL2, SW_HIDE); + } + + lpCV->dwFlags |= CF_SELECTCONVERTTO; // Make sure flag is set + CheckRadioButton(hDlg, IDCV_CONVERTTO, IDCV_ACTIVATEAS, IDCV_CONVERTTO); + + SwapWindows(hDlg, lpCV->hListVisible, lpCV->hListInvisible); + + lpCV->hListVisible = lpCV->hListInvisible; + lpCV->hListInvisible = hWndTemp; + + 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)) ) + { + dw = OleStdGetUserTypeOfClass((LPCLSID)(&lpCV->lpOCV->clsidConvertDefault), + lpCV->lpszConvertDefault, + OLEUI_CCHLABELMAX_SIZE, + NULL); + + if (0 == dw) + lstrcpy((LPTSTR)lpCV->lpszConvertDefault, (LPTSTR)lpCV->lpszCurrentObject); + } + else + lstrcpy((LPTSTR)lpCV->lpszConvertDefault, (LPTSTR)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; + + + + lRet = RegOpenKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), (HKEY FAR *)&hKey); + + if (lRet != ERROR_SUCCESS) + goto CheckInputFlag; + + else + { + LPTSTR lpszCLSID; + TCHAR szKey[OLEUI_CCHKEYMAX]; + CLSID clsid; + TCHAR szValue[OLEUI_CCHKEYMAX]; + + StringFromCLSIDA(&(lpCV->lpOCV->clsid), &lpszCLSID); + lstrcpy(szKey, lpszCLSID); + lstrcat(szKey, TEXT("\\TreatAs")); + + dw = OLEUI_CCHKEYMAX_SIZE; + lRet = RegQueryValue(hKey, (LPTSTR)szKey, (LPTSTR)szValue, (LPDWORD)&dw); + + if (lRet != ERROR_SUCCESS) + { + + RegCloseKey(hKey); + OleStdFreeString(lpszCLSID, NULL); + goto CheckInputFlag; + } + else + { + CLSIDFromStringA(szValue, &clsid); + + if (0 == OleStdGetUserTypeOfClass(&clsid, + lpCV->lpszActivateDefault, + OLEUI_CCHLABELMAX_SIZE, + NULL)) + { + RegCloseKey(hKey); + OleStdFreeString(lpszCLSID, NULL); + goto CheckInputFlag; + } + } + RegCloseKey(hKey); + OleStdFreeString(lpszCLSID, NULL); + goto SelectStringInListbox; + } + + +CheckInputFlag: + if ( (lpCV->dwFlags & CF_SETACTIVATEDEFAULT) + && (IsValidClassID(lpCV->lpOCV->clsidActivateDefault)) ) + { + dw = OleStdGetUserTypeOfClass((LPCLSID)(&lpCV->lpOCV->clsidActivateDefault), + lpCV->lpszActivateDefault, + OLEUI_CCHLABELMAX_SIZE, + NULL); + + if (0 == dw) + lstrcpy((LPTSTR)lpCV->lpszActivateDefault, (LPTSTR)lpCV->lpszCurrentObject); + } + else + lstrcpy((LPTSTR)(lpCV->lpszActivateDefault), (LPTSTR)lpCV->lpszCurrentObject); + + +SelectStringInListbox: + + if (lpCV->dwFlags & CF_SELECTCONVERTTO) + lRet = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)(LPTSTR)(lpCV->lpszConvertDefault)); + + else + lRet = SendMessage(lpCV->hListVisible, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)(LPTSTR)(lpCV->lpszActivateDefault)); + + if (LB_ERR == lRet) + SendMessage(lpCV->hListVisible, LB_SETCURSEL, (WPARAM)0, 0L); + + + // Initialize icon stuff + if (DVASPECT_ICON == lpCV->dvAspect ) + { + SendDlgItemMessage(hDlg, IDCV_DISPLAYASICON, BM_SETCHECK, TRUE, 0L); + + if ((HGLOBAL)NULL != lpOCV->hMetaPict) + { + TCHAR szLabel[OLEUI_CCHLABELMAX]; + HICON hIcon; + DWORD dwWrapIndex; + + + // Set the icon to the icon from the hMetaPict, + // set the label to the label from the hMetaPict. + + if (0 != OleUIMetafilePictExtractLabel(lpOCV->hMetaPict, (LPTSTR)szLabel, OLEUI_CCHLABELMAX_SIZE, &dwWrapIndex)) + { + if (0 == dwWrapIndex) // no second line + { + SendDlgItemMessage(hDlg, IDCV_ICONLABEL1, WM_SETTEXT, 0, (LPARAM)(LPTSTR)szLabel); + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, WM_SETTEXT, 0, (LPARAM)(LPTSTR)TEXT("")); + } + else + { + + LPTSTR lpszSecondLine; + + lpszSecondLine = szLabel + dwWrapIndex; + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, + WM_SETTEXT, 0, (LPARAM)lpszSecondLine); + + *lpszSecondLine = TEXT('\0'); + SendDlgItemMessage(hDlg, IDCV_ICONLABEL1, + WM_SETTEXT, 0, (LPARAM)(LPTSTR)szLabel); + } + + + } + + hIcon = OleUIMetafilePictExtractIcon(lpOCV->hMetaPict); + + if (NULL != hIcon) + { + SendDlgItemMessage(hDlg, IDCV_ICON, STM_SETICON, (WPARAM)hIcon, 0L); + lpCV->fCustomIcon = TRUE; + } + + OleUIMetafilePictExtractIconSource(lpOCV->hMetaPict, + (LPTSTR)(lpCV->lpszIconSource), + &(lpCV->IconIndex)); + + } + else + UpdateCVClassIcon(hDlg, lpCV, lpCV->hListVisible); + } + else + { + // Hide & disable icon stuff + StandardShowDlgItem(hDlg, IDCV_ICON, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL1, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_ICONLABEL2, SW_HIDE); + StandardShowDlgItem(hDlg, IDCV_CHANGEICON, 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) + && lpCV->lpOCV->lpszCaption[0] != '\0') + SetWindowText(hDlg, (LPTSTR)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 hList, + HWND hListInvisible, + LPTSTR FAR *lplpszCurrentClass, + BOOL fIsLinkedObject, + WORD wFormat, + UINT cClsidExclude, + LPCLSID lpClsidExclude) +{ + + DWORD dw; + UINT cStrings=0; + HKEY hKey; + LONG lRet; + TCHAR szFormatKey[OLEUI_CCHKEYMAX]; + TCHAR szClass[OLEUI_CCHKEYMAX]; + TCHAR szFormat[OLEUI_CCHKEYMAX]; + TCHAR szHRClassName[OLEUI_CCHKEYMAX]; + CLSID clsidForList; + + LPTSTR lpszCLSID; + + + //Clean out the existing strings. + SendMessage(hList, LB_RESETCONTENT, 0, 0L); + SendMessage(hListInvisible, LB_RESETCONTENT, 0, 0L); + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, (LPCTSTR) TEXT("CLSID"), (HKEY FAR *)&hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return (UINT)-1; + + if (NULL == *lplpszCurrentClass) + { + // alloc buffer here... + + LPMALLOC pIMalloc = NULL; + HRESULT hrErr; + + + hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); + + if (hrErr != NOERROR) + { + RegCloseKey(hKey); + return FALSE; + } + + // Allocate space for lpszCurrentClass + *lplpszCurrentClass = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHKEYMAX_SIZE); + pIMalloc->lpVtbl->Release(pIMalloc); + + lRet = OleStdGetUserTypeOfClass((REFCLSID)&clsid, + *lplpszCurrentClass, + OLEUI_CCHLABELMAX_SIZE, + NULL); + + if (0 ==lRet) + { + INT n = LoadString(ghInst, IDS_PSUNKNOWNTYPE, *lplpszCurrentClass, + OLEUI_CCHKEYMAX); + if (!n) + { + OutputDebugString(TEXT("Cannot LoadString\n")); + RegCloseKey(hKey); + return (UINT)-1; + } + } + } + + // Get the class name of the original class. + StringFromCLSIDA(&clsid, &lpszCLSID); + + + // 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 + + + cStrings=0; + lRet=RegEnumKey(hKey, cStrings++, szClass, OLEUI_CCHKEYMAX_SIZE); + + while ((LONG)ERROR_SUCCESS==lRet) + { + INT j; + BOOL fExclude=FALSE; + + + //Check if this CLSID is in the exclusion list. + CLSIDFromStringA(szClass, &clsidForList); + + for (j=0; j < (int)cClsidExclude; j++) + { + if (IsEqualCLSID(&clsidForList, (LPCLSID)(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((LPTSTR)szFormatKey, (LPTSTR)szClass); + lstrcat((LPTSTR)szFormatKey, (LPTSTR) TEXT("\\Conversion\\Readwritable\\Main")); + + dw=OLEUI_CCHKEYMAX_SIZE; + + lRet=RegQueryValue(hKey, (LPTSTR)szFormatKey, (LPTSTR)szFormat, (LONG FAR *)&dw); + + if ( ((LONG)ERROR_SUCCESS==lRet) + && (FormatIncluded((LPTSTR)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, (LPTSTR)szClass, (LPTSTR)szHRClassName, (LPDWORD)&dw); + + if ((LONG)ERROR_SUCCESS==lRet) + { + lstrcat((LPTSTR)szHRClassName, (LPTSTR) TEXT("\t")); + + // only add if not already in list + if (LB_ERR==SendMessage(hList,LB_FINDSTRING, 0, + (LPARAM)(LPSTR)szHRClassName)) { + lstrcat((LPTSTR)szHRClassName, (LPTSTR)szClass); + SendMessage(hList, LB_ADDSTRING, 0, + (DWORD)(LPTSTR)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((LPCTSTR)lpszCLSID, szClass) == 0)) + { + + //Check for a \Conversion\Readable\Main entry + lstrcpy((LPTSTR)szFormatKey, (LPTSTR)szClass); + lstrcat((LPTSTR)szFormatKey, (LPTSTR) TEXT("\\Conversion\\Readable\\Main")); + + dw=OLEUI_CCHKEYMAX_SIZE; + + // Check to see if this class can read the original class + // format. If it can, add the string to the listbox as + // CONVERT_LIST. + + lRet=RegQueryValue(hKey, (LPCTSTR)szFormatKey, (LPTSTR)szFormat, (LPDWORD)&dw); + + if ( ((LONG)ERROR_SUCCESS==lRet) + && (FormatIncluded((LPTSTR)szFormat, wFormat)) ) + { + + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, (LPCTSTR)szClass, (LPTSTR)szHRClassName, (LPDWORD)&dw); + + if ((LONG)ERROR_SUCCESS==lRet) + { + lstrcat((LPTSTR)szHRClassName, (LPTSTR) TEXT("\t")); + + // only add if not already in list + if (LB_ERR==SendMessage(hListInvisible,LB_FINDSTRING, 0, + (LPARAM)(LPSTR)szHRClassName)) { + lstrcat((LPTSTR)szHRClassName, szClass); + SendMessage(hListInvisible, LB_ADDSTRING, 0, + (DWORD)(LPTSTR)szHRClassName); + } + } // end if + + } // end if + } // end else +Next: + //Continue with the next key. + lRet=RegEnumKey(hKey, cStrings++, (LPTSTR)szClass, OLEUI_CCHKEYMAX_SIZE); + + } // end while + + // If the original class isn't already in the list, add it. + + lstrcpy((LPTSTR)szHRClassName, *lplpszCurrentClass); + lstrcat((LPTSTR)szHRClassName, (LPTSTR) TEXT("\t")); + + lRet = SendMessage(hList, LB_FINDSTRING, (WPARAM)-1, (LPARAM)(LPTSTR)szHRClassName); + + // only add it if it's not there already. + if (LB_ERR == lRet) { + lstrcat((LPTSTR)szHRClassName, lpszCLSID); + SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szHRClassName); + } + + lRet = SendMessage(hListInvisible, LB_FINDSTRING, (WPARAM)-1, (LPARAM)(LPTSTR)szHRClassName); + + // only add it if it's not there already. + if (LB_ERR == lRet) + SendMessage(hListInvisible, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szHRClassName); + + // Free the string we got from StringFromCLSID. + // OLE2NOTE: StringFromCLSID uses your IMalloc to alloc a + // string, so you need to be sure to free the string you + // get back, otherwise you'll have leaky memory. + + OleStdFreeString(lpszCLSID, NULL); + + RegCloseKey(hKey); + + return cStrings; +} + + +/* + * 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 +) +{ + + DWORD dw; + UINT cStrings=0; + HKEY hKey; + LONG lRet; + TCHAR szFormatKey[OLEUI_CCHKEYMAX]; + TCHAR szClass[OLEUI_CCHKEYMAX]; + TCHAR szFormat[OLEUI_CCHKEYMAX]; + TCHAR szHRClassName[OLEUI_CCHKEYMAX]; + BOOL fEnableConvert = FALSE; + + LPTSTR lpszCLSID; + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", (HKEY FAR *)&hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return FALSE; + + // Get the class name of the original class. + StringFromCLSIDA(rClsid, &lpszCLSID); + + // 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. + + cStrings=0; + lRet=RegEnumKey(hKey, cStrings++, szClass, OLEUI_CCHKEYMAX_SIZE); + + while ((LONG)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((LPTSTR)szFormatKey, (LPTSTR)szClass); + lstrcat((LPTSTR)szFormatKey, (LPTSTR) TEXT("\\Conversion\\Readwritable\\Main")); + + dw=OLEUI_CCHKEYMAX_SIZE; + + lRet=RegQueryValue(hKey, (LPCTSTR)szFormatKey, (LPTSTR)szFormat, (LONG FAR *)&dw); + + if ( (LONG)ERROR_SUCCESS != lRet) + { + // Try \\DataFormats\DefaultFile too + + lstrcpy((LPTSTR)szFormatKey, (LPTSTR)szClass); + lstrcat((LPTSTR)szFormatKey, (LPTSTR) TEXT("\\DataFormats\\DefaultFile")); + + dw=OLEUI_CCHKEYMAX_SIZE; + + lRet=RegQueryValue(hKey, (LPCTSTR)szFormatKey, (LPTSTR)szFormat, (LONG FAR *)&dw); + } + + + if ( ((LONG)ERROR_SUCCESS==lRet) + && (FormatIncluded((LPTSTR)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, (LPCTSTR)szClass, (LPTSTR)szHRClassName, (LPDWORD)&dw); + + if ((LONG)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((LPTSTR)lpszCLSID, (LPTSTR)szClass)== 0)) + { + + //Check for a \Conversion\Readable\Main entry + lstrcpy((LPTSTR)szFormatKey, (LPTSTR)szClass); + lstrcat((LPTSTR)szFormatKey, (LPTSTR) TEXT("\\Conversion\\Readable\\Main")); + + dw=OLEUI_CCHKEYMAX_SIZE; + + // Check to see if this class can read the original class + // format. If it can, add the string to the listbox as + // CONVERT_LIST. + + lRet=RegQueryValue(hKey, (LPTSTR)szFormatKey, (LPTSTR)szFormat, (LPDWORD)&dw); + + if ( ((LONG)ERROR_SUCCESS==lRet) + && (FormatIncluded((LPTSTR)szFormat, wFormat)) ) + { + + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, (LPTSTR)szClass, (LPTSTR)szHRClassName, (LPDWORD)&dw); + + if ((LONG)ERROR_SUCCESS==lRet) + { + + fEnableConvert = TRUE; + break; // STOP -- found one! + } // end if + + } // end if + } // end else +next: + //Continue with the next key. + lRet=RegEnumKey(hKey, cStrings++, (LPTSTR)szClass, OLEUI_CCHKEYMAX_SIZE); + + } // end while + + // Free the string we got from StringFromCLSID. + // OLE2NOTE: StringFromCLSID uses your IMalloc to alloc a + // string, so you need to be sure to free the string you + // get back, otherwise you'll have leaky memory. + + OleStdFreeString(lpszCLSID, NULL); + + 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) +{ + + LPTSTR lpToken; + TCHAR seps[] = TEXT(","); + static TCHAR szFormat[255]; // max size of atom (what GetClipboardName returns) + + + if (wFormat < 0xC000) // RegisterClipboardFormat returns values + { + char szTemp[11]; + + _itoa(wFormat, szTemp, 10); // between 0xC000 and 0xFFFF. + +#ifdef UNICODE + mbstowcs(szFormat, szTemp, 11); +#else + strncpy(szFormat, szTemp, 11); +#endif + + } + + else + GetClipboardFormatName(wFormat, szFormat, 255); + + lpToken = (LPTSTR)_fstrtok(szStringToSearch, seps); + + while (lpToken != NULL) + { + + if (0 ==lstrcmpi(lpToken, szFormat)) + return TRUE; + + else + lpToken = (LPTSTR)_fstrtok(NULL, seps); + } + + return FALSE; +} + + +/* + * UpdateCVClassIcon + * + * 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 + */ + +void UpdateCVClassIcon(HWND hDlg, LPCONVERT lpCV, HWND hList) + { + UINT iSel; + DWORD cb; + HGLOBAL hMem; + LPTSTR pszName, pszCLSID; + CLSID clsid; + HICON hIcon, hOldIcon; + UINT cch, uWrapIndex; + RECT LabelRect; + TCHAR szLabel[OLEUI_CCHLABELMAX]; + LPTSTR lpszLabel = szLabel; + HFONT hFont; + HWND hLabel1; + + /* + * When we change object type selection, get the new icon for that + * type into our structure and update it in the display. + */ + + 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); + + hMem=GlobalAlloc(GHND, cb+1); + + if (NULL==hMem) + return; + + pszName=GlobalLock(hMem); + + // Get whole string + SendMessage(hList, LB_GETTEXT, iSel, (LONG)pszName); + + // Set pointer to CLSID (string) + pszCLSID = PointerToNthField(pszName, 2, TEXT('\t')); + + //Create the class ID with this string. + CLSIDFromStringA(pszCLSID, &clsid); + + hIcon = HIconAndSourceFromClass(&clsid, (LPTSTR)(lpCV->lpszIconSource), &(lpCV->IconIndex)); + + if (NULL == hIcon) // Use Vanilla Document + { + lstrcpy((LPTSTR)(lpCV->lpszIconSource), (LPTSTR)szOLE2DLL); + lpCV->IconIndex = 0; // 1st icon in OLE2.DLL + hIcon = ExtractIcon(ghInst, + (LPTSTR)(lpCV->lpszIconSource), + lpCV->IconIndex); + } + + //Replace the current display with this new one. + hOldIcon = (HICON)SendDlgItemMessage(hDlg, IDCV_ICON, STM_SETICON, (WPARAM)hIcon, 0L); + + hLabel1 = GetDlgItem(hDlg, IDCV_ICONLABEL1); + + GetWindowRect(hLabel1, &LabelRect); + + // Get the label + if (lpCV->lpOCV->lpszDefLabel) { + // width is used as 1.5 times width of icon window + lpszLabel = ChopText(hLabel1, ((LabelRect.right-LabelRect.left)*3)/2, (LPTSTR)lpCV->lpOCV->lpszDefLabel); + LSTRCPYN(szLabel, lpCV->lpOCV->lpszDefLabel, sizeof(szLabel)/sizeof(TCHAR)); + } else { + if ((cch = OleStdGetAuxUserType(&clsid, AUXUSERTYPE_SHORTNAME, + (LPTSTR)szLabel, OLEUI_CCHLABELMAX_SIZE, NULL)) == 0) { + // If we can't get the AuxUserType2, then try the long name + if ((cch = OleStdGetUserTypeOfClass(&clsid, (LPTSTR)szLabel, + OLEUI_CCHKEYMAX_SIZE, NULL)) == 0) { + // last resort; use "Document" as label + LoadString(ghInst,IDS_DEFICONLABEL,(LPTSTR)szLabel,OLEUI_CCHLABELMAX); + cch = lstrlen((LPCTSTR)szLabel); + } + } + } + + hFont = (HFONT)SendMessage(hLabel1, WM_GETFONT, 0, 0L); + + // Figure out where to split the label + uWrapIndex = OleStdIconLabelTextOut(NULL, hFont, 0, 0, 0, &LabelRect, (LPTSTR)lpszLabel, cch, NULL); + + if (0 == uWrapIndex) + { + SendMessage(hLabel1, WM_SETTEXT, 0, (LPARAM)(LPTSTR)lpszLabel); + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, WM_SETTEXT, 0, (LPARAM)(LPTSTR)""); + } + else + { + TCHAR chKeep; + LPTSTR lpszSecondLine; + + chKeep = szLabel[uWrapIndex]; + lpszLabel[uWrapIndex] = TEXT('\0'); + + SendMessage(hLabel1, WM_SETTEXT, 0, (LPARAM)(LPTSTR)lpszLabel); + + lpszLabel[uWrapIndex] = chKeep; + lpszSecondLine = lpszLabel + uWrapIndex; + + SendDlgItemMessage(hDlg, IDCV_ICONLABEL2, WM_SETTEXT, 0, (LPARAM)lpszSecondLine); + } + + // get rid of the old icon + if ((HICON)NULL != hOldIcon) + DestroyIcon(hOldIcon); + + GlobalUnlock(hMem); + GlobalFree(hMem); + return; + } + + + + + + +BOOL IsValidClassID(CLSID cID) +{ + if (0 == _fmemcmp(&cID, &CLSID_NULL, sizeof(CLSID))) // if (CLSID_NULL == cID) + return FALSE; + else + return TRUE; +} + + + +/* + * 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) + { + LPTSTR pszT, // temp + lpszOutput, // text sent in SetDlgItemText + lpszDefObj, // string containing default object class + lpszSelObj, // string containing selected object class + lpszString; // stirng we get from loadstring + + UINT i, cch; + HGLOBAL hMem; + + HWND hList; // handle to listbox (so we can just use SendMsg i + // instead of SendDlgItemMsg). + + + 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. + */ + i=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L); + + cch=512+(UINT)SendMessage(hList, LB_GETTEXTLEN, i, 0L); + + hMem=GlobalAlloc(GHND, (DWORD)(4*cch)); + + if (NULL==hMem) + return; + + lpszOutput = (LPTSTR)GlobalLock(hMem); + lpszSelObj = lpszOutput + cch; + lpszDefObj = lpszSelObj + cch; + lpszString = lpszDefObj + cch; + + // Get selected object and null terminate human-readable name (1st field). + SendMessage(hList, LB_GETTEXT, i, (LONG)lpszSelObj); + + pszT = PointerToNthField(lpszSelObj, 2, TEXT('\t')); + +#ifdef WIN32 + // AnsiPrev is obsolete in Win32 + pszT = CharPrev((LPCTSTR) lpszSelObj, (LPCTSTR) pszT); +#else + pszT = AnsiPrev((LPCTSTR) lpszSelObj, (LPCTSTR) pszT); +#endif + + *pszT = TEXT('\0'); + + // Get default object + + GetDlgItemText(hDlg, IDCV_OBJECTTYPE, lpszDefObj, 512); + + + //Default is an empty string. + *lpszOutput=0; + + + if (lpCV->dwFlags & CF_SELECTCONVERTTO) + { + + if (lpCV->lpOCV->fIsLinkedObject) // working with linked object + LoadString(ghInst, IDS_CVRESULTCONVERTLINK, lpszOutput, cch); + + else + { + // converting to a new class + if (0 !=lstrcmp(lpszDefObj, lpszSelObj)) + { + if (0 != LoadString(ghInst, IDS_CVRESULTCONVERTTO, lpszString, cch)) + wsprintf(lpszOutput, lpszString, lpszDefObj, lpszSelObj); + + } + else // converting to the same class (no conversion) + { + + if (0 != LoadString(ghInst, IDS_CVRESULTNOCHANGE, lpszString, cch)) + wsprintf(lpszOutput, lpszString, lpszDefObj); + } + + } + + if (lpCV->dvAspect == DVASPECT_ICON) // Display as icon is checked + { + if (0 != LoadString(ghInst, IDS_CVRESULTDISPLAYASICON, lpszString, cch)) + lstrcat(lpszOutput, lpszString); + } + } + + if (lpCV->dwFlags & CF_SELECTACTIVATEAS) + { + + if (0!=LoadString(ghInst, IDS_CVRESULTACTIVATEAS, lpszString, cch)) + wsprintf(lpszOutput, lpszString, lpszDefObj, lpszSelObj); + + // activating as a new class + if (0 !=lstrcmp(lpszDefObj, lpszSelObj)) + { + if (0!=LoadString(ghInst, 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, IDCV_RESULTTEXT, lpszOutput); + + GlobalUnlock(hMem); + GlobalFree(hMem); + return; + } + + + + + + +/* + * 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) +{ + + LPMALLOC pIMalloc; + + + // Free our strings. Zero out the user type name string + // the the calling app doesn't free to it. + + if (NOERROR == CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + { + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)lpCV->lpszConvertDefault); + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)lpCV->lpszActivateDefault); + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)lpCV->lpszIconSource); + if (lpCV->lpOCV->lpszUserType) { + pIMalloc->lpVtbl->Free(pIMalloc,(LPVOID)lpCV->lpOCV->lpszUserType); + lpCV->lpOCV->lpszUserType = NULL; + } + if (lpCV->lpOCV->lpszDefLabel) { + pIMalloc->lpVtbl->Free(pIMalloc,(LPVOID)lpCV->lpOCV->lpszDefLabel); + lpCV->lpOCV->lpszDefLabel = NULL; + } + + pIMalloc->lpVtbl->Release(pIMalloc); + } + + return; +} + + + + + +/* + * 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) +{ + + RECT Rect1, Rect2; + + + GetWindowRect(hWnd1, &Rect1); + GetWindowRect(hWnd2, &Rect2); + + ScreenToClient(hDlg, (LPPOINT)&Rect1.left); + ScreenToClient(hDlg, (LPPOINT)&Rect1.right); + + 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); + + return; + +} + diff --git a/private/oleutest/letest/ole2ui/convert.dlg b/private/oleutest/letest/ole2ui/convert.dlg new file mode 100644 index 000000000..4f6f4dfc0 --- /dev/null +++ b/private/oleutest/letest/ole2ui/convert.dlg @@ -0,0 +1,32 @@ + +IDD_CONVERT DIALOG 60, 26, 270, 146 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Convert" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "Current Type:", IDCV_STXCURTYPE, 5, 7, 47, 8 + LTEXT "Current Object Type", IDCV_OBJECTTYPE, 55, 7, 129, 8 + LTEXT "Object T&ype:", IDCV_STXCONVERTTO, 71, 21, 89, 8 + LISTBOX IDCV_ACTIVATELIST, 71, 32, 118, 53, + LBS_USETABSTOPS | LBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP + LISTBOX IDCV_CONVERTLIST, 350, 180, 118, 53, + LBS_USETABSTOPS | LBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "OK", IDOK, 197, 6, 67, 14, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, 197, 24, 66, 14 + PUSHBUTTON "&Help", ID_OLEUIHELP, 197, 42, 66, 14 + CONTROL "&Display As Icon", IDCV_DISPLAYASICON, "Button", + BS_AUTOCHECKBOX | WS_TABSTOP, 200, 61, 64, 10 + GROUPBOX "Result", IDCV_GRPRESULT, 6, 87, 183, 50 + CONTROL "&Convert to:", IDCV_CONVERTTO, "Button", + BS_AUTORADIOBUTTON, 6, 34, 59, 10 + CONTROL "&Activate as:", IDCV_ACTIVATEAS, "Button", + BS_AUTORADIOBUTTON, 7, 58, 59, 10 + LTEXT "Result Text...", IDCV_RESULTTEXT, 11, 98, 174, 27 + ICON "", IDCV_ICON, 221, 75, 18, 20 + CTEXT "", IDCV_ICONLABEL1, 197, 100, 66, 8 + CTEXT "", IDCV_ICONLABEL2, 197, 108, 66, 12 + PUSHBUTTON "Change &Icon...", IDCV_CHANGEICON, 197, 121, 67, 14 +END + + + diff --git a/private/oleutest/letest/ole2ui/convert.h b/private/oleutest/letest/ole2ui/convert.h new file mode 100644 index 000000000..c6df6aa4f --- /dev/null +++ b/private/oleutest/letest/ole2ui/convert.h @@ -0,0 +1,63 @@ +/* + * CONVERT.H + * + * Internal definitions, structures, and function prototypes for the + * OLE 2.0 UI Convert dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + + +#ifndef _CONVERT_H_ +#define _CONVERT_H_ + + +//Internally used structure +typedef struct tagCONVERT + { + //Keep this item first as the Standard* functions depend on it here. + LPOLEUICONVERT lpOCV; //Original structure passed. + + /* + * 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 in CONVERT.C +BOOL CALLBACK EXPORT ConvertDialogProc(HWND, UINT, WPARAM, LPARAM); +BOOL FConvertInit(HWND hDlg, WPARAM, LPARAM); +UINT FPopulateListbox(HWND hListbox, CLSID cID); +BOOL IsValidClassID(CLSID cID); +void SetConvertResults(HWND, LPCONVERT); +UINT FillClassList( + CLSID clsid, + HWND hList, + HWND hListInvisible, + LPTSTR FAR *lplpszCurrentClass, + BOOL fIsLinkedObject, + WORD wFormat, + UINT cClsidExclude, + LPCLSID lpClsidExclude); +BOOL FormatIncluded(LPTSTR szStringToSearch, WORD wFormat); +void UpdateCVClassIcon(HWND hDlg, LPCONVERT lpCV, HWND hList); +void SwapWindows(HWND, HWND, HWND); +void ConvertCleanup(HWND hDlg, LPCONVERT lpCV); + +#endif // _CONVERT_H_ diff --git a/private/oleutest/letest/ole2ui/daytona/makefile b/private/oleutest/letest/ole2ui/daytona/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/oleutest/letest/ole2ui/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/oleutest/letest/ole2ui/daytona/ole2u32a.src b/private/oleutest/letest/ole2ui/daytona/ole2u32a.src new file mode 100644 index 000000000..fe30edf8e --- /dev/null +++ b/private/oleutest/letest/ole2ui/daytona/ole2u32a.src @@ -0,0 +1,200 @@ +#if 0 + + Microsoft Windows + Copyright (C) Microsoft Corporation, 1992 - 1992. + All rights reserved. + + This .def file is preprocessed by the compiler to create the version for + the current build in the appropriate subdir. Basically, whatever you + would have used in your code to control what is compiled when can be + used in this file for the same purpose. The following defines are in + use at the time this file was written: + + FLAT - Used to indicate a NT/DOS7 build + i386 - Intel i386/i486 build + MIPS - MIPS R3000/R4000 build + ALPHA - DEC Alpha build + DBG - Used to control Debug/Retail. Set to 1 if Debug, + 0 if Retail. + WIN31 - Win16 build + __OS2__ - OS/2 build (used by CT mostly) + + If none of these are used, it is assumed the entire file can be used + for all builds. + +#endif + +LIBRARY ole2u32a + +DESCRIPTION 'ole2u32a' + +EXPORTS + + SetDCToAnisotropic + SetDCToDrawInHimetricRect + ResetOrigDC + XformRectInPixelsToHimetric + XformRectInHimetricToPixels + XformSizeInPixelsToHimetric + XformSizeInHimetricToPixels + XformWidthInHimetricToPixels + XformWidthInPixelsToHimetric + XformHeightInHimetricToPixels + XformHeightInPixelsToHimetric + ParseCmdLine + OleStdIsOleLink + OleStdQueryInterface + OleStdCreateRootStorage + OleStdOpenRootStorage + OleStdOpenOrCreateRootStorage + OleStdCreateChildStorage + OleStdOpenChildStorage + OleStdCommitStorage + OleStdCreateStorageOnHGlobal + OleStdCreateTempStorage + OleStdDoConvert + OleStdGetTreatAsFmtUserType + OleStdDoTreatAsClass + OleStdSetupAdvises + OleStdSwitchDisplayAspect + OleStdSetIconInCache + OleStdGetData + OleStdMarkPasteEntryList + OleStdGetPriorityClipboardFormat + OleStdIsDuplicateFormat + OleStdRegisterAsRunning + OleStdRevokeAsRunning + OleStdNoteFileChangeTime + OleStdNoteObjectChangeTime + OleStdGetOleObjectData + OleStdGetLinkSourceData + OleStdGetObjectDescriptorData + OleStdGetObjectDescriptorDataFromOleObject + OleStdFillObjectDescriptorFromData + OleStdGetMetafilePictFromOleObject + OleStdCreateTempFileMoniker + OleStdGetFirstMoniker + OleStdGetLenFilePrefixOfMoniker + OleStdMalloc + OleStdRealloc + OleStdFree + OleStdGetSize + OleStdFreeString + OleStdCopyString + OleStdGetItemToken + OleStdInitVtbl + OleStdCheckVtbl + OleStdVerifyRelease + OleStdRelease + OleStdCreateDC + OleStdCreateIC + OleStdDeleteTargetDevice + OleStdCopyTargetDevice + OleStdCopyFormatEtc + FnAssert + OleDbgPrint + OleDbgPrintAlways + OleDbgSetDbgLevel + OleDbgGetDbgLevel + OleDbgIndent + OleDbgPrintRefCnt + OleDbgPrintRefCntAlways + OleDbgPrintRect + OleDbgPrintRectAlways + OleDbgPrintScodeAlways + OleUIInitialize + OleUIUnInitialize + OleUIAddVerbMenu + OleUIMetafilePictIconFree + OleUIMetafilePictIconDraw + OleUIMetafilePictExtractLabel + OleUIMetafilePictExtractIcon + OleUIMetafilePictExtractIconSource + OleUIInsertObject + OleUIPasteSpecial + OleUIEditLinks + OleUIChangeIcon + OleUIConvert + OleUIBusy + OleUIUpdateLinks + OleUIDrawHandles + OleUICanConvertOrActivateAs + OleUIDrawShading + OleUIShowObject + OleUIPromptUser + RegisterHatchWindowClass + CreateHatchWindow + GetHatchWidth + GetHatchRect + SetHatchRect + SetHatchWindowSize + OleStdEnumFmtEtc_Create + OleStdGetAuxUserType + OleStdGetUserTypeOfClass + OleStdIconLabelTextOut + OleStdMsgFilter_Create + OleStdMsgFilter_SetInComingCallStatus + OleStdMsgFilter_GetInComingCallStatus + OleStdMsgFilter_EnableBusyDialog + OleStdMsgFilter_EnableNotRespondingDialog + OleStdMsgFilter_SetParentWindow + OleStdGetMiscStatusOfClass + OleStdGetDefaultFileFormatOfClass + OleStdDestroyAllElements + OleStdCreateDbAlloc + OleStdInitSummaryInfo + OleStdFreeSummaryInfo + OleStdClearSummaryInfo + OleStdReadSummaryInfo + OleStdWriteSummaryInfo + OleStdGetSecurityProperty + OleStdSetSecurityProperty + OleStdGetStringProperty + OleStdSetStringProperty + OleStdGetStringZProperty + OleStdGetDocProperty + OleStdSetDocProperty + OleStdGetThumbNailProperty + OleStdSetThumbNailProperty + OleStdGetDateProperty + OleStdSetDateProperty + OleStdMsgFilter_SetHandleInComingCallbackProc + OleStdEnumStatData_Create + OleStdCopyStatData + OleStdCreateStandardPalette + OleStdMkParseDisplayName + CopyAndFreeOLESTR + CopyAndFreeSTR + CreateOLESTR + CreateSTR + CLSIDFromStringA + CLSIDFromProgIDA + CreateFileMonikerA + CreateItemMonikerA + GetClassFileA + MkParseDisplayNameA + OleCreateFromFileA + OleCreateLinkToFileA + OleGetIconOfClassA + OleGetIconOfFileA + OleMetafilePictFromIconAndLabelA + OleRegGetUserTypeA + ProgIDFromCLSIDA + ReadFmtUserTypeStgA + StgCreateDocfileA + StgOpenStorageA + StgSetTimesA + StringFromCLSIDA + WriteFmtUserTypeStgA + CallIMonikerGetDisplayNameA + CallIOleLinkGetSourceDisplayNameA + CallIOleLinkSetSourceDisplayNameA + CallIOleInPlaceFrameSetStatusTextA + CallIOleInPlaceUIWindowSetActiveObjectA + CallIOleObjectGetUserTypeA + CallIOleObjectSetHostNamesA + CallIStorageCreateStorageA + CallIStorageDestroyElementA + CallIStorageOpenStorageA + CallIStorageCreateStreamA + CallIStorageOpenStreamA diff --git a/private/oleutest/letest/ole2ui/daytona/ole2ui.src b/private/oleutest/letest/ole2ui/daytona/ole2ui.src new file mode 100644 index 000000000..24b82dcf6 --- /dev/null +++ b/private/oleutest/letest/ole2ui/daytona/ole2ui.src @@ -0,0 +1,199 @@ +#if 0 + + Microsoft Windows + Copyright (C) Microsoft Corporation, 1992 - 1992. + All rights reserved. + + This .def file is preprocessed by the compiler to create the version for + the current build in the appropriate subdir. Basically, whatever you + would have used in your code to control what is compiled when can be + used in this file for the same purpose. The following defines are in + use at the time this file was written: + + FLAT - Used to indicate a NT/DOS7 build + i386 - Intel i386/i486 build + MIPS - MIPS R3000/R4000 build + ALPHA - DEC Alpha build + DBG - Used to control Debug/Retail. Set to 1 if Debug, + 0 if Retail. + WIN31 - Win16 build + __OS2__ - OS/2 build (used by CT mostly) + + If none of these are used, it is assumed the entire file can be used + for all builds. + +#endif + +LIBRARY ole2ui + +DESCRIPTION 'ole2ui' + +EXPORTS + + SetDCToAnisotropic + SetDCToDrawInHimetricRect + ResetOrigDC + XformRectInPixelsToHimetric + XformRectInHimetricToPixels + XformSizeInPixelsToHimetric + XformSizeInHimetricToPixels + XformWidthInHimetricToPixels + XformWidthInPixelsToHimetric + XformHeightInHimetricToPixels + XformHeightInPixelsToHimetric + ParseCmdLine + OleStdIsOleLink + OleStdQueryInterface + OleStdCreateRootStorage + OleStdOpenRootStorage + OleStdOpenOrCreateRootStorage + OleStdCreateChildStorage + OleStdOpenChildStorage + OleStdCommitStorage + OleStdCreateStorageOnHGlobal + OleStdCreateTempStorage + OleStdDoConvert + OleStdGetTreatAsFmtUserType + OleStdDoTreatAsClass + OleStdSetupAdvises + OleStdSwitchDisplayAspect + OleStdSetIconInCache + OleStdGetData + OleStdMarkPasteEntryList + OleStdGetPriorityClipboardFormat + OleStdIsDuplicateFormat + OleStdRegisterAsRunning + OleStdRevokeAsRunning + OleStdNoteFileChangeTime + OleStdNoteObjectChangeTime + OleStdGetOleObjectData + OleStdGetLinkSourceData + OleStdGetObjectDescriptorData + OleStdGetObjectDescriptorDataFromOleObject + OleStdFillObjectDescriptorFromData + OleStdGetMetafilePictFromOleObject + OleStdCreateTempFileMoniker + OleStdGetFirstMoniker + OleStdGetLenFilePrefixOfMoniker + OleStdMalloc + OleStdRealloc + OleStdFree + OleStdGetSize + OleStdFreeString + OleStdCopyString + OleStdGetItemToken + OleStdInitVtbl + OleStdCheckVtbl + OleStdVerifyRelease + OleStdRelease + OleStdCreateDC + OleStdCreateIC + OleStdDeleteTargetDevice + OleStdCopyTargetDevice + OleStdCopyFormatEtc + OleDbgPrint + OleDbgPrintAlways + OleDbgSetDbgLevel + OleDbgGetDbgLevel + OleDbgIndent + OleDbgPrintRefCnt + OleDbgPrintRefCntAlways + OleDbgPrintRect + OleDbgPrintRectAlways + OleDbgPrintScodeAlways + OleUIInitialize + OleUIUnInitialize + OleUIAddVerbMenu + OleUIMetafilePictIconFree + OleUIMetafilePictIconDraw + OleUIMetafilePictExtractLabel + OleUIMetafilePictExtractIcon + OleUIMetafilePictExtractIconSource + OleUIInsertObject + OleUIPasteSpecial + OleUIEditLinks + OleUIChangeIcon + OleUIConvert + OleUIBusy + OleUIUpdateLinks + OleUIDrawHandles + OleUICanConvertOrActivateAs + OleUIDrawShading + OleUIShowObject + OleUIPromptUser + RegisterHatchWindowClass + CreateHatchWindow + GetHatchWidth + GetHatchRect + SetHatchRect + SetHatchWindowSize + OleStdEnumFmtEtc_Create + OleStdGetAuxUserType + OleStdGetUserTypeOfClass + OleStdIconLabelTextOut + OleStdMsgFilter_Create + OleStdMsgFilter_SetInComingCallStatus + OleStdMsgFilter_GetInComingCallStatus + OleStdMsgFilter_EnableBusyDialog + OleStdMsgFilter_EnableNotRespondingDialog + OleStdMsgFilter_SetParentWindow + OleStdGetMiscStatusOfClass + OleStdGetDefaultFileFormatOfClass + OleStdDestroyAllElements + OleStdCreateDbAlloc + OleStdInitSummaryInfo + OleStdFreeSummaryInfo + OleStdClearSummaryInfo + OleStdReadSummaryInfo + OleStdWriteSummaryInfo + OleStdGetSecurityProperty + OleStdSetSecurityProperty + OleStdGetStringProperty + OleStdSetStringProperty + OleStdGetStringZProperty + OleStdGetDocProperty + OleStdSetDocProperty + OleStdGetThumbNailProperty + OleStdSetThumbNailProperty + OleStdGetDateProperty + OleStdSetDateProperty + OleStdMsgFilter_SetHandleInComingCallbackProc + OleStdEnumStatData_Create + OleStdCopyStatData + OleStdCreateStandardPalette + OleStdMkParseDisplayName + CopyAndFreeOLESTR + CopyAndFreeSTR + CreateOLESTR + CreateSTR + CLSIDFromStringA + CLSIDFromProgIDA + CreateFileMonikerA + CreateItemMonikerA + GetClassFileA + MkParseDisplayNameA + OleCreateFromFileA + OleCreateLinkToFileA + OleGetIconOfClassA + OleGetIconOfFileA + OleMetafilePictFromIconAndLabelA + OleRegGetUserTypeA + ProgIDFromCLSIDA + ReadFmtUserTypeStgA + StgCreateDocfileA + StgOpenStorageA + StgSetTimesA + StringFromCLSIDA + WriteFmtUserTypeStgA + CallIMonikerGetDisplayNameA + CallIOleLinkGetSourceDisplayNameA + CallIOleLinkSetSourceDisplayNameA + CallIOleInPlaceFrameSetStatusTextA + CallIOleInPlaceUIWindowSetActiveObjectA + CallIOleObjectGetUserTypeA + CallIOleObjectSetHostNamesA + CallIStorageCreateStorageA + CallIStorageDestroyElementA + CallIStorageOpenStorageA + CallIStorageCreateStreamA + CallIStorageOpenStreamA diff --git a/private/oleutest/letest/ole2ui/daytona/sources b/private/oleutest/letest/ole2ui/daytona/sources new file mode 100644 index 000000000..91c6ca237 --- /dev/null +++ b/private/oleutest/letest/ole2ui/daytona/sources @@ -0,0 +1,64 @@ + +MAJORCOMP = cairole +MINORCOMP = com + +TARGETNAME= ole2u32a +TARGETPATH= obj +TARGETTYPE= DYNLINK + +DLLDEF= obj\*\ole2u32a.def +DLLENTRY= DllEntryPoint +DLLBASE=@$(BASEDIR)\PUBLIC\SDK\LIB\coffbase.txt,usermode + +INCLUDES=.. + +C_DEFINES=-DWIN32 -DDEBUG -DINC_OLE2 -DCLIENT -DWINDOWS -DOLE201 + +SOURCES= \ + ..\BUSY.C \ + ..\COMMON.C \ + ..\CONVERT.C \ + ..\DBALLOC.CPP \ + ..\DBGUTIL.C \ + ..\DLLENTRY.C \ + ..\DLLFUNCS.C \ + ..\DRAWICON.C \ + ..\ENUMFETC.C \ + ..\ENUMSTAT.C \ + ..\GETICON.C \ + ..\HATCH.C \ + ..\ICON.C \ + ..\ICONBOX.C \ + ..\INSOBJ.C \ + ..\LINKS.C \ + ..\MSGFILTR.C \ + ..\OBJFDBK.C \ + ..\OLE2UI.C \ + ..\OLESTD.C \ + ..\OLETHUNK.C \ + ..\OLEUTL.C \ + ..\PASTESPL.C \ + ..\PRECOMP.C \ + ..\REGDB.C \ + ..\RESIMAGE.C \ + ..\STDPAL.C \ + ..\SUMINFO.CPP \ + ..\TARGTDEV.C \ + ..\UTILITY.C \ + ..\OLE2UI.RC + +UMTYPE=windows + +TARGETLIBS= \ + $(BASEDIR)\public\sdk\lib\*\ole32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\gdi32.lib \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib \ + $(BASEDIR)\public\sdk\lib\*\advapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\uuid.lib + +USE_CRTDLL= 1 + +MISCFILES=..\..\data\letest12.olc diff --git a/private/oleutest/letest/ole2ui/dballoc.cpp b/private/oleutest/letest/ole2ui/dballoc.cpp new file mode 100644 index 000000000..b62259c64 --- /dev/null +++ b/private/oleutest/letest/ole2ui/dballoc.cpp @@ -0,0 +1,900 @@ + +/*** +*dballoc.cpp +* +* Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved. +* +*Purpose: +* This file contains a debug implementation of the IMalloc interface. +* +* This implementation is basically a simple wrapping of the C runtime, +* with additional work to detect memory leakage, and memory overwrite. +* +* Leakage is detected by tracking each allocation in an address +* instance table, and then checking to see if the table is empty +* when the last reference to the allocator is released. +* +* Memory overwrite is detected by placing a signature at the end +* of every allocated block, and checking to make sure the signature +* is unchanged when the block is freed. +* +* This implementation also has additional param validation code, as +* well as additional check make sure that instances that are passed +* to Free() were actually allocated by the corresponding instance +* of the allocator. +* +* +* Creating an instance of this debug allocator that uses the default +* output interface would look like the following, +* +* +* BOOL init_application_instance() +* { +* HRESULT hresult; +* IMalloc FAR* pmalloc; +* +* pmalloc = NULL; +* +* if((hresult = OleStdCreateDbAlloc(0,&pmalloc))!=NOERROR) +* goto LReturn; +* +* hresult = OleInitialize(pmalloc); +* +* // release pmalloc to let OLE hold the only ref to the it. later +* // when OleUnitialize is called, memory leaks will be reported. +* if(pmalloc != NULL) +* pmalloc->Release(); +* +* LReturn: +* +* return (hresult == NOERROR) ? TRUE : FALSE; +* } +* +* +* CONSIDER: could add an option to force error generation, something +* like DBALLOC_ERRORGEN +* +* CONSIDER: add support for heap-checking. say for example, +* DBALLOC_HEAPCHECK would do a heapcheck every free? every 'n' +* calls to free? ... +* +* +*Implementation Notes: +* +* The method IMalloc::DidAlloc() is allowed to always return +* "Dont Know" (-1). This method is called by Ole, and they take +* some appropriate action when they get this answer. + +The debugging allocator has the option to catch bugs where code is writing off +the end of allocated memory. This is implemented by using NT's virtual memory +services. To switch on this option, use + +#define DBALLOC_POWERDEBUG + +Note it will ONLY WORK ON NT. This option consumes a very large amount of +memory. Basically, for every allocation, it cooks the allocation so that the +end of the allocation will fall on a page boundary. An extra page of memory +is allocated after the requested memory. The protection bits for this page +are altered so that it is an error to read or write to it. Any incident of +writing past the end of allocated memory is trapped at the point of the error. + +This consumes a great deal of memory because at least two pages must be +allocated for each allocation. +* +*****************************************************************************/ + + +// Note: this file is designed to be stand-alone; it includes a +// carefully chosen, minimal set of headers. +// +// For conditional compilation we use the ole2 conventions, +// _MAC = mac +// WIN32 = Win32 (NT really) +// <nothing> = defaults to Win16 + + +// REVIEW: the following needs to modified to handle _MAC +#define STRICT +#ifndef INC_OLE2 + #define INC_OLE2 +#endif + +#include <windows.h> + +#include "ole2.h" + +#if defined( __TURBOC__) +#define __STDC__ (1) +#endif + +#define WINDLL 1 // make far pointer version of stdargs.h +#include <stdarg.h> + +#if defined( __TURBOC__) +#undef __STDC__ +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <string.h> +#include <limits.h> + +#include "dballoc.h" + + +#define DIM(X) (sizeof(X)/sizeof((X)[0])) + +#define UNREACHED 0 + +#if defined(WIN32) +# define MEMCMP(PV1, PV2, CB) memcmp((PV1), (PV2), (CB)) +# define MEMCPY(PV1, PV2, CB) memcpy((PV1), (PV2), (CB)) +# define MEMSET(PV, VAL, CB) memset((PV), (VAL), (CB)) +# define MALLOC(CB) malloc(CB) +# define REALLOC(PV, CB) realloc((PV), (CB)) +# define FREE(PV) free(PV) + +#ifndef WIN32 +# define HEAPMIN() _heapmin() +#else +# define HEAPMIN() +#endif + +#elif defined(_MAC) +# define MEMCMP(PV1, PV2) ERROR -- NYI +# define MEMCPY(PV1, PV2, CB) ERROR -- NYI +# define MEMSET(PV, VAL, CB) ERROR -- NYI +# define MALLOC(CB) ERROR -- NYI +# define REALLOC(PV, CB) ERROR -- NYI +# define FREE(PV) ERROR -- NYI +# define HEAPMIN() ERROR -- NYI +#else +# define MEMCMP(PV1, PV2, CB) _fmemcmp((PV1), (PV2), (CB)) +# define MEMCPY(PV1, PV2, CB) _fmemcpy((PV1), (PV2), (CB)) +# define MEMSET(PV, VAL, CB) _fmemset((PV), (VAL), (CB)) +# define MALLOC(CB) _fmalloc(CB) +# define REALLOC(PV, CB) _frealloc(PV, CB) +# define FREE(PV) _ffree(PV) +# define HEAPMIN() _fheapmin() +#endif + +#if defined( __TURBOC__ ) +#define classmodel _huge +#else +#define classmodel FAR +#endif + +class classmodel CStdDbOutput : public IDbOutput { +public: + static IDbOutput FAR* Create(); + + // IUnknown methods + + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv); + STDMETHOD_(ULONG, AddRef)(void); + STDMETHOD_(ULONG, Release)(void); + + + // IDbOutput methods + + STDMETHOD_(void, Printf)(TCHAR FAR* szFmt, ...); + + STDMETHOD_(void, Assertion)( + BOOL cond, + TCHAR FAR* szExpr, + TCHAR FAR* szFile, + UINT uLine, + TCHAR FAR* szMsg); + + + void FAR* operator new(size_t cb){ + return MALLOC(cb); + } + void operator delete(void FAR* pv){ + FREE(pv); + } + + CStdDbOutput(){ + m_refs = 0; + } + +private: + ULONG m_refs; + + TCHAR m_rgch[128]; // buffer for output formatting +}; + + +//--------------------------------------------------------------------- +// implementation of the debug allocator +//--------------------------------------------------------------------- + +class FAR CAddrNode +{ +public: + void FAR* m_pv; // instance + ULONG m_cb; // size of allocation in BYTES + ULONG m_nAlloc; // the allocation pass count + CAddrNode FAR* m_next; + + void FAR* operator new(size_t cb){ + return MALLOC(cb); + } + void operator delete(void FAR* pv){ + FREE(pv); + } +}; + + +class classmodel CDbAlloc : public IMalloc +{ +public: + static HRESULT Create( + ULONG options, IDbOutput FAR* pdbout, IMalloc FAR* FAR* ppmalloc); + + // IUnknown methods + + STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppv); + STDMETHOD_(ULONG, AddRef)(void); + STDMETHOD_(ULONG, Release)(void); + + // IMalloc methods + + STDMETHOD_(void FAR*, Alloc)(ULONG cb); + STDMETHOD_(void FAR*, Realloc)(void FAR* pv, ULONG cb); + STDMETHOD_(void, Free)(void FAR* pv); + STDMETHOD_(ULONG, GetSize)(void FAR* pv); + STDMETHOD_(int, DidAlloc)(void FAR* pv); + STDMETHOD_(void, HeapMinimize)(void); + + + void FAR* operator new(size_t cb){ + return MALLOC(cb); + } + void operator delete(void FAR* pv){ + FREE(pv); + } + + CDbAlloc(){ + m_refs = 1; + m_pdbout = NULL; + m_cAllocCalls = 0; + m_nBreakAtNthAlloc = 0; + m_nBreakAtAllocSize = 0; + MEMSET(m_rganode, 0, sizeof(m_rganode)); +#ifdef DBALLOC_POWERDEBUG + { + SYSTEM_INFO si; + + GetSystemInfo(&si); + m_virtPgSz = si.dwPageSize; + } +#endif // DBALLOC_POWERDEBUG + } + +private: + + ULONG m_refs; + ULONG m_cAllocCalls; // total count of allocation calls + ULONG m_nBreakAtNthAlloc; // allocation number to break to debugger + // this value should be set typically in the + // debugger. + ULONG m_nBreakAtAllocSize; // allocation size to break to debugger + // this value should be set typically in the + // debugger. + IDbOutput FAR* m_pdbout; // output interface + CAddrNode FAR* m_rganode[64]; // address instance table + + + // instance table methods + + BOOL IsEmpty(void); + + void AddInst(void FAR* pv, ULONG nAlloc, ULONG cb); + void DelInst(void FAR* pv); + CAddrNode FAR* GetInst(void FAR* pv); + + void DumpInst(CAddrNode FAR* pn); + void DumpInstTable(void); + + inline UINT HashInst(void FAR* pv) const { + return ((UINT)((ULONG)pv >> 4)) % DIM(m_rganode); + + } + + // output method(s) + + inline void Assertion( + BOOL cond, + TCHAR FAR* szExpr, + TCHAR FAR* szFile, + UINT uLine, + TCHAR FAR* szMsg) + { + m_pdbout->Assertion(cond, szExpr, szFile, uLine, szMsg); + } + + #define ASSERT(X) Assertion(X, TEXT(#X), TEXT(__FILE__), __LINE__, NULL) + + #define ASSERTSZ(X, SZ) Assertion(X, TEXT(#X), TEXT(__FILE__), __LINE__, SZ) + + static const BYTE m_rgchSig[]; + +#ifdef DBALLOC_POWERDEBUG + size_t m_virtPgSz; +#endif // DBALLOC_POWERDEBUG +}; + +const BYTE CDbAlloc::m_rgchSig[] = { 0xDE, 0xAD, 0xBE, 0xEF }; + + +/*** +*HRESULT OleStdCreateDbAlloc(ULONG reserved, IMalloc** ppmalloc) +* Purpose: +* Create an instance of CDbAlloc -- a debug implementation +* of IMalloc. +* +* Parameters: +* ULONG reserved - reserved for future use. must be 0. +* IMalloc FAR* FAR* ppmalloc - (OUT) pointer to an IMalloc interface +* of new debug allocator object +* Returns: +* HRESULT +* NOERROR - if no error. +* E_OUTOFMEMORY - allocation failed. +* +***********************************************************************/ +STDAPI OleStdCreateDbAlloc(ULONG reserved,IMalloc FAR* FAR* ppmalloc) +{ + return CDbAlloc::Create(reserved, NULL, ppmalloc); +} + + +HRESULT +CDbAlloc::Create( + ULONG options, + IDbOutput FAR* pdbout, + IMalloc FAR* FAR* ppmalloc) +{ + HRESULT hresult; + CDbAlloc FAR* pmalloc; + + + // default the instance of IDbOutput if the user didn't supply one + if(pdbout == NULL && ((pdbout = CStdDbOutput::Create()) == NULL)){ + hresult = ResultFromScode(E_OUTOFMEMORY); + goto LError0; + } + + pdbout->AddRef(); + + if((pmalloc = new FAR CDbAlloc()) == NULL){ + hresult = ResultFromScode(E_OUTOFMEMORY); + goto LError1; + } + + pmalloc->m_pdbout = pdbout; + + *ppmalloc = pmalloc; + + return NOERROR; + +LError1:; + pdbout->Release(); + pmalloc->Release(); + +LError0:; + return hresult; +} + +STDMETHODIMP +CDbAlloc::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IMalloc)){ + *ppv = this; + AddRef(); + return NOERROR; + } + return ResultFromScode(E_NOINTERFACE); +} + +STDMETHODIMP_(ULONG) +CDbAlloc::AddRef() +{ + return ++m_refs; +} + +STDMETHODIMP_(ULONG) +CDbAlloc::Release() +{ + if(--m_refs == 0){ + + // check for memory leakage + if(IsEmpty()){ + m_pdbout->Printf(TEXT("No Memory Leaks.\n")); + }else{ + m_pdbout->Printf(TEXT("Memory Leak Detected,\n")); + DumpInstTable(); + } + + m_pdbout->Release(); + delete this; + return 0; + } + return m_refs; +} + +STDMETHODIMP_(void FAR*) +CDbAlloc::Alloc(ULONG cb) +{ + size_t size; + void FAR* pv; + + ++m_cAllocCalls; + + if (m_nBreakAtNthAlloc && m_cAllocCalls == m_nBreakAtNthAlloc) { + ASSERTSZ(FALSE, TEXT("DBALLOC: NthAlloc Break target reached\r\n")); + } else if (m_nBreakAtAllocSize && cb == m_nBreakAtAllocSize) { + ASSERTSZ(FALSE, TEXT("DBALLOC: AllocSize Break target reached\r\n")); + } + +#ifndef DBALLOC_POWERDEBUG + // REVIEW: need to add support for huge allocations (on win16) + if((cb + sizeof(m_rgchSig)) > UINT_MAX) + return NULL; + + size = (size_t)cb; + + if((pv = MALLOC(size + sizeof(m_rgchSig))) == NULL) + return NULL; + + // set allocated block to some non-zero value + MEMSET(pv, -1, size); + + // put signature at end of allocated block + MEMCPY(((char FAR*)pv) + size, m_rgchSig, sizeof(m_rgchSig)); + + AddInst(pv, m_cAllocCalls, size); +#else + // for each allocate, allocate the amount of memory required, and + // one more page beyond that. We will change the protection bits of + // the trailing page so that we get an access violation if someone + // writes beyond the end of their allocated memory + { + size_t allocpgs; // number of pages to allocate + DWORD dwOldProt; // previous protection of the last page + void *plastpg; // points to the beginning of the last page + + // allocate at least one page for the allocation, and + // one to go after it + allocpgs = (cb + 2*m_virtPgSz) / m_virtPgSz; + pv = VirtualAlloc(NULL, allocpgs*m_virtPgSz, + MEM_COMMIT, PAGE_READWRITE); + + // change the protection of the last page + plastpg = (void *)(((BYTE *)pv)+m_virtPgSz*(allocpgs-1)); + VirtualProtect(plastpg, m_virtPgSz, PAGE_NOACCESS, &dwOldProt); + + // figure out what pointer to return to the user + pv = (void *)(((BYTE *)plastpg)-cb); + + // record the allocation + AddInst(pv, m_cAllocCalls, cb); + } +#endif // DBALLOC_POWERDEBUG + + return pv; +} + +STDMETHODIMP_(void FAR*) +CDbAlloc::Realloc(void FAR* pv, ULONG cb) +{ + size_t size; + CAddrNode *pcan; + +#ifndef DBALLOC_POWERDEBUG + // REVIEW: need to add support for huge realloc + if((cb + sizeof(m_rgchSig)) > UINT_MAX) + return NULL; +#endif // DBALLOC_POWERDEBUG + + if(pv == NULL){ + return Alloc(cb); + } + + ++m_cAllocCalls; + + ASSERT((pcan = GetInst(pv)) != NULL); +#ifndef DBALLOC_POWERDEBUG + + DelInst(pv); + + if(cb == 0){ + Free(pv); + return NULL; + } + + size = (size_t)cb; + + if((pv = REALLOC(pv, size + sizeof(m_rgchSig))) == NULL) + return NULL; + + // put signature at end of allocated block + MEMCPY(((char FAR*)pv) + size, m_rgchSig, sizeof(m_rgchSig)); + + AddInst(pv, m_cAllocCalls, size); +#else + { + void *pnew; + DWORD dwOldProt; + + // allocate new memory + pnew = Alloc(cb); + + // copy in the previous material + memcpy(pnew, pcan->m_pv, pcan->m_cb); + + // protect the old memory + VirtualProtect(pcan->m_pv, pcan->m_cb, PAGE_NOACCESS, + &dwOldProt); + + DelInst(pv); + AddInst(pv, m_cAllocCalls, cb); + pv = pnew; + } +#endif // DBALLOC_POWERDEBUG + + return pv; +} + +STDMETHODIMP_(void) +CDbAlloc::Free(void FAR* pv) +{ + if (pv == NULL) + { + // Free of NULL is a NO-OP + return; + } + + CAddrNode FAR* pn; + static TCHAR szSigMsg[] = TEXT("Signature Check Failed"); + + pn = GetInst(pv); + + // check for attempt to free an instance we didnt allocate + if(pn == NULL){ + ASSERTSZ(FALSE, TEXT("pointer freed by wrong allocator")); + return; + } + +#ifndef DBALLOC_POWERDEBUG + // verify the signature + if(MEMCMP(((char FAR*)pv) + pn->m_cb, m_rgchSig, sizeof(m_rgchSig)) != 0){ + m_pdbout->Printf(szSigMsg); m_pdbout->Printf(TEXT("\n")); + DumpInst(GetInst(pv)); + ASSERTSZ(FALSE, szSigMsg); + } + + // stomp on the contents of the block + MEMSET(pv, 0xCC, ((size_t)pn->m_cb + sizeof(m_rgchSig))); + + DelInst(pv); + FREE(pv); +#else + { + DWORD dwOldProt; + + // make the block inaccessible + VirtualProtect(pv, pn->m_cb, PAGE_NOACCESS, &dwOldProt); + DelInst(pv); + } +#endif // DBALLOC_POWERDEBUG +} + + +STDMETHODIMP_(ULONG) +CDbAlloc::GetSize(void FAR* pv) +{ + CAddrNode FAR* pn; + + if (pv == NULL) + { + // GetSize is supposed to return a -1 when NULL is passed in. + return (ULONG) -1; + } + + pn = GetInst(pv); + + if (pn == NULL) { + ASSERT(pn != NULL); + return 0; + } + + return pn->m_cb; +} + + +/*** +*PUBLIC HRESULT CDbAlloc::DidAlloc +*Purpose: +* Answer if the given address belongs to a block allocated by +* this allocator. +* +*Entry: +* pv = the instance to lookup +* +*Exit: +* return value = int +* 1 - did alloc +* 0 - did *not* alloc +* -1 - dont know (according to the ole2 spec it is always legal +* for the allocator to answer "dont know") +* +***********************************************************************/ +STDMETHODIMP_(int) +CDbAlloc::DidAlloc(void FAR* pv) +{ + return -1; // answer "I dont know" +} + + +STDMETHODIMP_(void) +CDbAlloc::HeapMinimize() +{ + HEAPMIN(); +} + + +//--------------------------------------------------------------------- +// instance table methods +//--------------------------------------------------------------------- + +/*** +*PRIVATE CDbAlloc::AddInst +*Purpose: +* Add the given instance to the address instance table. +* +*Entry: +* pv = the instance to add +* nAlloc = the allocation passcount of this instance +* +*Exit: +* None +* +***********************************************************************/ +void +CDbAlloc::AddInst(void FAR* pv, ULONG nAlloc, ULONG cb) +{ + UINT hash; + CAddrNode FAR* pn; + + + ASSERT(pv != NULL); + + pn = (CAddrNode FAR*)new FAR CAddrNode(); + + if (pn == NULL) { + ASSERT(pn != NULL); + return; + } + + pn->m_pv = pv; + pn->m_cb = cb; + pn->m_nAlloc = nAlloc; + + hash = HashInst(pv); + pn->m_next = m_rganode[hash]; + m_rganode[hash] = pn; +} + + +/*** +*UNDONE +*Purpose: +* Remove the given instance from the address instance table. +* +*Entry: +* pv = the instance to remove +* +*Exit: +* None +* +***********************************************************************/ +void +CDbAlloc::DelInst(void FAR* pv) +{ + CAddrNode FAR* FAR* ppn, FAR* pnDead; + + for(ppn = &m_rganode[HashInst(pv)]; *ppn != NULL; ppn = &(*ppn)->m_next){ + if((*ppn)->m_pv == pv){ + pnDead = *ppn; + *ppn = (*ppn)->m_next; + delete pnDead; + // make sure it doesnt somehow appear twice + ASSERT(GetInst(pv) == NULL); + return; + } + } + + // didnt find the instance + ASSERT(UNREACHED); +} + + +CAddrNode FAR* +CDbAlloc::GetInst(void FAR* pv) +{ + CAddrNode FAR* pn; + + for(pn = m_rganode[HashInst(pv)]; pn != NULL; pn = pn->m_next){ + if(pn->m_pv == pv) + return pn; + } + return NULL; +} + + +void +CDbAlloc::DumpInst(CAddrNode FAR* pn) +{ + if (pn == NULL) + return; + + m_pdbout->Printf(TEXT("[0x%lx] nAlloc=%ld size=%ld\n"), + pn->m_pv, pn->m_nAlloc, GetSize(pn->m_pv)); +} + + +/*** +*PRIVATE BOOL IsEmpty +*Purpose: +* Answer if the address instance table is empty. +* +*Entry: +* None +* +*Exit: +* return value = BOOL, TRUE if empty, FALSE otherwise +* +***********************************************************************/ +BOOL +CDbAlloc::IsEmpty() +{ + UINT u; + + for(u = 0; u < DIM(m_rganode); ++u){ + if(m_rganode[u] != NULL) + return FALSE; + } + + return TRUE; +} + + +/*** +*PRIVATE CDbAlloc::Dump +*Purpose: +* Print the current contents of the address instance table, +* +*Entry: +* None +* +*Exit: +* None +* +***********************************************************************/ +void +CDbAlloc::DumpInstTable() +{ + UINT u; + CAddrNode FAR* pn; + + for(u = 0; u < DIM(m_rganode); ++u){ + for(pn = m_rganode[u]; pn != NULL; pn = pn->m_next){ + DumpInst(pn); + } + } +} + + +//--------------------------------------------------------------------- +// implementation of CStdDbOutput +//--------------------------------------------------------------------- + +IDbOutput FAR* +CStdDbOutput::Create() +{ + return (IDbOutput FAR*)new FAR CStdDbOutput(); +} + +STDMETHODIMP +CStdDbOutput::QueryInterface(REFIID riid, void FAR* FAR* ppv) +{ + if(IsEqualIID(riid, IID_IUnknown)) + { + *ppv = this; + AddRef(); + return NOERROR; + } + return ResultFromScode(E_NOINTERFACE); +} + +STDMETHODIMP_(ULONG) +CStdDbOutput::AddRef() +{ + return ++m_refs; +} + +STDMETHODIMP_(ULONG) +CStdDbOutput::Release() +{ + if(--m_refs == 0){ + delete this; + return 0; + } + return m_refs; +} + +STDMETHODIMP_(void) +CStdDbOutput::Printf(TCHAR FAR* lpszFmt, ...) +{ + va_list args; + TCHAR szBuf[256]; +#if defined( OBSOLETE ) + TCHAR *pn, FAR* pf; +static TCHAR rgchFmtBuf[128]; +static TCHAR rgchOutputBuf[128]; + + // copy the 'far' format string to a near buffer so we can use + // a medium model vsprintf, which only supports near data pointers. + // + pn = rgchFmtBuf, pf=szFmt; + while(*pf != TEXT('\0')) + *pn++ = *pf++; + *pn = TEXT('\0'); +#endif + + va_start(args, lpszFmt); + +// wvsprintf(rgchOutputBuf, rgchFmtBuf, args); + wvsprintf(szBuf, lpszFmt, args); + + OutputDebugString(szBuf); +} + +STDMETHODIMP_(void) +CStdDbOutput::Assertion( + BOOL cond, + TCHAR FAR* szExpr, + TCHAR FAR* szFile, + UINT uLine, + TCHAR FAR* szMsg) +{ + if(cond) + return; + +#ifdef _DEBUG + // following is from compobj.dll (ole2) + #ifdef UNICODE + #ifndef NOASSERT + FnAssert(szExpr, szMsg, szFile, uLine); + #endif + #else + // we need to talk to comobj in UNICODE even though we are not defined + // as UNICODE + { + WCHAR wszExpr[255], wszMsg[255], wszFile[255]; + mbstowcs(wszExpr, szExpr, 255); + mbstowcs(wszMsg, szMsg, 255); + mbstowcs(wszFile, szFile, 255); + #ifndef NOASSERT + FnAssert(wszExpr, wszMsg, wszFile, uLine); + #endif + } + #endif +#else + // REVIEW: should be able to do something better that this... + DebugBreak(); +#endif +} diff --git a/private/oleutest/letest/ole2ui/dballoc.h b/private/oleutest/letest/ole2ui/dballoc.h new file mode 100644 index 000000000..42ccbaff2 --- /dev/null +++ b/private/oleutest/letest/ole2ui/dballoc.h @@ -0,0 +1,36 @@ +/*** +*dballoc.h +* +* Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved. +* +*Purpose: +* This file contains the definition of CDbAlloc - A debug implementation +* of the IMalloc interface. +* +*Implementation Notes: +* +*****************************************************************************/ + +#ifndef DBALLOC_H_INCLUDED /* { */ +#define DBALLOC_H_INCLUDED + + +interface IDbOutput : public IUnknown +{ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void FAR* FAR* ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + STDMETHOD_(void, Printf)(THIS_ + TCHAR FAR* szFmt, ...) PURE; + + STDMETHOD_(void, Assertion)(THIS_ + BOOL cond, + TCHAR FAR* szExpr, + TCHAR FAR* szFile, + UINT uLine, + TCHAR FAR* szMsg) PURE; +}; + + +#endif /* } DBALLOC_H_INCLUDED */ diff --git a/private/oleutest/letest/ole2ui/dbgutil.c b/private/oleutest/letest/ole2ui/dbgutil.c new file mode 100644 index 000000000..15c17a248 --- /dev/null +++ b/private/oleutest/letest/ole2ui/dbgutil.c @@ -0,0 +1,419 @@ +/************************************************************************* +** +** 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 +** +*************************************************************************/ + +#define STRICT 1 +#include "ole2ui.h" + +static int s_nDbgIndent = 0; // indent level for debug message +#if defined( _DEBUG ) +static int s_nDbgLevel = 0; // default dbg level printed +#else +static int s_nDbgLevel = 0; // default dbg level printed +#endif + +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) +{ + int i; + + if (nIndent < 0) + OleDbgIndent(nIndent); + + if (lpszPrefix && *lpszPrefix != TEXT('\0')) { + OutputDebugString(TEXT("| ")); + for (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 +) +{ +#if defined( _DEBUG ) + TCHAR szBuf[256]; + + wsprintf(szBuf, TEXT("[obj=(0x%lx) cnt=%ld] %s"), lpObj, refcnt, lpszMsg); + OleDbgPrintAlways(lpszPrefix, szBuf, 0); +#endif +} + + +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 +) +{ +#if defined( _DEBUG ) + 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); +#endif +} + + +#define CASE_SCODE(sc) \ + case sc: \ + lstrcpy((LPTSTR)szErrName, (LPTSTR)#sc); \ + break; + +STDAPI_(void) OleDbgPrintScodeAlways(LPTSTR lpszPrefix, LPTSTR lpszMsg, SCODE sc) +{ +#if defined( _DEBUG ) + TCHAR szBuf[256]; + TCHAR szErrName[40]; + + 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_CANTCALLOUT_AGAIN) + 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: + lstrcpy(szErrName, TEXT("UNKNOWN SCODE")); + } + + wsprintf(szBuf, TEXT("%s %s (0x%lx)\n"), lpszMsg, (LPTSTR)szErrName, sc); + OleDbgPrintAlways(lpszPrefix, szBuf, 0); +#endif // _DEBUG +} + +STDAPI FnAssert(LPSTR lpstrExpr, LPSTR lpstrMsg, LPSTR lpstrFileName, UINT iLine) +{ +#ifdef _DEBUG + char szOutput[1024]; + char szTitle[256]; + char szModuleName[128]; + char *pszModuleName; + int id; + + DWORD tid = GetCurrentThreadId(); + DWORD pid = GetCurrentProcessId(); + + wsprintfA(szOutput, "%s %s File: %s Line: %d PID: %d TID: %d\n", + lpstrExpr, lpstrMsg ? lpstrMsg : "", lpstrFileName, pid, tid); + OutputDebugString(szOutput); + + if (GetModuleFileNameA(NULL, szModuleName, 128)) + { + pszModuleName = strrchr(szModuleName, '\\'); + if (!pszModuleName) + { + pszModuleName = szModuleName; + } + else + { + pszModuleName++; + } + } + else + { + pszModuleName = "Unknown"; + } + + wsprintfA(szTitle, "Process: %s File: %s, line %u", + pszModuleName, lpstrFileName, iLine); + + wsprintfA(szOutput, "%s %s PID.TID %d.%d", + lpstrExpr, lpstrMsg ? lpstrMsg : "", pid, tid); + + id = MessageBoxA(NULL, + szOutput, + szTitle, + MB_SETFOREGROUND | MB_DEFAULT_DESKTOP_ONLY | + MB_TASKMODAL | MB_ICONEXCLAMATION | MB_OKCANCEL); + + + if (id == IDCANCEL) + { + DebugBreak(); + } + +#endif // _DEBUG + return NOERROR; +} diff --git a/private/oleutest/letest/ole2ui/debug.h b/private/oleutest/letest/ole2ui/debug.h new file mode 100644 index 000000000..fa5bfc7ef --- /dev/null +++ b/private/oleutest/letest/ole2ui/debug.h @@ -0,0 +1,69 @@ +/* + * DEBUG.H + * + * Definitions, structures, types, and function prototypes for debugging + * purposes. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved, + * as applied to redistribution of this source code in source form + * License is granted to use of compiled code in shipped binaries. + */ + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +#ifdef DEBUG + +//Basic debug macros +#define D(x) {x;} +#define ODS(x) D(OutputDebugString(x);OutputDebugString("\r\n")) + +#define ODSsz(f, s) {\ + char szDebug[128];\ + wsprintf(szDebug, f, (LPSTR)s);\ + ODS(szDebug);\ + } + + +#define ODSu(f, u) {\ + char szDebug[128];\ + wsprintf(szDebug, f, (UINT)u);\ + ODS(szDebug);\ + } + + +#define ODSlu(f, lu) {\ + char szDebug[128];\ + wsprintf(szDebug, f, (DWORD)lu);\ + ODS(szDebug);\ + } + +#define ODSszu(f, s, u) {\ + char szDebug[128];\ + wsprintf(szDebug, f, (LPSTR)s, (UINT)u);\ + ODS(szDebug);\ + } + + +#define ODSszlu(f, s, lu) {\ + char szDebug[128];\ + wsprintf(szDebug, f, (LPSTR)s, (DWORD)lu);\ + ODS(szDebug);\ + } + + +#else //NO DEBUG + +#define D(x) +#define ODS(x) + +#define ODSsz(f, s) +#define ODSu(f, u) +#define ODSlu(f, lu) +#define ODSszu(f, s, u) +#define ODSszlu(f, s, lu) + + +#endif //DEBUG + +#endif //_DEBUG_H_ diff --git a/private/oleutest/letest/ole2ui/default.ico b/private/oleutest/letest/ole2ui/default.ico Binary files differnew file mode 100644 index 000000000..4542c57d3 --- /dev/null +++ b/private/oleutest/letest/ole2ui/default.ico diff --git a/private/oleutest/letest/ole2ui/defuimak.ini b/private/oleutest/letest/ole2ui/defuimak.ini new file mode 100644 index 000000000..39517d711 --- /dev/null +++ b/private/oleutest/letest/ole2ui/defuimak.ini @@ -0,0 +1,20 @@ +# This is the DEBUG UILibrary INI file +MSG=DEBUG Version ($(LANG)) +DEBUG=1 +LIBNAME=outlui +REL_DIR=c:\ole2samp\release +OLEREL_DIR=c:\ole2samp\release +OBJ=DEBUG +RESOURCE=RESOURCE +CFLAGS=-c -Od -Gw2cs -W3 -Zpei -AMw -D_DEBUG -D_WINDLL -Gi +AFLAGS=-mx -Zi -DDEBUG +RFLAGS=-D DEBUG +LFLAGS=/MAP /CO /L /NOD /NOE /SE:300 +UILIBS=mdllcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +LANG=USA +DLLOBJS = $(UI_DLLOBJS:D^\=DEBUG^\) +LIBOBJS = $(UI_COBJS:D^\=DEBUG^\) $(UI_NOPCOBJS:D^\=DEBUG\NOPC^\) diff --git a/private/oleutest/letest/ole2ui/depend b/private/oleutest/letest/ole2ui/depend new file mode 100644 index 000000000..4007c4980 --- /dev/null +++ b/private/oleutest/letest/ole2ui/depend @@ -0,0 +1,87 @@ +$(O)busy.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h common.h utility.h busy.h + +$(O)common.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h common.h utility.h + +$(O)convert.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h common.h utility.h geticon.h regdb.h \ + convert.h + +$(O)dbgutil.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h + +$(O)regdb.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h + +$(O)drawicon.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h common.h utility.h geticon.h + +$(O)hatch.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h + +$(O)icon.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h common.h utility.h icon.h geticon.h + +$(O)iconbox.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h iconbox.h + +$(O)insobj.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h common.h utility.h icon.h insobj.h \ + resimage.h iconbox.h geticon.h + +$(O)links.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h common.h edlinks.h utility.h + +$(O)msgfiltr.obj : $(PRECOMP) \ + ole2ui.h olestd.h uiclass.h msgfiltr.h + +$(O)enumfetc.obj : $(PRECOMP) \ + ole2ui.h olestd.h + +$(O)enumstat.obj : $(PRECOMP) \ + ole2ui.h olestd.h + +$(O)objfdbk.obj : $(PRECOMP) \ + ole2ui.h olestd.h + +$(O)ole2ui.obj : $(PRECOMP) \ + ole2ui.h olestd.h common.h utility.h resimage.h iconbox.h + +$(O)olestd.obj : $(PRECOMP) \ + ole2ui.h olestd.h regdb.h geticon.h common.h + +$(O)targtdev.obj : $(PRECOMP) \ + ole2ui.h olestd.h + +$(O)oleutl.obj : $(PRECOMP) \ + ole2ui.h olestd.h + +$(O)pastespl.obj : $(PRECOMP) \ + ole2ui.h olestd.h pastespl.h common.h utility.h resimage.h iconbox.h \ + geticon.h regdb.h + +$(O)resimage.obj : $(PRECOMP) \ + ole2ui.h olestd.h resimage.h + +$(O)utility.obj : $(PRECOMP) \ + ole2ui.h olestd.h common.h utility.h geticon.h + +$(O)dllfuncs.obj : $(PRECOMP) \ + ole2ui.h olestd.h common.h uiclass.h + +$(O)NOPC\geticon.obj : \ + ole2ui.h olestd.h uiclass.h geticon.h + +$(O)NOPC\dballoc.obj : \ + dballoc.h + +$(O)NOPC\suminfo.obj : \ + suminfo.h wn_dos.h + +$(O)NOPC\stdpal.obj : \ + stdpal.h + +$(O)precomp.pch : \ + ole2ui.h olestd.h uiclass.h + diff --git a/private/oleutest/letest/ole2ui/depend.mk b/private/oleutest/letest/ole2ui/depend.mk new file mode 100644 index 000000000..2b6c05155 --- /dev/null +++ b/private/oleutest/letest/ole2ui/depend.mk @@ -0,0 +1,569 @@ +# +# Built automatically +# + +# +# Source files +# + +$(OBJDIR)\busy.obj $(OBJDIR)\busy.lst: .\busy.c $(CAIROLE)\h\export\coguid.h \ + $(CAIROLE)\h\export\compobj.h $(CAIROLE)\h\export\dvobj.h \ + $(CAIROLE)\h\export\initguid.h $(CAIROLE)\h\export\moniker.h \ + $(CAIROLE)\h\export\ole2.h $(CAIROLE)\h\export\oleguid.h \ + $(CAIROLE)\h\export\scode.h $(CAIROLE)\h\export\storage.h \ + $(CRTINC)\ctype.h $(CRTINC)\dos.h $(CRTINC)\excpt.h \ + $(CRTINC)\stdarg.h $(CRTINC)\string.h $(OSINC)\cderr.h \ + $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h $(OSINC)\dlgs.h \ + $(OSINC)\drivinit.h $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h \ + $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h \ + $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h \ + $(OSINC)\shellapi.h $(OSINC)\winbase.h $(OSINC)\wincon.h \ + $(OSINC)\windef.h $(OSINC)\windows.h $(OSINC)\winerror.h \ + $(OSINC)\wingdi.h $(OSINC)\winnetwk.h $(OSINC)\winnls.h \ + $(OSINC)\winnt.h $(OSINC)\winperf.h $(OSINC)\winreg.h \ + $(OSINC)\winsock.h $(OSINC)\winspool.h $(OSINC)\winsvc.h \ + $(OSINC)\winuser.h $(OSINC)\winver.h .\busy.h .\common.h .\ole2ui.h \ + .\olestd.h .\utility.h + +$(OBJDIR)\common.obj $(OBJDIR)\common.lst: .\common.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\malloc.h $(CRTINC)\ctype.h \ + $(CRTINC)\dos.h $(CRTINC)\excpt.h $(CRTINC)\stdarg.h \ + $(CRTINC)\string.h $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h \ + $(OSINC)\ddeml.h $(OSINC)\dlgs.h $(OSINC)\drivinit.h \ + $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h $(OSINC)\nb30.h \ + $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h \ + $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h \ + $(OSINC)\winbase.h $(OSINC)\wincon.h $(OSINC)\windef.h \ + $(OSINC)\windows.h $(OSINC)\winerror.h $(OSINC)\wingdi.h \ + $(OSINC)\winnetwk.h $(OSINC)\winnls.h $(OSINC)\winnt.h \ + $(OSINC)\winperf.h $(OSINC)\winreg.h $(OSINC)\winsock.h \ + $(OSINC)\winspool.h $(OSINC)\winsvc.h $(OSINC)\winuser.h \ + $(OSINC)\winver.h .\common.h .\ole2ui.h .\olestd.h .\utility.h + +$(OBJDIR)\convert.obj $(OBJDIR)\convert.lst: .\convert.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\stdlib.h $(CRTINC)\ctype.h \ + $(CRTINC)\dos.h $(CRTINC)\excpt.h $(CRTINC)\stdarg.h \ + $(CRTINC)\string.h $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h \ + $(OSINC)\ddeml.h $(OSINC)\dlgs.h $(OSINC)\drivinit.h \ + $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h $(OSINC)\nb30.h \ + $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h \ + $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h \ + $(OSINC)\winbase.h $(OSINC)\wincon.h $(OSINC)\windef.h \ + $(OSINC)\windows.h $(OSINC)\winerror.h $(OSINC)\wingdi.h \ + $(OSINC)\winnetwk.h $(OSINC)\winnls.h $(OSINC)\winnt.h \ + $(OSINC)\winperf.h $(OSINC)\winreg.h $(OSINC)\winsock.h \ + $(OSINC)\winspool.h $(OSINC)\winsvc.h $(OSINC)\winuser.h \ + $(OSINC)\winver.h .\convert.h .\geticon.h .\regdb.h .\common.h \ + .\ole2ui.h .\olestd.h .\utility.h + +$(OBJDIR)\dballoc.obj $(OBJDIR)\dballoc.lst: .\dballoc.cpp \ + $(CAIROLE)\h\export\ole2.h $(CAIROLE)\h\export\coguid.h \ + $(CAIROLE)\h\export\compobj.h $(CAIROLE)\h\export\dvobj.h \ + $(CAIROLE)\h\export\initguid.h $(CAIROLE)\h\export\moniker.h \ + $(CAIROLE)\h\export\ole2.h $(CAIROLE)\h\export\oleguid.h \ + $(CAIROLE)\h\export\scode.h $(CAIROLE)\h\export\storage.h \ + $(CRTINC)\limits.h $(CRTINC)\stdio.h $(CRTINC)\ctype.h \ + $(CRTINC)\excpt.h $(CRTINC)\malloc.h $(CRTINC)\stdarg.h \ + $(CRTINC)\stdlib.h $(CRTINC)\string.h $(OSINC)\cderr.h \ + $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h $(OSINC)\dlgs.h \ + $(OSINC)\drivinit.h $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h \ + $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h \ + $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h \ + $(OSINC)\shellapi.h $(OSINC)\winbase.h $(OSINC)\wincon.h \ + $(OSINC)\windef.h $(OSINC)\windows.h $(OSINC)\winerror.h \ + $(OSINC)\wingdi.h $(OSINC)\winnetwk.h $(OSINC)\winnls.h \ + $(OSINC)\winnt.h $(OSINC)\winperf.h $(OSINC)\winreg.h \ + $(OSINC)\winsock.h $(OSINC)\winspool.h $(OSINC)\winsvc.h \ + $(OSINC)\winuser.h $(OSINC)\winver.h .\dballoc.h + +$(OBJDIR)\dbgutil.obj $(OBJDIR)\dbgutil.lst: .\dbgutil.c \ + $(CAIROLE)\h\export\ole2.h $(CAIROLE)\h\export\coguid.h \ + $(CAIROLE)\h\export\compobj.h $(CAIROLE)\h\export\dvobj.h \ + $(CAIROLE)\h\export\initguid.h $(CAIROLE)\h\export\moniker.h \ + $(CAIROLE)\h\export\ole2.h $(CAIROLE)\h\export\oleguid.h \ + $(CAIROLE)\h\export\scode.h $(CAIROLE)\h\export\storage.h \ + $(CRTINC)\ctype.h $(CRTINC)\dos.h $(CRTINC)\excpt.h \ + $(CRTINC)\stdarg.h $(CRTINC)\string.h $(OSINC)\shellapi.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\ole2ui.h \ + .\olestd.h + +$(OBJDIR)\dllfuncs.obj $(OBJDIR)\dllfuncs.lst: .\dllfuncs.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\uiclass.h \ + .\common.h .\ole2ui.h .\olestd.h + +$(OBJDIR)\drawicon.obj $(OBJDIR)\drawicon.lst: .\drawicon.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\common.h \ + .\geticon.h .\ole2ui.h .\olestd.h .\utility.h + +$(OBJDIR)\enumfetc.obj $(OBJDIR)\enumfetc.lst: .\enumfetc.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\enumfetc.h \ + .\ole2ui.h .\olestd.h + +$(OBJDIR)\enumstat.obj $(OBJDIR)\enumstat.lst: .\enumstat.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\ole2ui.h \ + .\olestd.h + +$(OBJDIR)\geticon.obj $(OBJDIR)\geticon.lst: .\geticon.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\memory.h $(CRTINC)\ctype.h \ + $(CRTINC)\dos.h $(CRTINC)\excpt.h $(CRTINC)\stdarg.h \ + $(CRTINC)\stdlib.h $(CRTINC)\string.h $(OSINC)\cderr.h \ + $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h $(OSINC)\dlgs.h \ + $(OSINC)\drivinit.h $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h \ + $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h \ + $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h \ + $(OSINC)\shellapi.h $(OSINC)\winbase.h $(OSINC)\wincon.h \ + $(OSINC)\windef.h $(OSINC)\windows.h $(OSINC)\winerror.h \ + $(OSINC)\wingdi.h $(OSINC)\winnetwk.h $(OSINC)\winnls.h \ + $(OSINC)\winnt.h $(OSINC)\winperf.h $(OSINC)\winreg.h \ + $(OSINC)\winsock.h $(OSINC)\winspool.h $(OSINC)\winsvc.h \ + $(OSINC)\winuser.h $(OSINC)\winver.h .\common.h .\ole2ui.h \ + .\olestd.h .\utility.h + +$(OBJDIR)\hatch.obj $(OBJDIR)\hatch.lst: .\hatch.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\ole2ui.h \ + .\olestd.h + +$(OBJDIR)\icon.obj $(OBJDIR)\icon.lst: .\icon.c $(CAIROLE)\h\export\coguid.h \ + $(CAIROLE)\h\export\compobj.h $(CAIROLE)\h\export\dvobj.h \ + $(CAIROLE)\h\export\initguid.h $(CAIROLE)\h\export\moniker.h \ + $(CAIROLE)\h\export\ole2.h $(CAIROLE)\h\export\oleguid.h \ + $(CAIROLE)\h\export\scode.h $(CAIROLE)\h\export\storage.h \ + $(CRTINC)\ctype.h $(CRTINC)\dos.h $(CRTINC)\excpt.h \ + $(CRTINC)\stdarg.h $(CRTINC)\string.h $(OSINC)\cderr.h \ + $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h $(OSINC)\dlgs.h \ + $(OSINC)\drivinit.h $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h \ + $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h \ + $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h \ + $(OSINC)\shellapi.h $(OSINC)\winbase.h $(OSINC)\wincon.h \ + $(OSINC)\windef.h $(OSINC)\windows.h $(OSINC)\winerror.h \ + $(OSINC)\wingdi.h $(OSINC)\winnetwk.h $(OSINC)\winnls.h \ + $(OSINC)\winnt.h $(OSINC)\winperf.h $(OSINC)\winreg.h \ + $(OSINC)\winsock.h $(OSINC)\winspool.h $(OSINC)\winsvc.h \ + $(OSINC)\winuser.h $(OSINC)\winver.h .\icon.h .\common.h .\geticon.h \ + .\ole2ui.h .\olestd.h .\utility.h + +$(OBJDIR)\iconbox.obj $(OBJDIR)\iconbox.lst: .\iconbox.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\iconbox.h \ + .\ole2ui.h .\olestd.h + +$(OBJDIR)\insobj.obj $(OBJDIR)\insobj.lst: .\insobj.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\direct.h $(CRTINC)\ctype.h \ + $(CRTINC)\dos.h $(CRTINC)\excpt.h $(CRTINC)\malloc.h \ + $(CRTINC)\memory.h $(CRTINC)\stdarg.h $(CRTINC)\stdlib.h \ + $(CRTINC)\string.h $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h \ + $(OSINC)\ddeml.h $(OSINC)\dlgs.h $(OSINC)\drivinit.h \ + $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h $(OSINC)\nb30.h \ + $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h \ + $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h \ + $(OSINC)\winbase.h $(OSINC)\wincon.h $(OSINC)\windef.h \ + $(OSINC)\windows.h $(OSINC)\winerror.h $(OSINC)\wingdi.h \ + $(OSINC)\winnetwk.h $(OSINC)\winnls.h $(OSINC)\winnt.h \ + $(OSINC)\winperf.h $(OSINC)\winreg.h $(OSINC)\winsock.h \ + $(OSINC)\winspool.h $(OSINC)\winsvc.h $(OSINC)\winuser.h \ + $(OSINC)\winver.h .\insobj.h .\resimage.h .\common.h .\geticon.h \ + .\icon.h .\iconbox.h .\ole2ui.h .\olestd.h .\utility.h + +$(OBJDIR)\links.obj $(OBJDIR)\links.lst: .\links.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\stdlib.h \ + $(CRTINC)\string.h $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h \ + $(OSINC)\ddeml.h $(OSINC)\dlgs.h $(OSINC)\drivinit.h \ + $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h $(OSINC)\nb30.h \ + $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h \ + $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h \ + $(OSINC)\winbase.h $(OSINC)\wincon.h $(OSINC)\windef.h \ + $(OSINC)\windows.h $(OSINC)\winerror.h $(OSINC)\wingdi.h \ + $(OSINC)\winnetwk.h $(OSINC)\winnls.h $(OSINC)\winnt.h \ + $(OSINC)\winperf.h $(OSINC)\winreg.h $(OSINC)\winsock.h \ + $(OSINC)\winspool.h $(OSINC)\winsvc.h $(OSINC)\winuser.h \ + $(OSINC)\winver.h .\edlinks.h .\common.h .\ole2ui.h .\olestd.h \ + .\utility.h + +$(OBJDIR)\msgfiltr.obj $(OBJDIR)\msgfiltr.lst: .\msgfiltr.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\msgfiltr.h \ + .\ole2ui.h .\olestd.h + +$(OBJDIR)\objfdbk.obj $(OBJDIR)\objfdbk.lst: .\objfdbk.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\ole2ui.h \ + .\olestd.h + +$(OBJDIR)\ole2ui.obj $(OBJDIR)\ole2ui.lst: .\ole2ui.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\common.h \ + .\iconbox.h .\ole2ui.h .\olestd.h .\resimage.h .\utility.h + +$(OBJDIR)\olestd.obj $(OBJDIR)\olestd.lst: .\olestd.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\stdlib.h \ + $(CRTINC)\string.h $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h \ + $(OSINC)\ddeml.h $(OSINC)\dlgs.h $(OSINC)\drivinit.h \ + $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h $(OSINC)\nb30.h \ + $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h \ + $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h \ + $(OSINC)\winbase.h $(OSINC)\wincon.h $(OSINC)\windef.h \ + $(OSINC)\windows.h $(OSINC)\winerror.h $(OSINC)\wingdi.h \ + $(OSINC)\winnetwk.h $(OSINC)\winnls.h $(OSINC)\winnt.h \ + $(OSINC)\winperf.h $(OSINC)\winreg.h $(OSINC)\winsock.h \ + $(OSINC)\winspool.h $(OSINC)\winsvc.h $(OSINC)\winuser.h \ + $(OSINC)\winver.h .\common.h .\geticon.h .\ole2ui.h .\olestd.h \ + .\regdb.h + +$(OBJDIR)\oleutl.obj $(OBJDIR)\oleutl.lst: .\oleutl.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\stdlib.h \ + $(CRTINC)\string.h $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h \ + $(OSINC)\ddeml.h $(OSINC)\dlgs.h $(OSINC)\drivinit.h \ + $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h $(OSINC)\nb30.h \ + $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h \ + $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h \ + $(OSINC)\winbase.h $(OSINC)\wincon.h $(OSINC)\windef.h \ + $(OSINC)\windows.h $(OSINC)\winerror.h $(OSINC)\wingdi.h \ + $(OSINC)\winnetwk.h $(OSINC)\winnls.h $(OSINC)\winnt.h \ + $(OSINC)\winperf.h $(OSINC)\winreg.h $(OSINC)\winsock.h \ + $(OSINC)\winspool.h $(OSINC)\winsvc.h $(OSINC)\winuser.h \ + $(OSINC)\winver.h .\ole2ui.h .\olestd.h + +$(OBJDIR)\pastespl.obj $(OBJDIR)\pastespl.lst: .\pastespl.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\stdlib.h \ + $(CRTINC)\string.h $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h \ + $(OSINC)\ddeml.h $(OSINC)\dlgs.h $(OSINC)\drivinit.h \ + $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h $(OSINC)\nb30.h \ + $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h \ + $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h \ + $(OSINC)\winbase.h $(OSINC)\wincon.h $(OSINC)\windef.h \ + $(OSINC)\windows.h $(OSINC)\winerror.h $(OSINC)\wingdi.h \ + $(OSINC)\winnetwk.h $(OSINC)\winnls.h $(OSINC)\winnt.h \ + $(OSINC)\winperf.h $(OSINC)\winreg.h $(OSINC)\winsock.h \ + $(OSINC)\winspool.h $(OSINC)\winsvc.h $(OSINC)\winuser.h \ + $(OSINC)\winver.h .\pastespl.h .\common.h .\geticon.h .\icon.h \ + .\iconbox.h .\ole2ui.h .\olestd.h .\regdb.h .\resimage.h \ + .\utility.h + +$(OBJDIR)\precomp.obj $(OBJDIR)\precomp.lst: .\precomp.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\ole2ui.h \ + .\olestd.h + +$(OBJDIR)\regdb.obj $(OBJDIR)\regdb.lst: .\regdb.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\common.h \ + .\ole2ui.h .\olestd.h + +$(OBJDIR)\resimage.obj $(OBJDIR)\resimage.lst: .\resimage.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\ole2ui.h \ + .\olestd.h .\resimage.h + +$(OBJDIR)\stdpal.obj $(OBJDIR)\stdpal.lst: .\stdpal.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\excpt.h \ + $(CRTINC)\stdarg.h $(CRTINC)\string.h $(OSINC)\cderr.h \ + $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h $(OSINC)\dlgs.h \ + $(OSINC)\drivinit.h $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h \ + $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h \ + $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h \ + $(OSINC)\shellapi.h $(OSINC)\winbase.h $(OSINC)\wincon.h \ + $(OSINC)\windef.h $(OSINC)\windows.h $(OSINC)\winerror.h \ + $(OSINC)\wingdi.h $(OSINC)\winnetwk.h $(OSINC)\winnls.h \ + $(OSINC)\winnt.h $(OSINC)\winperf.h $(OSINC)\winreg.h \ + $(OSINC)\winsock.h $(OSINC)\winspool.h $(OSINC)\winsvc.h \ + $(OSINC)\winuser.h $(OSINC)\winver.h .\stdpal.h + +$(OBJDIR)\suminfo.obj $(OBJDIR)\suminfo.lst: .\suminfo.cpp \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h \ + .\..\release\variant.h .\suminfo.h .\wn_dos.h .\ole2ui.h .\olestd.h + +$(OBJDIR)\targtdev.obj $(OBJDIR)\targtdev.lst: .\targtdev.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\ole2ui.h \ + .\olestd.h + +$(OBJDIR)\template.obj $(OBJDIR)\template.lst: .\template.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\stdarg.h $(CRTINC)\string.h \ + $(OSINC)\cderr.h $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h \ + $(OSINC)\dlgs.h $(OSINC)\drivinit.h $(OSINC)\lzexpand.h \ + $(OSINC)\mmsystem.h $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h \ + $(OSINC)\rpcdce.h $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h \ + $(OSINC)\rpcnterr.h $(OSINC)\shellapi.h $(OSINC)\winbase.h \ + $(OSINC)\wincon.h $(OSINC)\windef.h $(OSINC)\windows.h \ + $(OSINC)\winerror.h $(OSINC)\wingdi.h $(OSINC)\winnetwk.h \ + $(OSINC)\winnls.h $(OSINC)\winnt.h $(OSINC)\winperf.h \ + $(OSINC)\winreg.h $(OSINC)\winsock.h $(OSINC)\winspool.h \ + $(OSINC)\winsvc.h $(OSINC)\winuser.h $(OSINC)\winver.h .\common.h \ + .\ole2ui.h .\olestd.h + +$(OBJDIR)\utility.obj $(OBJDIR)\utility.lst: .\utility.c \ + $(CAIROLE)\h\export\coguid.h $(CAIROLE)\h\export\compobj.h \ + $(CAIROLE)\h\export\dvobj.h $(CAIROLE)\h\export\initguid.h \ + $(CAIROLE)\h\export\moniker.h $(CAIROLE)\h\export\ole2.h \ + $(CAIROLE)\h\export\oleguid.h $(CAIROLE)\h\export\scode.h \ + $(CAIROLE)\h\export\storage.h $(CRTINC)\ctype.h $(CRTINC)\dos.h \ + $(CRTINC)\excpt.h $(CRTINC)\memory.h $(CRTINC)\stdarg.h \ + $(CRTINC)\stdlib.h $(CRTINC)\string.h $(OSINC)\cderr.h \ + $(OSINC)\commdlg.h $(OSINC)\dde.h $(OSINC)\ddeml.h $(OSINC)\dlgs.h \ + $(OSINC)\drivinit.h $(OSINC)\lzexpand.h $(OSINC)\mmsystem.h \ + $(OSINC)\nb30.h $(OSINC)\ole.h $(OSINC)\rpc.h $(OSINC)\rpcdce.h \ + $(OSINC)\rpcdcep.h $(OSINC)\rpcnsi.h $(OSINC)\rpcnterr.h \ + $(OSINC)\shellapi.h $(OSINC)\winbase.h $(OSINC)\wincon.h \ + $(OSINC)\windef.h $(OSINC)\windows.h $(OSINC)\winerror.h \ + $(OSINC)\wingdi.h $(OSINC)\winnetwk.h $(OSINC)\winnls.h \ + $(OSINC)\winnt.h $(OSINC)\winperf.h $(OSINC)\winreg.h \ + $(OSINC)\winsock.h $(OSINC)\winspool.h $(OSINC)\winsvc.h \ + $(OSINC)\winuser.h $(OSINC)\winver.h .\common.h .\geticon.h \ + .\ole2ui.h .\olestd.h .\utility.h + diff --git a/private/oleutest/letest/ole2ui/dirs b/private/oleutest/letest/ole2ui/dirs new file mode 100644 index 000000000..90a66698e --- /dev/null +++ b/private/oleutest/letest/ole2ui/dirs @@ -0,0 +1,3 @@ +DIRS= +OPTIONAL_DIRS= daytona \ + diff --git a/private/oleutest/letest/ole2ui/dllentry.c b/private/oleutest/letest/ole2ui/dllentry.c new file mode 100644 index 000000000..1cd1159e4 --- /dev/null +++ b/private/oleutest/letest/ole2ui/dllentry.c @@ -0,0 +1,55 @@ +//+------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1991 - 1992. +// +// File: dllentry.c +// +// Contents: Dll Entry point code. Calls the appropriate run-time +// init/term code and then defers to LibMain for further +// processing. +// +// Classes: <none> +// +// Functions: DllEntryPoint - Called by loader +// +// History: 10-May-92 BryanT Created +// 22-Jul-92 BryanT Switch to calling _cexit/_mtdeletelocks +// on cleanup. +// 06-Oct-92 BryanT Call RegisterWithCommnot on entry +// and DeRegisterWithCommnot on exit. +// This should fix the heap dump code. +// 27-Dec-93 AlexT Post 543 builds don't need special code. +// +//-------------------------------------------------------------------- + +#define USE_CRTDLL +#include <windows.h> + +BOOL WINAPI _CRT_INIT (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); + +BOOL DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); + +BOOL _CRTAPI1 LibMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); + +BOOL DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +{ + BOOL fRc = FALSE; + + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + _CRT_INIT(hDll, dwReason, lpReserved); + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + fRc = LibMain (hDll, dwReason, lpReserved); + break; + + case DLL_PROCESS_DETACH: + fRc = LibMain (hDll, dwReason, lpReserved); + _CRT_INIT(hDll, dwReason, lpReserved); + } + + return(fRc); +} diff --git a/private/oleutest/letest/ole2ui/dllfuncs.c b/private/oleutest/letest/ole2ui/dllfuncs.c new file mode 100644 index 000000000..283ca9d67 --- /dev/null +++ b/private/oleutest/letest/ole2ui/dllfuncs.c @@ -0,0 +1,110 @@ +/* + * DLLFUNCS.C + * + * 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 + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "uiclass.h" +#include "common.h" + +OLEDBGDATA_MAIN("ole2u32a") + + +/* + * LibMain + * + * Purpose: + * DLL-specific entry point called from LibEntry. Initializes + * the DLL's heap and registers the GizmoBar GizmoBar. + * + * Parameters: + * hInst HINSTANCE instance of the DLL. + * wDataSeg WORD segment selector of the DLL's data segment. + * wHeapSize WORD byte count of the heap. + * lpCmdLine LPSTR to command line used to start the module. + * + * Return Value: + * HANDLE Instance handle of the DLL. + * + */ + +#ifdef WIN32 + +BOOL _cdecl LibMain( + HINSTANCE hDll, + DWORD dwReason, + LPVOID lpvReserved) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + // Initialize OLE UI libraries. If you're linking with the static + // LIB version of this library, you need to make the below call in + // your application (because this LibMain won't be executed). + OleUIInitialize(hDll, (HINSTANCE)0, SZCLASSICONBOX, SZCLASSRESULTIMAGE); + } + else if (dwReason == DLL_PROCESS_DETACH) + { + OleUIUnInitialize(); + } + + return TRUE; +} + +#else + +int FAR PASCAL LibMain(HINSTANCE hInst, WORD wDataSeg + , WORD cbHeapSize, LPTSTR lpCmdLine) + { + OleDbgOut2(TEXT("LibMain: OLE2UI.DLL loaded\r\n")); + + // Initialize OLE UI libraries. If you're linking with the static LIB version + // of this library, you need to make the below call in your application (because + // this LibMain won't be executed). + + // The symbols SZCLASSICONBOX and SZCLASSRESULTIMAGE are both defined + // in uiclass.h + + OleUIInitialize(hInst, (HINSTANCE)0, TEXT(SZCLASSICONBOX), TEXT(SZCLASSRESULTIMAGE)); + + //All done... + if (0!=cbHeapSize) + UnlockData(0); + + return (int)hInst; + } + +#endif + +/* + * WEP + * + * Purpose: + * Required DLL Exit function. + * + * Parameters: + * bSystemExit BOOL indicating if the system is being shut + * down or the DLL has just been unloaded. + * + * Return Value: + * void + * + */ +int CALLBACK EXPORT WEP(int bSystemExit) +{ + OleUIUnInitialize(); + return 0; +} + + + + + + diff --git a/private/oleutest/letest/ole2ui/drawicon.c b/private/oleutest/letest/ole2ui/drawicon.c new file mode 100644 index 000000000..06cdd3ab7 --- /dev/null +++ b/private/oleutest/letest/ole2ui/drawicon.c @@ -0,0 +1,729 @@ +/* + * DRAWICON.C + * + * 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 + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "common.h" +#include "utility.h" +#include "geticon.h" + +/* + * Strings for metafile comments. KEEP THESE IN SYNC WITH THE + * STRINGS IN GETICON.C. + */ + +static TCHAR szIconOnly[]=TEXT("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 + * OleUIMetafilePictFromIconAndLabel + * + * Return Value: + * None + */ + +STDAPI_(void) OleUIMetafilePictIconFree(HGLOBAL hMetaPict) + { + LPMETAFILEPICT pMF; + + if (NULL==hMetaPict) + return; + + pMF=(LPMETAFILEPICT)GlobalLock(hMetaPict); + + if (NULL!=pMF) + { + if (NULL!=pMF->hMF) + DeleteMetaFile(pMF->hMF); + } + + GlobalUnlock(hMetaPict); + GlobalFree(hMetaPict); + return; + } + + + + + + + + +/* + * OleUIMetafilePictIconDraw + * + * Purpose: + * Draws the metafile from OleUIMetafilePictFromIconAndLabel, 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 + * OleUIMetafilePictFromIconAndLabel + * 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, LPRECT pRect, HGLOBAL hMetaPict + , BOOL fIconOnly) + { + LPMETAFILEPICT pMF; + DRAWINFO di; + int cx, cy; + SIZE size; + POINT point; + + if (NULL==hMetaPict) + return FALSE; + + pMF=GlobalLock(hMetaPict); + + if (NULL==pMF) + return FALSE; + + di.Rect = *pRect; + di.fIconOnly = fIconOnly; + + //Transform to back to pixels + cx=XformWidthInHimetricToPixels(hDC, pMF->xExt); + cy=XformHeightInHimetricToPixels(hDC, pMF->yExt); + + SaveDC(hDC); + + SetMapMode(hDC, pMF->mm); + SetViewportOrgEx(hDC, (pRect->right - cx) / 2, 0, &point); + + SetViewportExtEx(hDC, min ((pRect->right - cx) / 2 + cx, cx), cy, &size); + + if (fIconOnly) + { + // Since we've used the __export keyword on the + // EnumMetafileIconDraw proc, we do not need to use + // MakeProcInstance + EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileIconDraw + , (LPARAM)(LPDRAWINFO)&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 EXPORT 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==lstrcmpi(szIconOnly, (LPTSTR)&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) + { + LPMETAFILEPICT pMF; + LABELEXTRACT le; + HDC hDC; + + /* + * 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. + */ + + if (NULL==hMetaPict || NULL==lpszLabel || 0==cchLabel) + return FALSE; + + pMF=GlobalLock(hMetaPict); + + if (NULL==pMF) + return FALSE; + + 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=GetDC(NULL); + + // Since we've used the EXPORT keyword on the + // EnumMetafileExtractLabel proc, we do not need to use + // MakeProcInstance + + 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 EXPORT 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==lstrcmpi(szIconOnly, (LPTSTR)&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) + { + UINT cchMax; + LPTSTR lpszTemp; + + /* + * 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. + * + */ + + cchMax=min(pLE->u.cch - pLE->Index, (UINT)pMFR->rdParm[2]); + lpszTemp = pLE->lpsz + pLE->Index; + + lstrcpyn(lpszTemp, (LPTSTR)&(pMFR->rdParm[8]), cchMax + 1); +// lstrcpyn(lpszTemp, (LPTSTR)&(pMFR->rdParm[4]), cchMax + 1); + + 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) + { + LPMETAFILEPICT pMF; + HDC hDC; + ICONEXTRACT ie; + + /* + * 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. + */ + + if (NULL==hMetaPict) + return NULL; + + pMF=GlobalLock(hMetaPict); + + if (NULL==pMF) + return FALSE; + + //Use a screen DC so we have something valid to pass in. + hDC=GetDC(NULL); + ie.fAND=TRUE; + + // We get information back in the ICONEXTRACT structure. + // (Since we've used the EXPORT keyword on the + // EnumMetafileExtractLabel proc, we do not need to use + // MakeProcInstance) + EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractIcon, (LONG)(LPICONEXTRACT)&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 EXPORT EnumMetafileExtractIcon(HDC hDC, HANDLETABLE FAR *phTable + , METARECORD FAR *pMFR, int cObj, LPICONEXTRACT pIE) + { + LPBITMAPINFO lpBI; + LPBITMAPINFOHEADER lpBH; + LPBYTE lpbSrc; + LPBYTE lpbDst; + UINT uWidth, uHeight; + DWORD cb; + HGLOBAL hMem; + BITMAP bm; + HBITMAP hBmp; + int cxIcon, cyIcon; + + + //Continue enumeration if we don't see the records we want. + if (META_DIBBITBLT!=pMFR->rdFunction && META_DIBSTRETCHBLT!=pMFR->rdFunction) + return 1; + + /* + * 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]); + } + + lpBH=(LPBITMAPINFOHEADER)&(lpBI->bmiHeader); + + //Pointer to the bits which follows the BITMAPINFO structure. + 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); + } + + + /* + * 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. + */ + + //Use CreateBitmap for ANY monochrome bitmaps + if (pIE->fAND || 1==lpBH->biBitCount || lpBH->biBitCount > 8) + hBmp=CreateBitmap((UINT)lpBH->biWidth, (UINT)lpBH->biHeight, 1, 1, NULL); + else if (lpBH->biBitCount <= 8) + hBmp=CreateCompatibleBitmap(hDC, (UINT)lpBH->biWidth, (UINT)lpBH->biHeight); + + if (!hBmp || !SetDIBits(hDC, hBmp, 0, (UINT)lpBH->biHeight, (LPVOID)lpbSrc, lpBI, DIB_RGB_COLORS)) + { + if (!pIE->fAND) + GlobalFree(pIE->hMemAND); + + DeleteObject(hBmp); + return 0; + } + + //Allocate memory and get the DDBits into it. + GetObject(hBmp, sizeof(bm), &bm); + + cb=bm.bmHeight*bm.bmWidthBytes * bm.bmPlanes; + +// if (cb % 4 != 0) // dword align +// cb += 4 - (cb % 4); + + hMem=GlobalAlloc(GHND, cb); + + if (NULL==hMem) + { + if (NULL!=pIE->hMemAND) + GlobalFree(pIE->hMemAND); + + DeleteObject(hBmp); + return 0; + } + + 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. + */ + cxIcon = GetSystemMetrics(SM_CXICON); + cyIcon = GetSystemMetrics(SM_CYICON); + + pIE->hIcon=CreateIcon(ghInst, + uWidth, + uHeight, + (BYTE)bm.bmPlanes, + (BYTE)bm.bmBitsPixel, + (LPVOID)lpbSrc, + (LPVOID)lpbDst); + + GlobalUnlock(pIE->hMemAND); + GlobalFree(pIE->hMemAND); + GlobalFree(hMem); + + //We're done so we can stop. + return 0; + } + } + + + + + +/* + * OleUIMetafilePictExtractIconSource + * + * Purpose: + * Retrieves the filename and index of the icon source from a metafile + * created with OleUIMetafilePictFromIconAndLabel. + * + * Parameters: + * hMetaPict HGLOBAL to the METAFILEPICT containing the metafile. + * lpszSource LPTSTR in which to store the source filename. This + * buffer should be OLEUI_CCHPATHMAX 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) + { + LPMETAFILEPICT pMF; + LABELEXTRACT le; + HDC hDC; + + /* + * 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. + */ + + if (NULL==hMetaPict || NULL==lpszSource || NULL==piIcon) + return FALSE; + + pMF=GlobalLock(hMetaPict); + + if (NULL==pMF) + return FALSE; + + 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=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 EXPORT EnumMetafileExtractIconSource(HDC hDC, HANDLETABLE FAR *phTable + , METARECORD FAR *pMFR, int cObj, LPLABELEXTRACT pLE) + { + LPTSTR psz; + + /* + * 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==lstrcmpi(szIconOnly, (LPTSTR)&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]) + { + LSTRCPYN(pLE->lpsz, (LPTSTR)&pMFR->rdParm[2], OLEUI_CCHPATHMAX); + pLE->lpsz[OLEUI_CCHPATHMAX-1] = TEXT('\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. + */ + psz=(LPTSTR)&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/oleutest/letest/ole2ui/edlinks.h b/private/oleutest/letest/ole2ui/edlinks.h new file mode 100644 index 000000000..db721f47f --- /dev/null +++ b/private/oleutest/letest/ole2ui/edlinks.h @@ -0,0 +1,135 @@ +/* + * EDLINKS.H + * + * Internal definitions, structures, and function prototypes for the + * OLE 2.0 UI Edit Links dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + + +#ifndef _LINKS_H_ +#define _LINKS_H_ + +//INTERNAL INFORMATION STARTS HERE +#define OLEUI_SZMAX 255 +#define LINKTYPELEN 9 +#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; + + /* + * 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. + */ + +typedef struct tagEDITLINKS + { + //Keep this item first as the Standard* functions depend on it here. + + LPOLEUIEDITLINKS lpOEL; //Original structure passed. + + BOOL fClose; // Does the button read cancel (0) or + // close (1)? + int *rgIndex; // Array to hold indexes of selected items + int cSelItems; // Number of selected items + 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) +} EDITLINKS, *PEDITLINKS, FAR *LPEDITLINKS; + +// Data to and from the ChangeSource dialog hook +typedef struct tagOLEUICHANGESOURCEHOOKDATA +{ + //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 OLEUIINSERTOBJECT. All are IN-OUT unless otherwise spec. + LPLINKINFO lpLI; // IN: ptr to LinkInfo entry + LPEDITLINKS lpEL; // IN: ptr to EditLinks dialog struct + BOOL fValidLink; // OUT: was link source validated + LPTSTR lpszFrom; // OUT: string containing prefix of + // source changed from + LPTSTR lpszTo; // OUT: string containing prefix of + // source changed to +} OLEUICHANGESOURCEHOOKDATA, *POLEUICHANGESOURCEHOOKDATA, + FAR *LPOLEUICHANGESOURCEHOOKDATA; + + +// Data to and from the ChangeSource dialog hook +typedef struct tagCHANGESOURCEHOOKDATA +{ + LPOLEUICHANGESOURCEHOOKDATA lpOCshData; //Original structure passed. + LPOPENFILENAME lpOfn; + BOOL fValidLink; + int nFileLength; + int nEditLength; + TCHAR szFileName[OLEUI_CCHPATHMAX]; + TCHAR szItemName[OLEUI_CCHPATHMAX]; + BOOL bFileNameStored; + BOOL bItemNameStored; + TCHAR szEdit[OLEUI_CCHPATHMAX]; + LPTSTR lpszFrom; // string containing prefix of source + // changed from + LPTSTR lpszTo; // string containing prefix of source + // source changed to +} CHANGESOURCEHOOKDATA, *PCHANGESOURCEHOOKDATA, FAR *LPCHANGESOURCEHOOKDATA; + + +//Internal function prototypes +//LINKS.C +BOOL CALLBACK EXPORT 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*); +BOOL WINAPI ChangeSource(HWND hWndOwner, + LPTSTR lpszFile, + UINT cchFile, + UINT iFilterString, + COMMDLGHOOKPROC lpfnBrowseHook, + LPOLEUICHANGESOURCEHOOKDATA lpLbhData); +UINT CALLBACK EXPORT ChangeSourceHook(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +VOID InitControls(HWND hDlg, LPEDITLINKS lpEL); +VOID UpdateLinkLBItem(HWND hListBox, int nIndex, LPEDITLINKS lpEL, BOOL bSelect); +VOID DiffPrefix(LPCTSTR lpsz1, LPCTSTR lpsz2, TCHAR FAR* FAR* lplpszPrefix1, TCHAR FAR* FAR* lplpszPrefix2); +int PopupMessage(HWND hwndParent, UINT idTitle, UINT idMessage, UINT fuStyle); +VOID ChangeAllLinks(HWND hLIstBox, LPOLEUILINKCONTAINER lpOleUILinkCntr, LPTSTR lpszFrom, LPTSTR lpszTo); +int LoadLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr); +VOID RefreshLinkLB(HWND hListBox, LPOLEUILINKCONTAINER lpOleUILinkCntr); +#endif // __LINKS_H__ diff --git a/private/oleutest/letest/ole2ui/egares.bmp b/private/oleutest/letest/ole2ui/egares.bmp Binary files differnew file mode 100644 index 000000000..e9dbb065a --- /dev/null +++ b/private/oleutest/letest/ole2ui/egares.bmp diff --git a/private/oleutest/letest/ole2ui/enumfetc.c b/private/oleutest/letest/ole2ui/enumfetc.c new file mode 100644 index 000000000..15a6b3a90 --- /dev/null +++ b/private/oleutest/letest/ole2ui/enumfetc.c @@ -0,0 +1,308 @@ +/************************************************************************* +** +** OLE 2 Utility Code +** +** enumfetc.c +** +** This file contains a standard implementation of IEnumFormatEtc +** interface. +** This file is part of the OLE 2.0 User Interface support library. +** +** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved +** +*************************************************************************/ + +#define STRICT 1 +#include "ole2ui.h" +#include "enumfetc.h" + + +typedef struct tagOleStdEnumFmtEtc { + IEnumFORMATETCVtbl FAR* lpVtbl; + ULONG m_dwRefs; /* referance count */ + ULONG m_nIndex; /* current index in list */ + ULONG m_nCount; /* how many items in list */ + LPFORMATETC m_lpEtc; /* list of formatetc */ +} OLESTDENUMFMTETC, FAR* LPOLESTDENUMFMTETC; + +VOID OleStdEnumFmtEtc_Destroy(LPOLESTDENUMFMTETC pEtc); + +STDMETHODIMP OleStdEnumFmtEtc_QueryInterface( + LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* ppobj); +STDMETHODIMP_(ULONG) OleStdEnumFmtEtc_AddRef(LPENUMFORMATETC lpThis); +STDMETHODIMP_(ULONG) OleStdEnumFmtEtc_Release(LPENUMFORMATETC lpThis); +STDMETHODIMP OleStdEnumFmtEtc_Next(LPENUMFORMATETC lpThis, ULONG celt, + LPFORMATETC rgelt, ULONG FAR* pceltFetched); +STDMETHODIMP OleStdEnumFmtEtc_Skip(LPENUMFORMATETC lpThis, ULONG celt); +STDMETHODIMP OleStdEnumFmtEtc_Reset(LPENUMFORMATETC lpThis); +STDMETHODIMP OleStdEnumFmtEtc_Clone(LPENUMFORMATETC lpThis, + LPENUMFORMATETC FAR* ppenum); + +static IEnumFORMATETCVtbl g_EnumFORMATETCVtbl = { + OleStdEnumFmtEtc_QueryInterface, + OleStdEnumFmtEtc_AddRef, + OleStdEnumFmtEtc_Release, + OleStdEnumFmtEtc_Next, + OleStdEnumFmtEtc_Skip, + OleStdEnumFmtEtc_Reset, + OleStdEnumFmtEtc_Clone, +}; + +///////////////////////////////////////////////////////////////////////////// + + +STDAPI_(LPENUMFORMATETC) + OleStdEnumFmtEtc_Create(ULONG nCount, LPFORMATETC lpEtc) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPMALLOC lpMalloc=NULL; + LPOLESTDENUMFMTETC lpEF=NULL; + DWORD dwSize; + WORD i; + HRESULT hRes; + + hRes = CoGetMalloc(MEMCTX_TASK, &lpMalloc); + if (hRes != NOERROR) { + return NULL; + } + + lpEF = (LPOLESTDENUMFMTETC)lpMalloc->lpVtbl->Alloc(lpMalloc, + sizeof(OLESTDENUMFMTETC)); + if (lpEF == NULL) { + goto errReturn; + } + + lpEF->lpVtbl = &g_EnumFORMATETCVtbl; + lpEF->m_dwRefs = 1; + lpEF->m_nCount = nCount; + lpEF->m_nIndex = 0; + + dwSize = sizeof(FORMATETC) * lpEF->m_nCount; + + lpEF->m_lpEtc = (LPFORMATETC)lpMalloc->lpVtbl->Alloc(lpMalloc, dwSize); + if (lpEF->m_lpEtc == NULL) + goto errReturn; + + lpMalloc->lpVtbl->Release(lpMalloc); + + for (i=0; i<nCount; i++) { + OleStdCopyFormatEtc( + (LPFORMATETC)&(lpEF->m_lpEtc[i]), (LPFORMATETC)&(lpEtc[i])); + } + + return (LPENUMFORMATETC)lpEF; + +errReturn: + if (lpEF != NULL) + lpMalloc->lpVtbl->Free(lpMalloc, lpEF); + + if (lpMalloc != NULL) + lpMalloc->lpVtbl->Release(lpMalloc); + + return NULL; + +} /* OleStdEnumFmtEtc_Create() + */ + + +VOID + OleStdEnumFmtEtc_Destroy(LPOLESTDENUMFMTETC lpEF) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPMALLOC lpMalloc=NULL; + WORD i; + + if (lpEF != NULL) { + + if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) == NOERROR) { + + /* OLE2NOTE: we MUST free any memory that was allocated for + ** TARGETDEVICES contained within the FORMATETC elements. + */ + for (i=0; i<lpEF->m_nCount; i++) { + OleStdFree(lpEF->m_lpEtc[i].ptd); + } + + if (lpEF->m_lpEtc != NULL) { + lpMalloc->lpVtbl->Free(lpMalloc, lpEF->m_lpEtc); + } + + lpMalloc->lpVtbl->Free(lpMalloc, lpEF); + lpMalloc->lpVtbl->Release(lpMalloc); + } + } +} /* OleStdEnumFmtEtc_Destroy() + */ + + +STDMETHODIMP + OleStdEnumFmtEtc_QueryInterface( + LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* ppobj) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis; + *ppobj = NULL; + + if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IEnumFORMATETC)){ + *ppobj = (LPVOID)lpEF; + } + + if (*ppobj == NULL) return ResultFromScode(E_NOINTERFACE); + else{ + OleStdEnumFmtEtc_AddRef(lpThis); + return NOERROR; + } + +} /* OleStdEnumFmtEtc_QueryInterface() + */ + + +STDMETHODIMP_(ULONG) + OleStdEnumFmtEtc_AddRef(LPENUMFORMATETC lpThis) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis; + return lpEF->m_dwRefs++; + +} /* OleStdEnumFmtEtc_AddRef() + */ + + +STDMETHODIMP_(ULONG) + OleStdEnumFmtEtc_Release(LPENUMFORMATETC lpThis) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis; + DWORD dwRefs = --lpEF->m_dwRefs; + + if (dwRefs == 0) + OleStdEnumFmtEtc_Destroy(lpEF); + + return dwRefs; + +} /* OleStdEnumFmtEtc_Release() + */ + + +STDMETHODIMP + OleStdEnumFmtEtc_Next(LPENUMFORMATETC lpThis, ULONG celt, LPFORMATETC rgelt, + ULONG FAR* pceltFetched) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis; + ULONG i=0; + ULONG nOffset; + + if (rgelt == NULL) { + return ResultFromScode(E_INVALIDARG); + } + + while (i < celt) { + nOffset = lpEF->m_nIndex + i; + + if (nOffset < lpEF->m_nCount) { + OleStdCopyFormatEtc( + (LPFORMATETC)&(rgelt[i]), (LPFORMATETC)&(lpEF->m_lpEtc[nOffset])); + i++; + }else{ + break; + } + } + + lpEF->m_nIndex += (WORD)i; + + if (pceltFetched != NULL) { + *pceltFetched = i; + } + + if (i != celt) { + return ResultFromScode(S_FALSE); + } + + return NOERROR; +} /* OleStdEnumFmtEtc_Next() + */ + + +STDMETHODIMP + OleStdEnumFmtEtc_Skip(LPENUMFORMATETC lpThis, ULONG celt) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis; + ULONG i=0; + ULONG nOffset; + + while (i < celt) { + nOffset = lpEF->m_nIndex + i; + + if (nOffset < lpEF->m_nCount) { + i++; + }else{ + break; + } + } + + lpEF->m_nIndex += (WORD)i; + + if (i != celt) { + return ResultFromScode(S_FALSE); + } + + return NOERROR; +} /* OleStdEnumFmtEtc_Skip() + */ + + +STDMETHODIMP + OleStdEnumFmtEtc_Reset(LPENUMFORMATETC lpThis) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis; + lpEF->m_nIndex = 0; + + return NOERROR; +} /* OleStdEnumFmtEtc_Reset() + */ + + +STDMETHODIMP + OleStdEnumFmtEtc_Clone(LPENUMFORMATETC lpThis, LPENUMFORMATETC FAR* ppenum) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis; + + if (ppenum == NULL) { + return ResultFromScode(E_INVALIDARG); + } + + *ppenum = OleStdEnumFmtEtc_Create(lpEF->m_nCount, lpEF->m_lpEtc); + + // make sure cloned enumerator has same index state as the original + if (*ppenum) { + LPOLESTDENUMFMTETC lpEFClone = (LPOLESTDENUMFMTETC)*ppenum; + lpEFClone->m_nIndex = lpEF->m_nIndex; + return NOERROR; + } else + return ResultFromScode(E_OUTOFMEMORY); + +} /* OleStdEnumFmtEtc_Clone() + */ + diff --git a/private/oleutest/letest/ole2ui/enumfetc.h b/private/oleutest/letest/ole2ui/enumfetc.h new file mode 100644 index 000000000..60b82d151 --- /dev/null +++ b/private/oleutest/letest/ole2ui/enumfetc.h @@ -0,0 +1,13 @@ +// This file is now OBSOLETE (include olestd.h instead) + +/************************************************************************* +** +** OLE 2 Utility Code +** +** enumfetc.c +** +** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved +** +*************************************************************************/ + +// Function prototypes moved to olestd.h diff --git a/private/oleutest/letest/ole2ui/enumstat.c b/private/oleutest/letest/ole2ui/enumstat.c new file mode 100644 index 000000000..17a42048f --- /dev/null +++ b/private/oleutest/letest/ole2ui/enumstat.c @@ -0,0 +1,336 @@ +/************************************************************************* +** +** OLE 2 Utility Code +** +** enumstat.c +** +** This file contains a standard implementation of IEnumStatData +** interface. +** This file is part of the OLE 2.0 User Interface support library. +** +** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved +** +*************************************************************************/ + +#define STRICT 1 +#include "ole2ui.h" + + +typedef struct tagOleStdEnumStatData { + IEnumSTATDATAVtbl FAR* lpVtbl; + ULONG m_dwRefs; /* referance count */ + ULONG m_nIndex; /* current index in list */ + ULONG m_nCount; /* how many items in list */ + LPSTATDATA m_lpStat; /* list of STATDATA */ +} OLESTDENUMSTATDATA, FAR* LPOLESTDENUMSTATDATA; + +VOID OleStdEnumStatData_Destroy(LPOLESTDENUMSTATDATA pStat); + +STDMETHODIMP OleStdEnumStatData_QueryInterface( + LPENUMSTATDATA lpThis, REFIID riid, LPVOID FAR* ppobj); +STDMETHODIMP_(ULONG) OleStdEnumStatData_AddRef(LPENUMSTATDATA lpThis); +STDMETHODIMP_(ULONG) OleStdEnumStatData_Release(LPENUMSTATDATA lpThis); +STDMETHODIMP OleStdEnumStatData_Next(LPENUMSTATDATA lpThis, ULONG celt, + LPSTATDATA rgelt, ULONG FAR* pceltFetched); +STDMETHODIMP OleStdEnumStatData_Skip(LPENUMSTATDATA lpThis, ULONG celt); +STDMETHODIMP OleStdEnumStatData_Reset(LPENUMSTATDATA lpThis); +STDMETHODIMP OleStdEnumStatData_Clone(LPENUMSTATDATA lpThis, + LPENUMSTATDATA FAR* ppenum); + +static IEnumSTATDATAVtbl g_EnumSTATDATAVtbl = { + OleStdEnumStatData_QueryInterface, + OleStdEnumStatData_AddRef, + OleStdEnumStatData_Release, + OleStdEnumStatData_Next, + OleStdEnumStatData_Skip, + OleStdEnumStatData_Reset, + OleStdEnumStatData_Clone, +}; + +///////////////////////////////////////////////////////////////////////////// + +STDAPI_(BOOL) + OleStdCopyStatData(LPSTATDATA pDest, LPSTATDATA pSrc) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + if ((pDest == NULL) || (pSrc == NULL)) { + return FALSE; + } + + if (OleStdCopyFormatEtc(&pDest->formatetc, &pSrc->formatetc) == FALSE) { + return FALSE; + } + + pDest->advf = pSrc->advf; + pDest->pAdvSink = pSrc->pAdvSink; + pDest->dwConnection = pSrc->dwConnection; + + if (pDest->pAdvSink != NULL) { + pDest->pAdvSink->lpVtbl->AddRef(pDest->pAdvSink); + } + + return TRUE; + +} /* OleStdCopyStatData() + */ + +STDAPI_(LPENUMSTATDATA) + OleStdEnumStatData_Create(ULONG nCount, LPSTATDATA lpStatOrg) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPMALLOC lpMalloc=NULL; + LPOLESTDENUMSTATDATA lpSD=NULL; + DWORD dwSize; + WORD i; + HRESULT hRes; + + hRes = CoGetMalloc(MEMCTX_TASK, &lpMalloc); + if (hRes != NOERROR) { + return NULL; + } + + lpSD = (LPOLESTDENUMSTATDATA)lpMalloc->lpVtbl->Alloc(lpMalloc, + sizeof(OLESTDENUMSTATDATA)); + if (lpSD == NULL) { + goto errReturn; + } + + lpSD->lpVtbl = &g_EnumSTATDATAVtbl; + lpSD->m_dwRefs = 1; + lpSD->m_nCount = nCount; + lpSD->m_nIndex = 0; + + dwSize = sizeof(STATDATA) * lpSD->m_nCount; + + lpSD->m_lpStat = (LPSTATDATA)lpMalloc->lpVtbl->Alloc(lpMalloc, dwSize); + if (lpSD->m_lpStat == NULL) + goto errReturn; + + lpMalloc->lpVtbl->Release(lpMalloc); + + for (i=0; i<nCount; i++) { + OleStdCopyStatData( + (LPSTATDATA)&(lpSD->m_lpStat[i]), (LPSTATDATA)&(lpStatOrg[i])); + } + + return (LPENUMSTATDATA)lpSD; + +errReturn: + if (lpSD != NULL) + lpMalloc->lpVtbl->Free(lpMalloc, lpSD); + + if (lpMalloc != NULL) + lpMalloc->lpVtbl->Release(lpMalloc); + + return NULL; + +} /* OleStdEnumStatData_Create() + */ + + +VOID + OleStdEnumStatData_Destroy(LPOLESTDENUMSTATDATA lpSD) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPMALLOC lpMalloc=NULL; + WORD i; + + if (lpSD != NULL) { + + if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) == NOERROR) { + + /* OLE2NOTE: we MUST free any memory that was allocated for + ** TARGETDEVICES contained within the STATDATA elements. + */ + for (i=0; i<lpSD->m_nCount; i++) { + if( lpSD->m_lpStat[i].pAdvSink ) + lpSD->m_lpStat[i].pAdvSink->lpVtbl->Release(lpSD->m_lpStat[i].pAdvSink); + + OleStdFree(lpSD->m_lpStat[i].formatetc.ptd); + } + + if (lpSD->m_lpStat != NULL) { + lpMalloc->lpVtbl->Free(lpMalloc, lpSD->m_lpStat); + } + + lpMalloc->lpVtbl->Free(lpMalloc, lpSD); + lpMalloc->lpVtbl->Release(lpMalloc); + } + } +} /* OleStdEnumStatData_Destroy() + */ + + +STDMETHODIMP + OleStdEnumStatData_QueryInterface( + LPENUMSTATDATA lpThis, REFIID riid, LPVOID FAR* ppobj) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis; + *ppobj = NULL; + + if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IEnumSTATDATA)){ + *ppobj = (LPVOID)lpSD; + } + + if (*ppobj == NULL) return ResultFromScode(E_NOINTERFACE); + else{ + OleStdEnumStatData_AddRef(lpThis); + return NOERROR; + } + +} /* OleStdEnumStatData_QueryInterface() + */ + + +STDMETHODIMP_(ULONG) + OleStdEnumStatData_AddRef(LPENUMSTATDATA lpThis) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis; + return lpSD->m_dwRefs++; + +} /* OleStdEnumStatData_AddRef() + */ + + +STDMETHODIMP_(ULONG) + OleStdEnumStatData_Release(LPENUMSTATDATA lpThis) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis; + DWORD dwRefs = --lpSD->m_dwRefs; + + if (dwRefs == 0) + OleStdEnumStatData_Destroy(lpSD); + + return dwRefs; + +} /* OleStdEnumStatData_Release() + */ + + +STDMETHODIMP + OleStdEnumStatData_Next(LPENUMSTATDATA lpThis, ULONG celt, LPSTATDATA rgelt, + ULONG FAR* pceltFetched) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis; + ULONG i=0; + ULONG nOffset; + + if (rgelt == NULL) { + return ResultFromScode(E_INVALIDARG); + } + + while (i < celt) { + nOffset = lpSD->m_nIndex + i; + + if (nOffset < lpSD->m_nCount) { + OleStdCopyStatData( + (LPSTATDATA)&(rgelt[i]), (LPSTATDATA)&(lpSD->m_lpStat[nOffset])); + i++; + }else{ + break; + } + } + + lpSD->m_nIndex += (WORD)i; + + if (pceltFetched != NULL) { + *pceltFetched = i; + } + + if (i != celt) { + return ResultFromScode(S_FALSE); + } + + return NOERROR; +} /* OleStdEnumStatData_Next() + */ + + +STDMETHODIMP + OleStdEnumStatData_Skip(LPENUMSTATDATA lpThis, ULONG celt) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis; + ULONG i=0; + ULONG nOffset; + + while (i < celt) { + nOffset = lpSD->m_nIndex + i; + + if (nOffset < lpSD->m_nCount) { + i++; + }else{ + break; + } + } + + lpSD->m_nIndex += (WORD)i; + + if (i != celt) { + return ResultFromScode(S_FALSE); + } + + return NOERROR; +} /* OleStdEnumStatData_Skip() + */ + + +STDMETHODIMP + OleStdEnumStatData_Reset(LPENUMSTATDATA lpThis) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis; + lpSD->m_nIndex = 0; + + return NOERROR; +} /* OleStdEnumStatData_Reset() + */ + + +STDMETHODIMP + OleStdEnumStatData_Clone(LPENUMSTATDATA lpThis, LPENUMSTATDATA FAR* ppenum) +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +{ + LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis; + + if (ppenum == NULL) { + return ResultFromScode(E_INVALIDARG); + } + + *ppenum = OleStdEnumStatData_Create(lpSD->m_nCount, lpSD->m_lpStat); + + // make sure cloned enumerator has same index state as the original + if (*ppenum) { + LPOLESTDENUMSTATDATA lpSDClone = (LPOLESTDENUMSTATDATA)*ppenum; + lpSDClone->m_nIndex = lpSD->m_nIndex; + return NOERROR; + } else + return ResultFromScode(E_OUTOFMEMORY); + +} /* OleStdEnumStatData_Clone() + */ + diff --git a/private/oleutest/letest/ole2ui/filelist.mk b/private/oleutest/letest/ole2ui/filelist.mk new file mode 100644 index 000000000..1a15317c7 --- /dev/null +++ b/private/oleutest/letest/ole2ui/filelist.mk @@ -0,0 +1,75 @@ +############################################################################ +# +# Microsoft Windows +# Copyright (C) Microsoft Corporation, 1992 - 1992. +# All rights reserved. +# +############################################################################ + + +# +# Name of target. Include an extension (.dll, .lib, .exe) +# If the target is part of the release, set RELEASE to 1. +# + +TARGET = ole2uixd.lib +RELEASE = 0 +TARGET_DESCRIPTION = "$(PLATFORM) $(BUILDTYPE) OLE 2 UI Library" + + +# +# Source files. Remember to prefix each name with .\ +# + +CFILES = .\busy.c \ + .\common.c \ + .\convert.c \ + .\dbgutil.c \ + .\dllfuncs.c \ + .\drawicon.c \ + .\enumfetc.c \ + .\enumstat.c \ + .\geticon.c \ + .\hatch.c \ + .\icon.c \ + .\iconbox.c \ + .\insobj.c \ + .\links.c \ + .\msgfiltr.c \ + .\objfdbk.c \ + .\ole2ui.c \ + .\olestd.c \ + .\oleutl.c \ + .\pastespl.c \ + .\precomp.c \ + .\regdb.c \ + .\resimage.c \ + .\stdpal.c \ + .\targtdev.c \ + .\utility.c + +CPPFILES = .\suminfo.cpp \ + .\dballoc.cpp + +RCFILES = .\ole2ui.rc + +# +# Libraries and other object files to link. +# +OBJFILES = +LIBS = + +DEFFILE = + + +# +# Precompiled headers. +# + +PXXFILE = +PFILE = +CINC = -I$(CAIROLE)\h -I$(CAIROLE)\common \ + -I.\resource\usa -I.\resource\static + +CFLAGS=/DWIN32 /D_DEBUG /DOLE201 /D_INC_OLE + diff --git a/private/oleutest/letest/ole2ui/fileopen.dlg b/private/oleutest/letest/ole2ui/fileopen.dlg new file mode 100644 index 000000000..65f6e91dc --- /dev/null +++ b/private/oleutest/letest/ole2ui/fileopen.dlg @@ -0,0 +1,33 @@ +DLGINCLUDE RCDATA DISCARDABLE +BEGIN + "OLE2UI.H\0" +END + +IDD_FILEOPEN DIALOG 36, 24, 264, 134 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Open" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Source:", stc3, 6, 3, 76, 9 + EDITTEXT edt1, 7, 13, 195, 12, ES_AUTOHSCROLL | ES_OEMCONVERT + LISTBOX lst1, 6, 34, 90, 68, LBS_SORT | LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL | + WS_TABSTOP + LTEXT "&Directories:", ID_DUMMY, 110, 28, 92, 9 + LTEXT "", stc1, 110, 36, 92, 9, SS_NOPREFIX + LISTBOX lst2, 110, 49, 92, 53, LBS_SORT | LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL | + WS_TABSTOP + LTEXT "List Files of &Type:", stc2, 6, 104, 90, 9 + COMBOBOX cmb1, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | + WS_BORDER | WS_VSCROLL | WS_TABSTOP + LTEXT "Dri&ves:", stc4, 110, 104, 92, 9 + COMBOBOX cmb2, 110, 114, 92, 68, CBS_DROPDOWNLIST | + CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | + CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK", IDOK, 208, 6, 50, 14, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, 208, 24, 50, 14, WS_GROUP + PUSHBUTTON "&Help", IDHELP, 208, 46, 50, 14, WS_GROUP + CONTROL "&Read Only", chx1, "Button", BS_AUTOCHECKBOX | WS_GROUP | + WS_TABSTOP, 208, 68, 50, 12 +END diff --git a/private/oleutest/letest/ole2ui/geticon.c b/private/oleutest/letest/ole2ui/geticon.c new file mode 100644 index 000000000..0bf1e13b3 --- /dev/null +++ b/private/oleutest/letest/ole2ui/geticon.c @@ -0,0 +1,1177 @@ +/************************************************************************* +** +** The following API's are now OBSOLETE because equivalent API's have been +** added to the OLE2.DLL library +** GetIconOfFile superceeded by OleGetIconOfFile +** GetIconOfClass superceeded by OleGetIconOfClass +** OleUIMetafilePictFromIconAndLabel +** superceeded by OleMetafilePictFromIconAndLabel +*************************************************************************/ + +/* + * GETICON.C + * + * Functions to create DVASPECT_ICON metafile from filename or classname. + * + * GetIconOfFile + * GetIconOfClass + * OleUIMetafilePictFromIconAndLabel + * HIconAndSourceFromClass Extracts the first icon in a class's server path + * and returns the path and icon index to caller. + * FIconFileFromClass Retrieves the path to the exe/dll containing the + * default icon, and the index of the icon. + * OleStdIconLabelTextOut Draw icon label text (line break if necessary) + * + * (c) Copyright Microsoft Corp. 1992-1993 All Rights Reserved + */ + + +/******* + * + * ICON (DVASPECT_ICON) METAFILE FORMAT: + * + * The metafile generated with OleUIMetafilePictFromIconAndLabel contains + * the following records which are used by the functions in DRAWICON.C + * 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. + * + *******/ + +#define STRICT 1 +#include "ole2ui.h" + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <commdlg.h> +#include <memory.h> +#include <cderr.h> +#include "common.h" +#include "utility.h" + +static TCHAR szSeparators[] = TEXT(" \t\\/!:"); + +#define IS_SEPARATOR(c) ( (c) == TEXT(' ') || (c) == TEXT('\\') \ + || (c) == TEXT('/') || (c) == TEXT('\t') \ + || (c) == TEXT('!') || (c) == TEXT(':') ) +#define IS_FILENAME_DELIM(c) ( (c) == TEXT('\\') || (c) == TEXT('/') \ + || (c) == TEXT(':') ) + + +#if defined( OBSOLETE ) +static HINSTANCE s_hInst; + +static TCHAR szMaxWidth[] =TEXT("WWWWWWWWWW"); + +//Strings for metafile comments. +static TCHAR szIconOnly[]=TEXT("IconOnly"); //Where to stop to exclude label. + +#ifdef WIN32 +static TCHAR szOLE2DLL[] = TEXT("ole2w32.dll"); // name of OLE 2.0 library +#else +static TCHAR szOLE2DLL[] = TEXT("ole2.dll"); // name of OLE 2.0 library +#endif + +#define ICONINDEX 0 + +#define AUXUSERTYPE_SHORTNAME USERCLASSTYPE_SHORT // short name +#define HIMETRIC_PER_INCH 2540 // number HIMETRIC units per inch +#define PTS_PER_INCH 72 // number points (font size) per inch + +#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) +#define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH) + +static TCHAR szVanillaDocIcon[] = TEXT("DefIcon"); + +static TCHAR szDocument[40] = TEXT(""); + + +/* + * GetIconOfFile(HINSTANCE hInst, LPSTR lpszPath, BOOL fUseFileAsLabel) + * + * Purpose: + * Returns a hMetaPict containing an icon and label (filename) for the + * specified filename. + * + * Parameters: + * hinst + * lpszPath LPTSTR path including filename to use + * fUseFileAsLabel BOOL TRUE if the icon's label is the filename, FALSE if + * there should be no label. + * + * Return Value: + * HGLOBAL hMetaPict containing the icon and label - if there's no + * class in reg db for the file in lpszPath, then we use + * Document. If lpszPath is NULL, then we return NULL. + */ + +STDAPI_(HGLOBAL) GetIconOfFile(HINSTANCE hInst, LPTSTR lpszPath, BOOL fUseFileAsLabel) +{ + TCHAR szIconFile[OLEUI_CCHPATHMAX]; + TCHAR szLabel[OLEUI_CCHLABELMAX]; + LPTSTR lpszClsid = NULL; + CLSID clsid; + HICON hDefIcon = NULL; + UINT IconIndex = 0; + HGLOBAL hMetaPict; + HRESULT hResult; + + if (NULL == lpszPath) // even if fUseFileAsLabel is FALSE, we still + return NULL; // need a valid filename to get the class. + + s_hInst = hInst; + + hResult = GetClassFileA(lpszPath, &clsid); + + if (NOERROR == hResult) // use the clsid we got to get to the icon + { + hDefIcon = HIconAndSourceFromClass(&clsid, + (LPTSTR)szIconFile, + &IconIndex); + } + + if ( (NOERROR != hResult) || (NULL == hDefIcon) ) + { + // Here, either GetClassFile failed or HIconAndSourceFromClass failed. + + LPTSTR lpszTemp; + + lpszTemp = lpszPath; + + while ((*lpszTemp != TEXT('.')) && (*lpszTemp != TEXT('\0'))) + lpszTemp++; + + + if (TEXT('.') != *lpszTemp) + goto UseVanillaDocument; + + + if (FALSE == GetAssociatedExecutable(lpszTemp, (LPTSTR)szIconFile)) + goto UseVanillaDocument; + + hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex); + } + + if (hDefIcon <= (HICON)1) // ExtractIcon returns 1 if szExecutable is not exe, + { // 0 if there are no icons. +UseVanillaDocument: + + lstrcpy((LPTSTR)szIconFile, (LPTSTR)szOLE2DLL); + IconIndex = ICONINDEX; + hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex); + + } + + // Now let's get the label we want to use. + + if (fUseFileAsLabel) // strip off path, so we just have the filename. + { + int istrlen; + LPTSTR lpszBeginFile; + + istrlen = lstrlen(lpszPath); + + // set pointer to END of path, so we can walk backwards through it. + lpszBeginFile = lpszPath + istrlen -1; + + while ( (lpszBeginFile >= lpszPath) + && (!IS_FILENAME_DELIM(*lpszBeginFile)) ) + lpszBeginFile--; + + + lpszBeginFile++; // step back over the delimiter + + + LSTRCPYN(szLabel, lpszBeginFile, sizeof(szLabel)/sizeof(TCHAR)); + } + + else // use the short user type (AuxUserType2) for the label + { + + if (0 == OleStdGetAuxUserType(&clsid, AUXUSERTYPE_SHORTNAME, + (LPTSTR)szLabel, OLEUI_CCHLABELMAX_SIZE, NULL)) { + + if ('\0'==szDocument[0]) { + LoadString( + s_hInst,IDS_DEFICONLABEL,szDocument,sizeof(szDocument)/sizeof(TCHAR)); + } + lstrcpy(szLabel, szDocument); + } + } + + + hMetaPict = OleUIMetafilePictFromIconAndLabel(hDefIcon, + szLabel, + (LPTSTR)szIconFile, + IconIndex); + + DestroyIcon(hDefIcon); + + return hMetaPict; + +} + + + +/* + * GetIconOfClass(HINSTANCE hInst, REFCLSID rclsid, LPSTR lpszLabel, BOOL fUseTypeAsLabel) + * + * Purpose: + * Returns a hMetaPict containing an icon and label (human-readable form + * of class) for the specified clsid. + * + * Parameters: + * hinst + * rclsid REFCLSID pointing to clsid to use. + * lpszLabel label to use for icon. + * fUseTypeAsLabel Use the clsid's user type name as the icon's label. + * + * Return Value: + * HGLOBAL hMetaPict containing the icon and label - if we + * don't find the clsid in the reg db then we + * return NULL. + */ + +STDAPI_(HGLOBAL) GetIconOfClass(HINSTANCE hInst, REFCLSID rclsid, LPTSTR lpszLabel, BOOL fUseTypeAsLabel) +{ + + TCHAR szLabel[OLEUI_CCHLABELMAX]; + TCHAR szIconFile[OLEUI_CCHPATHMAX]; + HICON hDefIcon; + UINT IconIndex; + HGLOBAL hMetaPict; + + + s_hInst = hInst; + + if (!fUseTypeAsLabel) // Use string passed in as label + { + if (NULL != lpszLabel) + LSTRCPYN(szLabel, lpszLabel, OLEUI_CCHLABELMAX_SIZE); + else + *szLabel = TEXT('\0'); + } + else // Use AuxUserType2 (short name) as label + { + + if (0 == OleStdGetAuxUserType(rclsid, + AUXUSERTYPE_SHORTNAME, + (LPTSTR)szLabel, + OLEUI_CCHLABELMAX_SIZE, + NULL)) + + // If we can't get the AuxUserType2, then try the long name + if (0 == OleStdGetUserTypeOfClass(rclsid, szLabel, OLEUI_CCHKEYMAX_SIZE, NULL)) { + if (TEXT('\0')==szDocument[0]) { + LoadString( + s_hInst,IDS_DEFICONLABEL,szDocument,sizeof(szDocument)/sizeof(TCHAR)); + } + lstrcpy(szLabel, szDocument); // last resort + } + } + + // Get the icon, icon index, and path to icon file + hDefIcon = HIconAndSourceFromClass(rclsid, + (LPTSTR)szIconFile, + &IconIndex); + + if (NULL == hDefIcon) // Use Vanilla Document + { + lstrcpy((LPTSTR)szIconFile, (LPTSTR)szOLE2DLL); + IconIndex = ICONINDEX; + hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex); + } + + // Create the metafile + hMetaPict = OleUIMetafilePictFromIconAndLabel(hDefIcon, szLabel, + (LPTSTR)szIconFile, IconIndex); + + DestroyIcon(hDefIcon); + + return hMetaPict; + +} + + +/* + * OleUIMetafilePictFromIconAndLabel + * + * Purpose: + * Creates a METAFILEPICT structure that container a metafile in which + * the icon and label are drawn. A comment record is inserted between + * the icon and the label code so our special draw function can stop + * playing before the label. + * + * Parameters: + * hIcon HICON to draw into the metafile + * pszLabel LPTSTR to the label string. + * pszSourceFile LPTSTR containing the local pathname of the icon + * as we either get from the user or from the reg DB. + * iIcon UINT providing the index into pszSourceFile where + * the icon came from. + * + * Return Value: + * HGLOBAL Global memory handle containing a METAFILEPICT where + * the metafile uses the MM_ANISOTROPIC mapping mode. The + * extents reflect both icon and label. + */ + +STDAPI_(HGLOBAL) OleUIMetafilePictFromIconAndLabel(HICON hIcon, LPTSTR pszLabel + , LPTSTR pszSourceFile, UINT iIcon) + { + HDC hDC, hDCScreen; + HMETAFILE hMF; + HGLOBAL hMem; + LPMETAFILEPICT pMF; + UINT cxIcon, cyIcon; + UINT cxText, cyText; + UINT cx, cy; + UINT cchLabel = 0; + HFONT hFont, hFontT; + int cyFont; + TCHAR szIndex[10]; + RECT TextRect; + SIZE size; + POINT point; + UINT fuAlign; + + if (NULL==hIcon) // null label is valid but NOT a null icon + return NULL; + + //Create a memory metafile + hDC=(HDC)CreateMetaFile(NULL); + + if (NULL==hDC) + return NULL; + + //Allocate the metafilepict + hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(METAFILEPICT)); + + if (NULL==hMem) + { + hMF=CloseMetaFile(hDC); + DeleteMetaFile(hMF); + return NULL; + } + + + if (NULL!=pszLabel) + { + cchLabel=lstrlen(pszLabel); + + if (cchLabel >= OLEUI_CCHLABELMAX) + pszLabel[cchLabel] = TEXT('\0'); // truncate string + } + + //Need to use the screen DC for these operations + hDCScreen=GetDC(NULL); + cyFont=-(8*GetDeviceCaps(hDCScreen, LOGPIXELSY))/72; + + //cyFont was calculated to give us 8 point. + hFont=CreateFont(cyFont, 5, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET + , OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY + , FF_SWISS, TEXT("MS Sans Serif")); + + hFontT=SelectObject(hDCScreen, hFont); + + GetTextExtentPoint(hDCScreen,szMaxWidth,lstrlen(szMaxWidth),&size); + SelectObject(hDCScreen, hFontT); + + cxText = size.cx; + cyText = size.cy * 2; + + cxIcon = GetSystemMetrics(SM_CXICON); + cyIcon = GetSystemMetrics(SM_CYICON); + + + // If we have no label, then we want the metafile to be the width of + // the icon (plus margin), not the width of the fattest string. + if ( (NULL == pszLabel) || (TEXT('\0') == *pszLabel) ) + cx = cxIcon + cxIcon / 4; + else + cx = max(cxText, cxIcon); + + cy=cyIcon+cyText+4; + + //Set the metafile size to fit the icon and label + SetWindowOrgEx(hDC, 0, 0, &point); + SetWindowExtEx(hDC, cx, cy, &size); + + //Set up rectangle to pass to OleStdIconLabelTextOut + SetRectEmpty(&TextRect); + + TextRect.right = cx; + TextRect.bottom = cy; + + //Draw the icon and the text, centered with respect to each other. + DrawIcon(hDC, (cx-cxIcon)/2, 0, hIcon); + + //String that indicates where to stop if we're only doing icons + Escape(hDC, MFCOMMENT, lstrlen(szIconOnly)+1, szIconOnly, NULL); + + SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); + SetBkMode(hDC, TRANSPARENT); + fuAlign = SetTextAlign(hDC, TA_LEFT | TA_TOP | TA_NOUPDATECP); + + OleStdIconLabelTextOut(hDC, + hFont, + 0, + cy - cyText, + ETO_CLIPPED, + &TextRect, + pszLabel, + cchLabel, + NULL); + + //Write comments containing the icon source file and index. + if (NULL!=pszSourceFile) + { + //+1 on string lengths insures the null terminator is embedded. + Escape(hDC, MFCOMMENT, lstrlen(pszSourceFile)+1, pszSourceFile, NULL); + + cchLabel=wsprintf(szIndex, TEXT("%u"), iIcon); + Escape(hDC, MFCOMMENT, cchLabel+1, szIndex, NULL); + } + + SetTextAlign(hDC, fuAlign); + + //All done with the metafile, now stuff it all into a METAFILEPICT. + hMF=CloseMetaFile(hDC); + + if (NULL==hMF) + { + GlobalFree(hMem); + ReleaseDC(NULL, hDCScreen); + return NULL; + } + + //Fill out the structure + pMF=(LPMETAFILEPICT)GlobalLock(hMem); + + //Transform to HIMETRICS + cx=XformWidthInPixelsToHimetric(hDCScreen, cx); + cy=XformHeightInPixelsToHimetric(hDCScreen, cy); + ReleaseDC(NULL, hDCScreen); + + pMF->mm=MM_ANISOTROPIC; + pMF->xExt=cx; + pMF->yExt=cy; + pMF->hMF=hMF; + + GlobalUnlock(hMem); + + DeleteObject(hFont); + + return hMem; + } + +#endif // OBSOLETE + + +/* + * 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; + LONG dw; + LRESULT lRet; + TCHAR szValue[OLEUI_CCHKEYMAX]; + TCHAR szKey[OLEUI_CCHKEYMAX]; + LPTSTR lpszTemp, lpszExe; + + + lRet = RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + + if (ERROR_SUCCESS != lRet) + return FALSE; + + dw = OLEUI_CCHPATHMAX_SIZE; + lRet = RegQueryValue(hKey, lpszExtension, (LPTSTR)szValue, &dw); //ProgId + + if (ERROR_SUCCESS != lRet) + { + RegCloseKey(hKey); + return FALSE; + } + + + // szValue now has ProgID + lstrcpy(szKey, szValue); + lstrcat(szKey, TEXT("\\Shell\\Open\\Command")); + + + dw = OLEUI_CCHPATHMAX_SIZE; + lRet = RegQueryValue(hKey, (LPTSTR)szKey, (LPTSTR)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. + + lpszTemp = (LPTSTR)szValue; + + while ((TEXT('\0') != *lpszTemp) && (iswspace(*lpszTemp))) + lpszTemp++; // Strip off leading spaces + + lpszExe = lpszTemp; + + while ((TEXT('\0') != *lpszTemp) && (!iswspace(*lpszTemp))) + lpszTemp++; // Step through exe name + + *lpszTemp = TEXT('\0'); // null terminate at first space (or at end). + + + lstrcpy(lpszExecutable, lpszExe); + + return TRUE; + +} + + +/* + * HIconAndSourceFromClass + * + * Purpose: + * Given an object class name, finds an associated executable in the + * registration database and extracts the first icon from that + * executable. If none is available or the class has no associated + * executable, this function returns NULL. + * + * Parameters: + * rclsid pointer to clsid to look up. + * pszSource LPSTR in which to place the source of the icon. + * This is assumed to be OLEUI_CCHPATHMAX + * puIcon UINT FAR * in which to store the index of the + * icon in pszSource. + * + * Return Value: + * HICON Handle to the extracted icon if there is a module + * associated to pszClass. NULL on failure to either + * find the executable or extract and icon. + */ + +HICON FAR PASCAL HIconAndSourceFromClass(REFCLSID rclsid, LPTSTR pszSource, UINT FAR *puIcon) + { + HICON hIcon; + UINT IconIndex; + + if (NULL==rclsid || NULL==pszSource || IsEqualCLSID(rclsid,&CLSID_NULL)) + return NULL; + + if (!FIconFileFromClass(rclsid, pszSource, OLEUI_CCHPATHMAX_SIZE, &IconIndex)) + return NULL; + + hIcon=ExtractIcon(ghInst, pszSource, IconIndex); + + if ((HICON)32 > hIcon) + hIcon=NULL; + else + *puIcon= IconIndex; + + return hIcon; + } + + +/* + * 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) +{ + LPTSTR lpField = lpszString; + int cFieldFound = 1; + + if (1 ==nField) + return lpszString; + + while (*lpField != TEXT('\0')) + { + + if (*lpField++ == chDelimiter) + { + + cFieldFound++; + + if (nField == cFieldFound) + return lpField; + } + } + + return lpField; + +} + + +/* + * FIconFileFromClass + * + * Purpose: + * Looks up the path to executable that contains the class default icon. + * + * Parameters: + * rclsid pointer to CLSID to look up. + * pszEXE LPSTR at which to store the server name + * cch UINT size of pszEXE + * lpIndex LPUINT to index of icon within executable + * + * Return Value: + * BOOL TRUE if one or more characters were loaded into pszEXE. + * FALSE otherwise. + */ + +BOOL FAR PASCAL FIconFileFromClass(REFCLSID rclsid, LPTSTR pszEXE, UINT cchBytes, UINT FAR *lpIndex) +{ + + LONG dw; + LONG lRet; + HKEY hKey; + LPMALLOC lpIMalloc; + HRESULT hrErr; + LPTSTR lpBuffer; + LPTSTR lpIndexString; + UINT cBufferSize = 136;// room for 128 char path and icon's index + TCHAR szKey[64]; + LPSTR pszClass; + UINT cch=cchBytes / sizeof(TCHAR); // number of characters + + + if (NULL==rclsid || NULL==pszEXE || 0==cch || IsEqualCLSID(rclsid,&CLSID_NULL)) + return FALSE; + + //Here, we use CoGetMalloc and alloc a buffer (maxpathlen + 8) to + //pass to RegQueryValue. Then, we copy the exe to pszEXE and the + //index to *lpIndex. + + hrErr = CoGetMalloc(MEMCTX_TASK, &lpIMalloc); + + if (NOERROR != hrErr) + return FALSE; + + lpBuffer = (LPTSTR)lpIMalloc->lpVtbl->Alloc(lpIMalloc, cBufferSize); + + if (NULL == lpBuffer) + { + lpIMalloc->lpVtbl->Release(lpIMalloc); + return FALSE; + } + + + if (CoIsOle1Class(rclsid)) + { + + LPOLESTR lpszProgID; + + // we've got an ole 1.0 class on our hands, so we look at + // progID\protocol\stdfileedting\server to get the + // name of the executable. + + ProgIDFromCLSID(rclsid, &lpszProgID); + + //Open up the class key +#ifdef UNICODE + lRet=RegOpenKey(HKEY_CLASSES_ROOT, lpszProgID, &hKey); +#else + { + char szTemp[255]; + + wcstombs(szTemp, lpszProgID, 255); + lRet=RegOpenKey(HKEY_CLASSES_ROOT, szTemp, &hKey); + } +#endif + + if (ERROR_SUCCESS != lRet) + { + lpIMalloc->lpVtbl->Free(lpIMalloc, lpszProgID); + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return FALSE; + } + + dw=(LONG)cBufferSize; + lRet = RegQueryValue(hKey, TEXT("Protocol\\StdFileEditing\\Server"), lpBuffer, &dw); + + if (ERROR_SUCCESS != lRet) + { + + RegCloseKey(hKey); + lpIMalloc->lpVtbl->Free(lpIMalloc, lpszProgID); + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return FALSE; + } + + + // Use server and 0 as the icon index + LSTRCPYN(pszEXE, lpBuffer, cch); + + *lpIndex = 0; + + RegCloseKey(hKey); + lpIMalloc->lpVtbl->Free(lpIMalloc, lpszProgID); + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return TRUE; + + } + + + + /* + * We have to go walking in the registration database under the + * classname, so we first open the classname key and then check + * under "\\DefaultIcon" to get the file that contains the icon. + */ + + StringFromCLSIDA(rclsid, &pszClass); + + lstrcpy(szKey, TEXT("CLSID\\")); + + lstrcat(szKey, pszClass); + + //Open up the class key + lRet=RegOpenKey(HKEY_CLASSES_ROOT, szKey, &hKey); + + if (ERROR_SUCCESS != lRet) + { + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return FALSE; + } + + //Get the executable path and icon index. + + dw=(LONG)cBufferSize; + lRet=RegQueryValue(hKey, TEXT("DefaultIcon"), lpBuffer, &dw); + + if (ERROR_SUCCESS != lRet) + { + // no DefaultIcon key...try LocalServer + + dw=(LONG)cBufferSize; + lRet=RegQueryValue(hKey, TEXT("LocalServer"), lpBuffer, &dw); + + if (ERROR_SUCCESS != lRet) + { + // no LocalServer entry either...they're outta luck. + + RegCloseKey(hKey); + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return FALSE; + } + + + // Use server from LocalServer or Server and 0 as the icon index + LSTRCPYN(pszEXE, lpBuffer, cch); + + *lpIndex = 0; + + RegCloseKey(hKey); + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return TRUE; + } + + RegCloseKey(hKey); + + // lpBuffer contains a string that looks like "<pathtoexe>,<iconindex>", + // so we need to separate the path and the icon index. + + lpIndexString = PointerToNthField(lpBuffer, 2, TEXT(',')); + + if (TEXT('\0') == *lpIndexString) // no icon index specified - use 0 as default. + { + *lpIndex = 0; + + } + else + { + LPTSTR lpTemp; + static TCHAR szTemp[16]; + + lstrcpy((LPTSTR)szTemp, lpIndexString); + + // Put the icon index part into *pIconIndex +#ifdef UNICODE + { + char szTEMP1[16]; + + wcstombs(szTEMP1, szTemp, 16); + *lpIndex = atoi((const char *)szTEMP1); + } +#else + *lpIndex = atoi((const char *)szTemp); +#endif + + // Null-terminate the exe part. +#ifdef WIN32 + lpTemp = CharPrev(lpBuffer, lpIndexString); +#else + lpTemp = AnsiPrev(lpBuffer, lpIndexString); +#endif + *lpTemp = TEXT('\0'); + } + + if (!LSTRCPYN(pszEXE, lpBuffer, cch)) + { + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return FALSE; + } + + // Free the memory we alloc'd and leave. + lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer); + lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass); + lpIMalloc->lpVtbl->Release(lpIMalloc); + return TRUE; +} + + + +/* + * OleStdIconLabelTextOut + * + * Purpose: + * Replacement for DrawText to be used in the "Display as Icon" metafile. + * Uses ExtTextOut to output a string center on (at most) two lines. + * Uses a very simple word wrap algorithm to split the lines. + * + * Parameters: (same as for ExtTextOut, except for hFont) + * hDC device context to draw into; if this is NULL, then we don't + * ETO the text, we just return the index of the beginning + * of the second line + * hFont font to use + * nXStart x-coordinate of starting position + * nYStart y-coordinate of starting position + * fuOptions rectangle type + * lpRect rect far * containing rectangle to draw text in. + * lpszString string to draw + * cchString length of string (truncated if over OLEUI_CCHLABELMAX) + * lpDX spacing between character cells + * + * Return Value: + * UINT Index of beginning of last line (0 if there's only one + * line of text). + * + */ + +STDAPI_(UINT) OleStdIconLabelTextOut(HDC hDC, + HFONT hFont, + int nXStart, + int nYStart, + UINT fuOptions, + RECT FAR * lpRect, + LPTSTR lpszString, + UINT cchString, + int FAR * lpDX) +{ + + HDC hDCScreen; + static TCHAR szTempBuff[OLEUI_CCHLABELMAX]; + int cxString, cyString, cxMaxString; + int cxFirstLine, cyFirstLine, cxSecondLine; + int index; + int cch = cchString; + TCHAR chKeep; + LPTSTR lpszSecondLine; + HFONT hFontT; + BOOL fPrintText = TRUE; + UINT iLastLineStart = 0; + SIZE size; + + // Initialization stuff... + + if (NULL == hDC) // If we got NULL as the hDC, then we don't actually call ETO + fPrintText = FALSE; + + + // Make a copy of the string (NULL or non-NULL) that we're using + if (NULL == lpszString) + *szTempBuff = TEXT('\0'); + + else + LSTRCPYN(szTempBuff, lpszString, sizeof(szTempBuff)/sizeof(TCHAR)); + + // set maximum width + cxMaxString = lpRect->right - lpRect->left; + + // get screen DC to do text size calculations + hDCScreen = GetDC(NULL); + + hFontT=SelectObject(hDCScreen, hFont); + + // get the extent of our label +#ifdef WIN32 + // GetTextExtentPoint32 has fixed the off-by-one bug. + GetTextExtentPoint32(hDCScreen, szTempBuff, cch, &size); +#else + GetTextExtentPoint(hDCScreen, szTempBuff, cch, &size); +#endif + + cxString = size.cx; + cyString = size.cy; + + // Select in the font we want to use + if (fPrintText) + SelectObject(hDC, hFont); + + // String is smaller than max string - just center, ETO, and return. + if (cxString <= cxMaxString) + { + + if (fPrintText) + ExtTextOut(hDC, + nXStart + (lpRect->right - cxString) / 2, + nYStart, + fuOptions, + lpRect, + szTempBuff, + cch, + NULL); + + iLastLineStart = 0; // only 1 line of text + goto CleanupAndLeave; + } + + // String is too long...we've got to word-wrap it. + + + // Are there any spaces, slashes, tabs, or bangs in string? + + if (lstrlen(szTempBuff) != (int) +#ifdef UNICODE + wcscspn(szTempBuff, szSeparators) +#else + strcspn(szTempBuff, szSeparators) +#endif + ) + { + // Yep, we've got spaces, so we'll try to find the largest + // space-terminated string that will fit on the first line. + + index = cch; + + + while (index >= 0) + { + + TCHAR cchKeep; + + // scan the string backwards for spaces, slashes, tabs, or bangs + + while (!IS_SEPARATOR(szTempBuff[index]) ) + index--; + + + if (index <= 0) + break; + + cchKeep = szTempBuff[index]; // remember what char was there + + szTempBuff[index] = TEXT('\0'); // just for now + +#ifdef WIN32 + GetTextExtentPoint32( + hDCScreen, (LPTSTR)szTempBuff,lstrlen((LPTSTR)szTempBuff),&size); +#else + GetTextExtentPoint( + hDCScreen, (LPTSTR)szTempBuff,lstrlen((LPTSTR)szTempBuff),&size); +#endif + + cxFirstLine = size.cx; + cyFirstLine = size.cy; + + szTempBuff[index] = cchKeep; // put the right char back + + if (cxFirstLine <= cxMaxString) + { + + iLastLineStart = index + 1; + + if (!fPrintText) + goto CleanupAndLeave; + + ExtTextOut(hDC, + nXStart + (lpRect->right - cxFirstLine) / 2, + nYStart, + fuOptions, + lpRect, + (LPTSTR)szTempBuff, + index + 1, + lpDX); + + lpszSecondLine = (LPTSTR)szTempBuff; + + lpszSecondLine += (index + 1) ; + + GetTextExtentPoint(hDCScreen, + lpszSecondLine, + lstrlen(lpszSecondLine), + &size); + + // If the second line is wider than the rectangle, we + // just want to clip the text. + cxSecondLine = min(size.cx, cxMaxString); + + ExtTextOut(hDC, + nXStart + (lpRect->right - cxSecondLine) / 2, + nYStart + cyFirstLine, + fuOptions, + lpRect, + lpszSecondLine, + lstrlen(lpszSecondLine), + lpDX); + + goto CleanupAndLeave; + + } // end if + + index--; + + } // end while + + } // end if + + // Here, there are either no spaces in the string (strchr(szTempBuff, ' ') + // returned NULL), or there spaces in the string, but they are + // positioned so that the first space terminated string is still + // longer than one line. So, we walk backwards from the end of the + // string until we find the largest string that will fit on the first + // line , and then we just clip the second line. + + cch = lstrlen((LPTSTR)szTempBuff); + + chKeep = szTempBuff[cch]; + szTempBuff[cch] = TEXT('\0'); + + GetTextExtentPoint(hDCScreen, szTempBuff, lstrlen(szTempBuff),&size); + + cxFirstLine = size.cx; + cyFirstLine = size.cy; + + while (cxFirstLine > cxMaxString) + { + // We allow 40 characters in the label, but the metafile is + // only as wide as 10 W's (for aesthetics - 20 W's wide looked + // dumb. This means that if we split a long string in half (in + // terms of characters), then we could still be wider than the + // metafile. So, if this is the case, we just step backwards + // from the halfway point until we get something that will fit. + // Since we just let ETO clip the second line + + szTempBuff[cch--] = chKeep; + if (0 == cch) + goto CleanupAndLeave; + + chKeep = szTempBuff[cch]; + szTempBuff[cch] = TEXT('\0'); + + GetTextExtentPoint( + hDCScreen, szTempBuff, lstrlen(szTempBuff), &size); + cxFirstLine = size.cx; + } + + iLastLineStart = cch; + + if (!fPrintText) + goto CleanupAndLeave; + + ExtTextOut(hDC, + nXStart + (lpRect->right - cxFirstLine) / 2, + nYStart, + fuOptions, + lpRect, + (LPTSTR)szTempBuff, + lstrlen((LPTSTR)szTempBuff), + lpDX); + + szTempBuff[cch] = chKeep; + lpszSecondLine = szTempBuff; + lpszSecondLine += cch ; + + GetTextExtentPoint( + hDCScreen, (LPTSTR)lpszSecondLine, lstrlen(lpszSecondLine), &size); + + // If the second line is wider than the rectangle, we + // just want to clip the text. + cxSecondLine = min(size.cx, cxMaxString); + + ExtTextOut(hDC, + nXStart + (lpRect->right - cxSecondLine) / 2, + nYStart + cyFirstLine, + fuOptions, + lpRect, + lpszSecondLine, + lstrlen(lpszSecondLine), + lpDX); + +CleanupAndLeave: + SelectObject(hDCScreen, hFontT); + ReleaseDC(NULL, hDCScreen); + return iLastLineStart; + +} + diff --git a/private/oleutest/letest/ole2ui/geticon.h b/private/oleutest/letest/ole2ui/geticon.h new file mode 100644 index 000000000..223411385 --- /dev/null +++ b/private/oleutest/letest/ole2ui/geticon.h @@ -0,0 +1,18 @@ +// This file is now OBSOLETE (include olestd.h instead) +/* + * GETICON.H + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +/************************************************************************* +** +** The following API's are now OBSOLETE because equivalent API's have been +** added to the OLE2.DLL library +** GetIconOfFile superceeded by OleGetIconOfFile +** GetIconOfClass superceeded by OleGetIconOfClass +** OleUIMetafilePictFromIconAndLabel +** superceeded by OleMetafilePictFromIconAndLabel +*************************************************************************/ + +// Other function prototypes moved to olestd.h diff --git a/private/oleutest/letest/ole2ui/hatch.c b/private/oleutest/letest/ole2ui/hatch.c new file mode 100644 index 000000000..1e156a1e0 --- /dev/null +++ b/private/oleutest/letest/ole2ui/hatch.c @@ -0,0 +1,325 @@ +/* + * HATCH.C + * + * Miscellaneous API's to generate hatch window for in-place active + * objects. This is part of the OLE 2.0 User Interface Support Library. + * + * Copyright (c)1993 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" + +// offsets in the extra bytes stored with the hatch window +#define EB_HATCHWIDTH 0 +#define EB_HATCHRECT_LEFT 2 +#define EB_HATCHRECT_TOP 4 +#define EB_HATCHRECT_RIGHT 6 +#define EB_HATCHRECT_BOTTOM 8 + +// class name of hatch window +#define CLASS_HATCH TEXT("Hatch Window") + +// local function prototypes +LRESULT FAR PASCAL EXPORT HatchWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); + + +/* + * HatchRegisterClass + * + * Purpose: + * Register the hatch window + * + * Parameters: + * hInst Process instance + * + * Return Value: + * TRUE if successful + * FALSE if failed + * + */ +STDAPI_(BOOL) RegisterHatchWindowClass(HINSTANCE hInst) +{ + WNDCLASS wc; + + // Register Hatch Window Class + wc.style = CS_BYTEALIGNWINDOW; + wc.lpfnWndProc = HatchWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 5 * sizeof(int); // extra bytes stores + // uHatchWidth + // rcHatchRect + wc.hInstance = hInst; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = CLASS_HATCH; + + if (!RegisterClass(&wc)) + return FALSE; + else + return TRUE; +} + + +/* + * CreateHatchWindow + * + * Purpose: + * Create the hatch window + * + * Parameters: + * hWndParent parent of hatch window + * hInst instance handle + * + * Return Value: + * pointer to hatch window if successful + * NULL if failed + * + */ +STDAPI_(HWND) CreateHatchWindow(HWND hWndParent, HINSTANCE hInst) +{ + HWND hWnd; + + if (!hWndParent || !hInst) + return NULL; + + hWnd = CreateWindow( + CLASS_HATCH, + TEXT("Hatch Window"), + WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + 0, 0, 0, 0, + hWndParent, + (HMENU)NULL, + hInst, + 0L + ); + + if (!hWnd) + return NULL; + + return hWnd; +} + +/* + * GetHatchWidth + * + * Purpose: + * Get width of hatch border + * + * Parameters: + * hWndHatch hatch window handle + * + * Return Value: + * width of the hatch border + */ +STDAPI_(UINT) GetHatchWidth(HWND hWndHatch) +{ + if (!IsWindow(hWndHatch)) + return 0; + + return (UINT)GetWindowWord(hWndHatch, EB_HATCHWIDTH); +} + +/* + * GetHatchRect + * + * Purpose: + * Get hatch rect. this is the size of the hatch window if it were + * not clipped by the ClipRect. + * + * Parameters: + * hWndHatch hatch window handle + * lprcHatchRect hatch rect + * + * Return Value: + * none + */ +STDAPI_(void) GetHatchRect(HWND hWndHatch, LPRECT lprcHatchRect) +{ + if (!IsWindow(hWndHatch)) { + SetRect(lprcHatchRect, 0, 0, 0, 0); + return; + } + + lprcHatchRect->left = GetWindowWord(hWndHatch, EB_HATCHRECT_LEFT); + lprcHatchRect->top = GetWindowWord(hWndHatch, EB_HATCHRECT_TOP); + lprcHatchRect->right = GetWindowWord(hWndHatch, EB_HATCHRECT_RIGHT); + lprcHatchRect->bottom = GetWindowWord(hWndHatch, EB_HATCHRECT_BOTTOM); +} + + +/* SetHatchRect + * + * + * Purpose: + * Store hatch rect with HatchRect window. + * this rect is the size of the hatch window if it were + * not clipped by the ClipRect. + * + * Parameters: + * hWndHatch hatch window handle + * lprcHatchRect hatch rect + * + * Return Value: + * none + */ +STDAPI_(void) SetHatchRect(HWND hWndHatch, LPRECT lprcHatchRect) +{ + if (!IsWindow(hWndHatch)) + return; + + SetWindowWord(hWndHatch, EB_HATCHRECT_LEFT, (WORD)lprcHatchRect->left); + SetWindowWord(hWndHatch, EB_HATCHRECT_TOP, (WORD)lprcHatchRect->top); + SetWindowWord(hWndHatch, EB_HATCHRECT_RIGHT, (WORD)lprcHatchRect->right); + SetWindowWord(hWndHatch, EB_HATCHRECT_BOTTOM,(WORD)lprcHatchRect->bottom); +} + + +/* SetHatchWindowSize + * + * + * Purpose: + * Move/size the HatchWindow correctly given the rect required by the + * in-place server object window and the lprcClipRect imposed by the + * in-place container. both rect's are expressed in the client coord. + * of the in-place container's window (which is the parent of the + * HatchWindow). + * + * OLE2NOTE: the in-place server must honor the lprcClipRect specified + * by its in-place container. it must NOT draw outside of the ClipRect. + * in order to achieve this, the hatch window is sized to be + * exactly the size that should be visible (rcVisRect). the + * rcVisRect is defined as the intersection of the full size of + * the HatchRect window and the lprcClipRect. + * the ClipRect could infact clip the HatchRect on the + * right/bottom and/or on the top/left. if it is clipped on the + * right/bottom then it is sufficient to simply resize the hatch + * window. but if the HatchRect is clipped on the top/left then + * in-place server document window (child of HatchWindow) must be moved + * by the delta that was clipped. the window origin of the + * in-place server window will then have negative coordinates relative + * to its parent HatchWindow. + * + * Parameters: + * hWndHatch hatch window handle + * lprcIPObjRect full size of in-place server object window + * lprcClipRect clipping rect imposed by in-place container + * lpptOffset offset required to position in-place server object + * window properly. caller should call: + * OffsetRect(&rcObjRect,lpptOffset->x,lpptOffset->y) + * + * Return Value: + * none + */ +STDAPI_(void) SetHatchWindowSize( + HWND hWndHatch, + LPRECT lprcIPObjRect, + LPRECT lprcClipRect, + LPPOINT lpptOffset +) +{ + RECT rcHatchRect; + RECT rcVisRect; + UINT uHatchWidth; + POINT ptOffset; + + if (!IsWindow(hWndHatch)) + return; + + rcHatchRect = *lprcIPObjRect; + uHatchWidth = GetHatchWidth(hWndHatch); + InflateRect((LPRECT)&rcHatchRect, uHatchWidth + 1, uHatchWidth + 1); + + IntersectRect((LPRECT)&rcVisRect, (LPRECT)&rcHatchRect, lprcClipRect); + MoveWindow( + hWndHatch, + rcVisRect.left, + rcVisRect.top, + rcVisRect.right-rcVisRect.left, + rcVisRect.bottom-rcVisRect.top, + TRUE /* fRepaint */ + ); + InvalidateRect(hWndHatch, NULL, TRUE); + + ptOffset.x = -rcHatchRect.left + (rcHatchRect.left - rcVisRect.left); + ptOffset.y = -rcHatchRect.top + (rcHatchRect.top - rcVisRect.top); + + /* convert the rcHatchRect into the client coordinate system of the + ** HatchWindow itself + */ + OffsetRect((LPRECT)&rcHatchRect, ptOffset.x, ptOffset.y); + + SetHatchRect(hWndHatch, (LPRECT)&rcHatchRect); + + // calculate offset required to position in-place server doc window + lpptOffset->x = ptOffset.x; + lpptOffset->y = ptOffset.y; +} + + +/* + * HatchWndProc + * + * Purpose: + * WndProc for hatch window + * + * Parameters: + * hWnd + * Message + * wParam + * lParam + * + * Return Value: + * message dependent + */ +LRESULT FAR PASCAL EXPORT HatchWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + int nBorderWidth; + + switch (Message) { + + case WM_CREATE: + nBorderWidth = GetProfileInt( + TEXT("windows"), + TEXT("oleinplaceborderwidth"), + DEFAULT_HATCHBORDER_WIDTH + ); + SetWindowWord(hWnd, EB_HATCHWIDTH, (WORD)nBorderWidth); + break; + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + RECT rcHatchRect; + + nBorderWidth = GetHatchWidth(hWnd); + hDC = BeginPaint(hWnd, &ps); + GetHatchRect(hWnd, (LPRECT)&rcHatchRect); + OleUIDrawShading(&rcHatchRect, hDC, OLEUI_SHADE_BORDERIN, + nBorderWidth); + InflateRect((LPRECT)&rcHatchRect, -nBorderWidth, -nBorderWidth); + OleUIDrawHandles(&rcHatchRect, hDC, OLEUI_HANDLES_OUTSIDE, + nBorderWidth+1, TRUE); + EndPaint(hWnd, &ps); + break; + } + + /* OLE2NOTE: Any window that is used during in-place activation + ** must handle the WM_SETCURSOR message or else the cursor + ** of the in-place parent will be used. if WM_SETCURSOR is + ** not handled, then DefWindowProc sends the message to the + ** window's parent. + */ + case WM_SETCURSOR: + SetCursor(LoadCursor( NULL, MAKEINTRESOURCE(IDC_ARROW) ) ); + return (LRESULT)TRUE; + + default: + return DefWindowProc(hWnd, Message, wParam, lParam); + } + + return 0L; +} diff --git a/private/oleutest/letest/ole2ui/hivgares.bmp b/private/oleutest/letest/ole2ui/hivgares.bmp Binary files differnew file mode 100644 index 000000000..0011166da --- /dev/null +++ b/private/oleutest/letest/ole2ui/hivgares.bmp diff --git a/private/oleutest/letest/ole2ui/icon.c b/private/oleutest/letest/ole2ui/icon.c new file mode 100644 index 000000000..048a991fe --- /dev/null +++ b/private/oleutest/letest/ole2ui/icon.c @@ -0,0 +1,857 @@ +/* + * ICON.C + * + * Implements the OleUIChangeIcon function which invokes the complete + * Change Icon dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "common.h" +#include "utility.h" +#include "icon.h" +#include "geticon.h" + +/* + * 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) + { + UINT uRet; + HGLOBAL hMemDlg=NULL; + + uRet=UStandardValidation((LPOLEUISTANDARD)lpCI, sizeof(OLEUICHANGEICON) + , &hMemDlg); + + if (OLEUI_SUCCESS!=uRet) + return uRet; + +#if defined( OBSOLETE ) + if (NULL==lpCI->hMetaPict) + uRet=OLEUI_CIERR_MUSTHAVECURRENTMETAFILE; +#endif + + if (lpCI->dwFlags & CIF_USEICONEXE) + { + if ( (NULL == lpCI->szIconExe) + || (IsBadReadPtr(lpCI->szIconExe, lpCI->cchIconExe)) + || (IsBadWritePtr(lpCI->szIconExe, lpCI->cchIconExe)) ) + uRet = OLEUI_CIERR_SZICONEXEINVALID; + + } + + // REVIEW: how do we validate the CLSID? +/* + if ('\0'==*((LPSTR)&lpCI->clsid)) + uRet=OLEUI_CIERR_MUSTHAVECLSID; +*/ + if (OLEUI_ERR_STANDARDMIN <= uRet) + { + if (NULL!=hMemDlg) + FreeResource(hMemDlg); + + return uRet; + } + + //Now that we've validated everything, we can invoke the dialog. + return UStandardInvocation(ChangeIconDialogProc, (LPOLEUISTANDARD)lpCI + , hMemDlg, MAKEINTRESOURCE(IDD_CHANGEICON)); + } + + + + + +/* + * ChangeIconDialogProc + * + * Purpose: + * Implements the OLE Change Icon dialog as invoked through the + * OleUIChangeIcon function. + * + * Parameters: + * Standard + * + * Return Value: + * Standard + */ + +BOOL CALLBACK EXPORT ChangeIconDialogProc(HWND hDlg, UINT iMsg + , WPARAM wParam, LPARAM lParam) + { + LPCHANGEICON lpCI; + HICON hIcon; + HGLOBAL hMetaPict; + BOOL fOK=FALSE; + UINT uRet=0; + LPTSTR psz; + TCHAR szTemp[OLEUI_CCHPATHMAX]; + + //Declare Win16/Win32 compatible WM_COMMAND parameters. + COMMANDPARAMS(wID, wCode, hWndMsg); + + 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) + { + //Insure that icons are properly destroyed. + SendDlgItemMessage(hDlg, ID_ICONLIST, LB_RESETCONTENT, 0, 0L); + + StandardCleanup(lpCI, hDlg); + EndDialog(hDlg, wParam); + return TRUE; + } + + switch (iMsg) + { + 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: + //Free the GDI object for the item + DestroyIcon((HICON)LOWORD(((LPDELETEITEMSTRUCT)lParam)->itemData)); + break; + + + case WM_COMMAND: + switch (wID) + { + case ID_CURRENT: + case ID_DEFAULT: + case ID_FROMFILE: + UpdateResultIcon(lpCI, hDlg, wID); + break; + + case ID_LABELEDIT: + //When the edit loses focus, update the result display + if (EN_KILLFOCUS==wCode) + { + GetDlgItemText(hDlg, ID_LABELEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR)); + SetDlgItemText(hDlg, ID_RESULTLABEL, szTemp); + } + break; + + case ID_FROMFILEEDIT: + //If the text changed, remove any selection in the list. + GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR)); + + if (lpCI && lstrcmpi(szTemp, lpCI->szFile)) + { + SendDlgItemMessage(hDlg, ID_ICONLIST, LB_SETCURSEL + , (WPARAM)-1, 0); + + //Also force selection of ID_FROMFILE + CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_FROMFILE); + } + break; + + + case ID_ICONLIST: + switch (wCode) + { + case LBN_SETFOCUS: + //If we got the focus, see about updating. + GetDlgItemText(hDlg, ID_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, ID_ICONLIST, lpCI->szFile); + UpdateResultIcon(lpCI, hDlg, ID_FROMFILE); + } + break; + + case LBN_SELCHANGE: + UpdateResultIcon(lpCI, hDlg, ID_FROMFILE); + break; + + case LBN_DBLCLK: + //Same as pressing OK. + SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg); + break; + } + break; + + + case ID_BROWSE: + { + DWORD dwOfnFlags; + + /* + * 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 ID_BROWSE to customize the dialog and from + * trying to figure out what we do after we have the name. + */ + + //Copy for reference + LSTRCPYN(szTemp, lpCI->szFile, sizeof(szTemp)/sizeof(TCHAR)); + + uRet=UStandardHook(lpCI, hDlg, uMsgBrowse, OLEUI_CCHPATHMAX_SIZE + , (LONG)(LPSTR)lpCI->szFile); + + dwOfnFlags = OFN_FILEMUSTEXIST; + if (lpCI->lpOCI->dwFlags & CIF_SHOWHELP) + dwOfnFlags |= OFN_SHOWHELP; + + if (0==uRet) + uRet=(BOOL)Browse(hDlg, lpCI->szFile, NULL, OLEUI_CCHPATHMAX_SIZE, IDS_ICONFILTERS, dwOfnFlags); + + /* + * Only reinitialize if the file changed, so if we got + * TRUE from the hook but the user hit Cancel, we don't + * spend time unecessarily refilling the list. + */ + if (0!=uRet && 0!=lstrcmpi(szTemp, lpCI->szFile)) + { + CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_FROMFILE); + SetDlgItemText(hDlg, ID_FROMFILEEDIT, lpCI->szFile); + UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile); + UpdateResultIcon(lpCI, hDlg, ID_FROMFILE); + } + } + break; + + + case IDOK: + /* + * If the user pressed enter, compare the current file + * and the one we have stored. If they match, then + * refill the listbox instead of closing down. This is + * so the user can press Enter in the edit control as + * they would expect to be able to do. + */ + GetDlgItemText(hDlg, ID_FROMFILEEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR)); + + //Check if the file changed at all. + if (0!=lstrcmpi(szTemp, lpCI->szFile)) + { + lstrcpy(lpCI->szFile, szTemp); + UFillIconList(hDlg, ID_ICONLIST, lpCI->szFile); + UpdateResultIcon(lpCI, hDlg, ID_FROMFILE); + + //Eat this message to prevent focus change. + return TRUE; + } + + // Check if the file name is valid + // (if FromFile is enabled) + if (ID_FROMFILE & lpCI->dwFlags) + { + OFSTRUCT of; + HWND hWnd; + if (HFILE_ERROR==DoesFileExist(lpCI->szFile, &of)) + { + OpenFileError(hDlg, of.nErrCode, lpCI->szFile); + hWnd = GetDlgItem(hDlg, ID_FROMFILEEDIT); + SetFocus(hWnd); + SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + return TRUE; // eat this message + } + } + + if ((HWND)LOWORD(lParam) != GetFocus()) + SetFocus((HWND)LOWORD(lParam)); + + /* + * On closing, create a new metafilepict with the + * current icon and label, destroying the old structure. + * + * Since we make a copy of the icon by placing it into + * the metafile, we have to make sure we delete the + * icon in the current field. When the listbox is + * destroyed WM_DELETEITEMs will clean it up appropriately. + */ + + hIcon=(HICON)SendDlgItemMessage(hDlg, ID_RESULTICON + , STM_GETICON, 0, 0L); + + /* + * If default is selected then we get the source + * information from registrion database for the + * current class to put in the metafile. If current + * is selected the we just retrieve the original file + * again and recreate the metafile. If from file is + * selected we use the current filename from the + * control and the current listbox selection. + */ + + psz=lpCI->szFile; + + if (lpCI->dwFlags & CIF_SELECTDEFAULT) + { + psz=lpCI->szDefIconFile; + lpCI->iIcon=lpCI->iDefIcon; + hIcon=lpCI->hDefIcon; + } + + if (lpCI->dwFlags & CIF_SELECTCURRENT) + { + //Go get the current icon source back. + OleUIMetafilePictExtractIconSource(lpCI->lpOCI->hMetaPict + , psz, &lpCI->iIcon); + } + + if (lpCI->dwFlags & CIF_SELECTFROMFILE) + { + GetDlgItemText(hDlg, ID_FROMFILEEDIT, psz, OLEUI_CCHPATHMAX); + + lpCI->iIcon=(UINT)SendDlgItemMessage(hDlg + , ID_ICONLIST, LB_GETCURSEL, 0, 0L); + } + + + //Get the label and go create the metafile + GetDlgItemText(hDlg, ID_LABELEDIT, szTemp, sizeof(szTemp)/sizeof(TCHAR)); + + //If psz is NULL (default) we get no source comments. + +#ifdef OLE201 + hMetaPict=OleUIMetafilePictFromIconAndLabel(hIcon, + szTemp, psz, lpCI->iIcon); +#endif + + //Clean up the current icon that we extracted. + hIcon=(HICON)SendDlgItemMessage(hDlg, ID_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); + + if (NULL==hMetaPict) + SendMessage(hDlg, uMsgEndDialog, OLEUI_FALSE, 0L); + + OleUIMetafilePictIconFree(lpCI->lpOCI->hMetaPict); + lpCI->lpOCI->hMetaPict=hMetaPict; + + lpCI->lpOCI->dwFlags = lpCI->dwFlags; + + SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L); + break; + + + case IDCANCEL: + //Clean up the current icon that we extracted. + hIcon=(HICON)SendDlgItemMessage(hDlg, ID_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 ID_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)); + } + } + 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) + { + LPCHANGEICON lpCI; + LPOLEUICHANGEICON lpOCI; + HFONT hFont; + HWND hList; + UINT cyList; + RECT rc, rcG; + UINT uID; + + //1. Copy the structure at lParam into our instance memory. + lpCI=(LPCHANGEICON)LpvStandardInit(hDlg, sizeof(CHANGEICON), TRUE, &hFont); + + //PvStandardInit send a termination to us already. + if (NULL==lpCI) + return FALSE; + + //Save the original pointer and copy necessary information. + lpOCI=(LPOLEUICHANGEICON)lParam; + + lpCI->lpOCI =lpOCI; + lpCI->dwFlags=lpOCI->dwFlags; + + //Go extract the icon source from the metafile. + OleUIMetafilePictExtractIconSource(lpOCI->hMetaPict, lpCI->szFile, &lpCI->iIcon); + + //Go extract the icon and the label from the metafile + OleUIMetafilePictExtractLabel(lpOCI->hMetaPict, lpCI->szLabel, OLEUI_CCHLABELMAX_SIZE, NULL); + lpCI->hCurIcon=OleUIMetafilePictExtractIcon(lpOCI->hMetaPict); + + //2. If we got a font, send it to the necessary controls. + if (NULL!=hFont) + { + SendDlgItemMessage(hDlg, ID_RESULTLABEL, WM_SETFONT + , (WPARAM)hFont, 0L); + } + + + //3. Show or hide the help button + if (!(lpCI->dwFlags & CIF_SHOWHELP)) + StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE); + + + /* + * 4. Set text limits and initial control values. If we're given + * an intial label we set it in the edit and static controls. + * If we don't, then we copy the default contents of the static + * control into the edit control, meaning that only the default + * static control string need be localized. + */ + + SendDlgItemMessage(hDlg, ID_LABELEDIT, EM_LIMITTEXT, OLEUI_CCHLABELMAX, 0L); + SendDlgItemMessage(hDlg, ID_FROMFILEEDIT, EM_LIMITTEXT, OLEUI_CCHPATHMAX, 0L); + SetDlgItemText(hDlg, ID_FROMFILEEDIT, lpCI->szFile); + + //Copy the label text into the edit and static controls. + SetDlgItemText(hDlg, ID_LABELEDIT, lpCI->szLabel); + SetDlgItemText(hDlg, ID_RESULTLABEL, lpCI->szLabel); + + + lpCI->hDefIcon = NULL; + + if (lpCI->dwFlags & CIF_USEICONEXE) + { + lpCI->hDefIcon = ExtractIcon(ghInst, lpCI->lpOCI->szIconExe, 0); + + if (NULL != lpCI->hDefIcon) + { + lstrcpy(lpCI->szDefIconFile, lpCI->lpOCI->szIconExe); + lpCI->iDefIcon = 0; + } + } + + + if (NULL == lpCI->hDefIcon) + { + HGLOBAL hMetaPict; + +#ifdef OLE201 + hMetaPict = GetIconOfClass(ghInst, + &lpCI->lpOCI->clsid, + NULL, + TRUE); +#endif + + lpCI->hDefIcon = OleUIMetafilePictExtractIcon(hMetaPict); + + OleUIMetafilePictExtractIconSource(hMetaPict, + lpCI->szDefIconFile, + &lpCI->iDefIcon); + + OleUIMetafilePictIconFree(hMetaPict); + } + + + //Initialize all the icon displays. + SendDlgItemMessage(hDlg, ID_CURRENTICON, STM_SETICON + , (WPARAM)lpCI->hCurIcon, 0L); + SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_SETICON + , (WPARAM)lpCI->hDefIcon, 0L); + SendDlgItemMessage(hDlg, ID_RESULTICON, STM_SETICON + , (WPARAM)lpCI->hCurIcon, 0L); + + + /* + * 5. 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). + */ + cyList=GetSystemMetrics(SM_CYICON)+GetSystemMetrics(SM_CYHSCROLL) + +GetSystemMetrics(SM_CYBORDER)*2+CYICONPAD; + + hList=GetDlgItem(hDlg, ID_ICONLIST); + 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); + + /* + * 5a. 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); + GetWindowRect(GetDlgItem(hDlg, ID_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, ID_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, ID_LABEL), &rc); + SetWindowPos(GetDlgItem(hDlg, ID_LABEL), NULL, 0, cyList + , rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER); + + GetClientRect(GetDlgItem(hDlg, ID_LABELEDIT), &rc); + SetWindowPos(GetDlgItem(hDlg, ID_LABELEDIT), NULL, 0, cyList + , rc.right, rc.bottom, SWP_NOSIZE | SWP_NOZORDER); + } + + + /* + * 6. 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, ID_ICONLIST, lpCI->szFile)) + { + //If szFile worked, then select the source icon in the listbox. + SendDlgItemMessage(hDlg, ID_ICONLIST, LB_SETCURSEL, lpCI->iIcon, 0L); + } + + + if (lpCI->dwFlags & CIF_SELECTCURRENT) + CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, ID_CURRENT); + else + { + uID=(lpCI->dwFlags & CIF_SELECTFROMFILE) ? ID_FROMFILE : ID_DEFAULT; + CheckRadioButton(hDlg, ID_CURRENT, ID_FROMFILE, uID); + } + + //7. 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); + + //8. 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) + { + HWND hList; + UINT i; + UINT cIcons=0; + HCURSOR hCur; + HICON hIcon; + OFSTRUCT of; + + if (NULL==hDlg || !IsWindow(hDlg) || NULL==pszFile) + return 0; + + 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 + hCur=HourGlassOn(); + + //Check if the file is valid. + if (HFILE_ERROR!=DoesFileExist(pszFile, &of)) + { + #ifdef EXTRACTICONWORKS + //Get the icon count for this file. + cIcons=(UINT)ExtractIcon(ghInst, pszFile, (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=ExtractIcon(ghInst, pszFile, 0); + + //Fake a failure with cIcons=0, or cleanup hIcon from this test. + if (32 > (UINT)hIcon) + cIcons=0; + else + DestroyIcon(hIcon); + #endif + + if (0!=cIcons) + { + SendMessage(hList, WM_SETREDRAW, FALSE, 0L); + + for (i=0; i<cIcons; i++) + { + hIcon=ExtractIcon(ghInst, pszFile, i); + + if (32 < (UINT)hIcon) + SendMessage(hList, LB_ADDSTRING, 0, (LONG)(UINT)hIcon); + #ifndef EXTRACTICONWORKS + else + { + //ExtractIcon failed, so let's leave now. + break; + } + #endif + } + + //Force complete repaint + SendMessage(hList, WM_SETREDRAW, TRUE, 0L); + InvalidateRect(hList, NULL, TRUE); + + //Select an icon + SendMessage(hList, LB_SETCURSEL, 0, 0L); + } + else + ErrorWithFile(hDlg, ghInst, IDS_CINOICONSINFILE, pszFile, MB_OK); + } + else + OpenFileError(hDlg, of.nErrCode, pszFile); + + 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) + { + COLORREF cr; + + /* + * 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)) + { + //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)LOWORD(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) + { + UINT iSel; + LONG lTemp=LB_ERR; + + lpCI->dwFlags &= ~(CIF_SELECTCURRENT | CIF_SELECTDEFAULT | CIF_SELECTFROMFILE); + + switch (uID) + { + case ID_CURRENT: + lTemp=SendDlgItemMessage(hDlg, ID_CURRENTICON, STM_GETICON, 0, 0L); + lpCI->dwFlags |= CIF_SELECTCURRENT; + break; + + case ID_DEFAULT: + lTemp=SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_GETICON, 0, 0L); + lpCI->dwFlags |= CIF_SELECTDEFAULT; + break; + + case ID_FROMFILE: + //Get the selected icon from the list and place it in the result + lpCI->dwFlags |= CIF_SELECTFROMFILE; + + iSel=(UINT)SendDlgItemMessage(hDlg, ID_ICONLIST, LB_GETCURSEL, 0, 0L); + if ((UINT)LB_ERR==iSel) + lTemp=SendDlgItemMessage(hDlg, ID_DEFAULTICON, STM_GETICON, 0, 0L); + else + SendDlgItemMessage(hDlg, ID_ICONLIST, LB_GETTEXT, iSel + , (LPARAM)(LPLONG)&lTemp); + + break; + } + + if ((LONG)LB_ERR!=lTemp) + SendDlgItemMessage(hDlg, ID_RESULTICON, STM_SETICON, LOWORD(lTemp), 0L); + return; + } + + diff --git a/private/oleutest/letest/ole2ui/icon.dlg b/private/oleutest/letest/ole2ui/icon.dlg new file mode 100644 index 000000000..43a2f274c --- /dev/null +++ b/private/oleutest/letest/ole2ui/icon.dlg @@ -0,0 +1,48 @@ +// DLGINCLUDE RCDATA DISCARDABLE +// BEGIN +// "OLE2UI.H\0" +// END + + +IDD_CHANGEICON DIALOG 18, 18, 261, 152 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Change Icon" +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Icon", ID_GROUP, 4, 6, 180, 124 + CONTROL "&Current", ID_CURRENT, "Button", BS_AUTORADIOBUTTON | + WS_GROUP , 10, 19, 46, 10 + + CONTROL "&Default", ID_DEFAULT, "Button", BS_AUTORADIOBUTTON, + 10, 44, 46, 10 + + CONTROL "&From File:", ID_FROMFILE, "Button", BS_AUTORADIOBUTTON, + 10, 68, 46, 10 + + ICON "", ID_CURRENTICON, 58, 15, 18, 20 + + ICON "", ID_DEFAULTICON, 58, 40, 18, 20 + + EDITTEXT ID_FROMFILEEDIT, 58, 68, 119, 12, ES_LOWERCASE | + ES_AUTOHSCROLL | WS_GROUP | ES_OEMCONVERT + + LISTBOX ID_ICONLIST, 58, 84, 119, 40, LBS_OWNERDRAWFIXED | + LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_HSCROLL | + WS_TABSTOP + + LTEXT "&Label:", ID_LABEL, 6, 138, 32, 8 + + EDITTEXT ID_LABELEDIT, 38, 136, 146, 12, ES_AUTOHSCROLL + + DEFPUSHBUTTON "OK", IDOK, 189, 6, 66, 14 + + PUSHBUTTON "Cancel", IDCANCEL, 189, 23, 66, 14 + + PUSHBUTTON "&Browse...", ID_BROWSE, 189, 41, 66, 14 + + PUSHBUTTON "&Help", ID_OLEUIHELP, 189, 59, 66, 14 + + CTEXT "", ID_RESULTLABEL, 193, 114, 63, 24 + ICON "", ID_RESULTICON, 214, 90, 18, 20 +END + diff --git a/private/oleutest/letest/ole2ui/icon.h b/private/oleutest/letest/ole2ui/icon.h new file mode 100644 index 000000000..512155949 --- /dev/null +++ b/private/oleutest/letest/ole2ui/icon.h @@ -0,0 +1,59 @@ +/* + * ICON.H + * + * Internal definitions, structures, and function prototypes for the + * OLE 2.0 UI Change Icon dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + + +#ifndef _ICON_H_ +#define _ICON_H_ + +#ifndef RC_INVOKED +#pragma message ("INCLUDING ICON.H from " __FILE__) +#endif /* RC_INVOKED */ + +#define CXICONPAD 12 +#define CYICONPAD 4 + +// Property used by ChangeIcon dialog to give its parent window access to +// its hDlg. The PasteSpecial dialog may need to force the ChgIcon dialog +// down if the clipboard contents change underneath it. if so it will send +// a IDCANCEL command to the ChangeIcon dialog. +#define PROP_HWND_CHGICONDLG TEXT("HWND_CIDLG") + +//Internally used structure +typedef struct tagCHANGEICON + { + LPOLEUICHANGEICON lpOCI; //Original structure passed. + + /* + * 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[OLEUI_CCHPATHMAX]; + UINT iIcon; + HICON hDefIcon; + TCHAR szDefIconFile[OLEUI_CCHPATHMAX]; + UINT iDefIcon; + UINT nBrowseHelpID; // Help ID callback for Browse dlg + } CHANGEICON, *PCHANGEICON, FAR *LPCHANGEICON; + + +//Internal function prototypes +//ICON.C +BOOL CALLBACK EXPORT ChangeIconDialogProc(HWND, UINT, WPARAM, LPARAM); +BOOL FChangeIconInit(HWND, WPARAM, LPARAM); +UINT UFillIconList(HWND, UINT, LPTSTR); +BOOL FDrawListIcon(LPDRAWITEMSTRUCT); +void UpdateResultIcon(LPCHANGEICON, HWND, UINT); + + +#endif //_ICON_H_ diff --git a/private/oleutest/letest/ole2ui/iconbox.c b/private/oleutest/letest/ole2ui/iconbox.c new file mode 100644 index 000000000..8422f5dcc --- /dev/null +++ b/private/oleutest/letest/ole2ui/iconbox.c @@ -0,0 +1,253 @@ +/* + * ICONBOX.C + * + * 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 + */ + + +#define STRICT 1 +#include "ole2ui.h" +#include "iconbox.h" + + +//Flag indicating if we've registered the class +static BOOL fRegistered=FALSE; + + +/* + * 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. + * + * lpszClassName LPSTR containing the class name to register the + * IconBox control class with. + * + * Return Value: + * BOOL TRUE if all initialization succeeded, FALSE otherwise. + */ + +BOOL FIconBoxInitialize(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpszClassName) + { + WNDCLASS wc; + + // 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) + { + 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.lpszClassName =lpszClassName; + wc.style =CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW; + + fRegistered=RegisterClass(&wc); + } + } + + return fRegistered; +} + + +/* + * 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) + { + //Nothing to do. + 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 EXPORT IconBoxWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) + { + HGLOBAL hMF=NULL; + PAINTSTRUCT ps; + HDC hDC; + RECT rc; + + + //Handle standard Windows messages. + switch (iMsg) + { + case WM_CREATE: + SetWindowLong(hWnd, IBWW_HIMAGE, 0); + SetWindowWord(hWnd, IBWW_FLABEL, TRUE); + return 0L; + + + case WM_ERASEBKGND: + { + + HBRUSH hBrush; + RECT Rect; +#if defined( WIN32 ) + POINT point; +#endif + + GetClientRect(hWnd, &Rect); +#if defined( WIN32 ) + hBrush = (HBRUSH)SendMessage(GetParent(hWnd), + WM_CTLCOLORDLG, + wParam, + (LPARAM)GetParent(hWnd)); +#else + hBrush = (HBRUSH)SendMessage(GetParent(hWnd), + WM_CTLCOLOR, + wParam, + MAKELPARAM(GetParent(hWnd), CTLCOLOR_DLG)); +#endif + + + if (!hBrush) + return FALSE; + + UnrealizeObject(hBrush); + +#if defined( WIN32 ) + SetBrushOrgEx((HDC)wParam, 0, 0, &point); +#else + SetBrushOrg((HDC)wParam, 0, 0); +#endif + + FillRect((HDC)wParam, &Rect, hBrush); + + return TRUE; + } + + + case WM_PAINT: + hMF=(HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE); + + //BeginPaint and EndPaint clear us even if hMF is NULL. + hDC=BeginPaint(hWnd, &ps); + + if (NULL!=hMF) + { + BOOL fLabel; + + //Now we get to paint the metafile, centered in our rect. + 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. + */ + + 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 contains the new handle. + * lParam is a flag to delete the old or not. + */ + hMF=(HGLOBAL)SetWindowLong(hWnd, IBWW_HIMAGE, wParam); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + + //Delete the old handle if requested + if (0L!=lParam) + { + OleUIMetafilePictIconFree(hMF); + hMF=NULL; + } + + return (LONG)(UINT)hMF; + + + case IBXM_IMAGEGET: + //Return the current index. + hMF=(HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE); + return (LONG)(UINT)hMF; + + + case IBXM_IMAGEFREE: + //Free up whatever we're holding. + hMF=(HGLOBAL)GetWindowLong(hWnd, IBWW_HIMAGE); + OleUIMetafilePictIconFree(hMF); + 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/oleutest/letest/ole2ui/iconbox.h b/private/oleutest/letest/ole2ui/iconbox.h new file mode 100644 index 000000000..057b59e75 --- /dev/null +++ b/private/oleutest/letest/ole2ui/iconbox.h @@ -0,0 +1,31 @@ +/* + * 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, LPTSTR); +void IconBoxUninitialize(void); +LONG CALLBACK EXPORT 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/oleutest/letest/ole2ui/insobj.c b/private/oleutest/letest/ole2ui/insobj.c new file mode 100644 index 000000000..53fa094c9 --- /dev/null +++ b/private/oleutest/letest/ole2ui/insobj.c @@ -0,0 +1,1724 @@ +/* + * INSOBJ.C + * + * Implements the OleUIInsertObject function which invokes the complete + * Insert Object dialog. Makes use of the OleChangeIcon function in + * ICON.C. + * + * Copyright (c)1993 Microsoft Corporation, All Rights Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include <commdlg.h> +#include <memory.h> +#include <direct.h> +#include <malloc.h> +#include <dos.h> +#include <stdlib.h> +#include "common.h" +#include "utility.h" +#include "icon.h" +#include "insobj.h" +#include "resimage.h" +#include "iconbox.h" +#include "geticon.h" + +#define IS_FILENAME_DELIM(c) ( (c) == TEXT('\\') || (c) == TEXT('/') || (c) == TEXT(':') ) + +/* + * 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) + { + UINT uRet; + HGLOBAL hMemDlg=NULL; + HRESULT hrErr; + + uRet=UStandardValidation((LPOLEUISTANDARD)lpIO, sizeof(OLEUIINSERTOBJECT) + , &hMemDlg); + + if (OLEUI_SUCCESS!=uRet) + return uRet; + + //Now we can do Insert Object specific validation. + + + // NULL is NOT valid for lpszFile + if ( (NULL == lpIO->lpszFile) + || (IsBadReadPtr(lpIO->lpszFile, lpIO->cchFile)) + || (IsBadWritePtr(lpIO->lpszFile, lpIO->cchFile)) ) + uRet=OLEUI_IOERR_LPSZFILEINVALID; + + if (NULL != lpIO->lpszFile + && (lpIO->cchFile <= 0 || lpIO->cchFile > OLEUI_CCHPATHMAX_SIZE)) + uRet=OLEUI_IOERR_CCHFILEINVALID; + + if (0!=lpIO->cClsidExclude) + { + if (NULL!=lpIO->lpClsidExclude && 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(lpIO->lpIOleClientSite->lpVtbl, sizeof(IOleClientSiteVtbl))) + uRet=OLEUI_IOERR_LPIOLECLIENTSITEINVALID; + + if (NULL!=lpIO->lpIStorage + && IsBadReadPtr(lpIO->lpIStorage->lpVtbl, sizeof(IStorageVtbl))) + uRet=OLEUI_IOERR_LPISTORAGEINVALID; + } + + if (OLEUI_ERR_STANDARDMIN <= uRet) + { + if (NULL!=hMemDlg) + FreeResource(hMemDlg); + + 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) && (lpIO->dwFlags & IOF_CREATENEWOBJECT)) + { + 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)) + { + hrErr=OleCreateFromFileA(&CLSID_NULL, lpIO->lpszFile, &lpIO->iid + , lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite + , lpIO->lpIStorage, lpIO->ppvObj); + lpIO->sc = GetScode(hrErr); + } + + if ((lpIO->dwFlags & IOF_CHECKLINK) && (lpIO->dwFlags & IOF_CREATELINKOBJECT)) + { + hrErr=OleCreateLinkToFileA(lpIO->lpszFile, &lpIO->iid + , lpIO->oleRender, lpIO->lpFormatEtc, lpIO->lpIOleClientSite + , lpIO->lpIStorage, lpIO->ppvObj); + 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 EXPORT InsertObjectDialogProc(HWND hDlg, UINT iMsg + , WPARAM wParam, LPARAM lParam) + { + LPOLEUIINSERTOBJECT lpOIO; + LPINSERTOBJECT lpIO; + OLEUICHANGEICON ci; + UINT i; + BOOL fCheck=FALSE; + UINT uRet=0; + + //Declare Win16/Win32 compatible WM_COMMAND parameters. + COMMANDPARAMS(wID, wCode, hWndMsg); + + //This will fail under WM_INITDIALOG, where we allocate it. + 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) + { + InsertObjectCleanup(hDlg); + StandardCleanup(lpIO, hDlg); + EndDialog(hDlg, wParam); + return TRUE; + } + + switch (iMsg) + { + case WM_INITDIALOG: + return FInsertObjectInit(hDlg, wParam, lParam); + + case WM_COMMAND: + switch (wID) + { + case ID_IO_CREATENEW: + FToggleObjectSource(hDlg, lpIO, IOF_SELECTCREATENEW); + break; + + case ID_IO_CREATEFROMFILE: + FToggleObjectSource(hDlg, lpIO, IOF_SELECTCREATEFROMFILE); + break; + + case ID_IO_LINKFILE: + 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 ID_IO_OBJECTTYPELIST: + switch (wCode) + { + case LBN_SELCHANGE: + UpdateClassIcon(hDlg, lpIO, hWndMsg); + SetInsertObjectResults(hDlg, lpIO); + break; + + case LBN_DBLCLK: + //Same as pressing OK. + SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg); + break; + } + break; + + + case ID_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)); + EnableWindow(GetDlgItem(hDlg, ID_IO_LINKFILE), lpIO->fFileSelected); + EnableWindow(GetDlgItem(hDlg, ID_IO_DISPLAYASICON), lpIO->fFileSelected); + EnableWindow(GetDlgItem(hDlg, ID_IO_CHANGEICON), lpIO->fFileSelected); + EnableWindow(GetDlgItem(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 ID_IO_DISPLAYASICON: + fCheck=IsDlgButtonChecked(hDlg, wID); + EnableWindow(GetDlgItem(hDlg, ID_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, ID_IO_OBJECTTYPELIST)); + + UpdateClassType(hDlg, lpIO, TRUE); + } + + else + { + HWND hWndEC; + + lpIO->fAsIconFile= FALSE; + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = FALSE; + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, 0, 0L); + UpdateClassType(hDlg, lpIO, FALSE); + + lpIO->dwFlags &=~IOF_CHECKDISPLAYASICON; + CheckDlgButton(hDlg, ID_IO_DISPLAYASICON, 0); + + hWndEC = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWndEC); + SendMessage(hWndEC, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + return TRUE; + } + } + else + UpdateClassIcon(hDlg, lpIO, + GetDlgItem(hDlg, ID_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. + */ + i=(fCheck) ? SW_SHOWNORMAL : SW_HIDE; + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, i); + StandardShowDlgItem(hDlg, ID_IO_ICONDISPLAY, i); + + break; + + + case ID_IO_CHANGEICON: + { + + LPMALLOC pIMalloc; + HWND hList; + LPTSTR pszString, pszCLSID; + + int iCurSel; + + // 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->fFileDirty = TRUE; + hWndEC = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWndEC); + SendMessage(hWndEC, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + return TRUE; + } + else + lpIO->fFileDirty = FALSE; + } + + + + //Initialize the structure for the hook. + _fmemset((LPOLEUICHANGEICON)&ci, 0, sizeof(ci)); + + ci.hMetaPict=(HGLOBAL)SendDlgItemMessage(hDlg + , ID_IO_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L); + + ci.cbStruct =sizeof(ci); + ci.hWndOwner=hDlg; + ci.dwFlags =CIF_SELECTCURRENT; + + if (lpIO->dwFlags & IOF_SHOWHELP) + ci.dwFlags |= CIF_SHOWHELP; + + + + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + // Initialize clsid... + if (NOERROR != CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return FALSE; + + pszString = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, + OLEUI_CCHKEYMAX_SIZE + + OLEUI_CCHCLSIDSTRING_SIZE); + + + hList = GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + iCurSel = (int)SendMessage(hList, LB_GETCURSEL, 0, 0L); + SendMessage(hList, LB_GETTEXT, iCurSel, (LONG)pszString); + + pszCLSID = PointerToNthField(pszString, 2, TEXT('\t')); + + CLSIDFromStringA((LPTSTR)pszCLSID, (LPCLSID)&(ci.clsid)); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszString); + pIMalloc->lpVtbl->Release(pIMalloc); + } + else // IOF_SELECTCREATEFROMFILE + { + + TCHAR szFileName[OLEUI_CCHPATHMAX]; + + GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, (LPTSTR)szFileName, OLEUI_CCHPATHMAX); + + if (NOERROR != GetClassFileA(szFileName, (LPCLSID)&(ci.clsid))) + { + LPTSTR lpszExtension; + int istrlen; + + istrlen = lstrlen(szFileName); + + lpszExtension = (LPTSTR)szFileName + istrlen -1; + + while ( (lpszExtension > szFileName) && + (*lpszExtension != TEXT('.')) ) + lpszExtension--; + + GetAssociatedExecutable(lpszExtension, (LPTSTR)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)(LPTSTR)&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, ID_IO_ICONDISPLAY, IBXM_IMAGESET + , (WPARAM)ci.hMetaPict, 0L); + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + SendMessage(hList, LB_SETITEMDATA, iCurSel, ci.hMetaPict); + } + } + break; + + + case ID_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 ID_IO_BROWSE to customize the dialog and from + * trying to figure out what we do after we have the name. + */ + + TCHAR szTemp[OLEUI_CCHPATHMAX]; + TCHAR szInitialDir[OLEUI_CCHPATHMAX]; + DWORD dwOfnFlags; + int nChars; + BOOL fUseInitialDir = FALSE; + + + nChars = GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, (LPTSTR)szTemp, OLEUI_CCHPATHMAX); + + if (FValidateInsertFile(hDlg, FALSE, &lpIO->nErrCode)) + { + + int istrlen; + + GetFileTitle((LPTSTR)szTemp, lpIO->szFile, OLEUI_CCHPATHMAX); + + istrlen = lstrlen(lpIO->szFile); + + LSTRCPYN((LPTSTR)szInitialDir, szTemp, nChars - istrlen); + fUseInitialDir = TRUE; + + } + else // file name isn't valid...lop off end of szTemp to get a + // valid directory + { +#if defined( WIN32 ) + TCHAR szBuffer[OLEUI_CCHPATHMAX]; + DWORD Attribs; + + LSTRCPYN(szBuffer, szTemp, OLEUI_CCHPATHMAX-1); + szBuffer[OLEUI_CCHPATHMAX-1] = TEXT('\0'); + + if (TEXT('\\') == szBuffer[nChars-1]) + szBuffer[nChars-1] = TEXT('\0'); + + Attribs = GetFileAttributes(szBuffer); + if (Attribs != 0xffffffff && + (Attribs & FILE_ATTRIBUTE_DIRECTORY) ) + { + lstrcpy(szInitialDir, (LPTSTR)szBuffer); + fUseInitialDir = TRUE; + } +#else + static TCHAR szBuffer[OLEUI_CCHPATHMAX]; + static int attrib ; + + LSTRCPYN(szBuffer, szTemp, OLEUI_CCHPATHMAX-1); + szBuffer[OLEUI_CCHPATHMAX-1] = TEXT('\0'); + + AnsiToOem(szBuffer, szBuffer); +#if defined( OBSOLETE ) // fix bug# 3575 + if (TEXT('\\') == szBuffer[nChars-1]) + szBuffer[nChars-1] = TEXT('\0'); + + if(0 == _dos_getfileattr(szBuffer, &attrib)) +#endif // OBSOLETE + { + lstrcpy(szInitialDir, (LPTSTR)szBuffer); + fUseInitialDir = TRUE; + } +#endif + *lpIO->szFile = TEXT('\0'); + } + + uRet=UStandardHook(lpIO, hDlg, uMsgBrowse + , OLEUI_CCHPATHMAX_SIZE, (LPARAM)(LPSTR)lpIO->szFile); + + dwOfnFlags = OFN_FILEMUSTEXIST; + + if (lpIO->lpOIO->dwFlags & IOF_SHOWHELP) + dwOfnFlags |= OFN_SHOWHELP; + + if (0==uRet) + uRet=(UINT)Browse(hDlg, + lpIO->szFile, + fUseInitialDir ? (LPTSTR)szInitialDir : NULL, + OLEUI_CCHPATHMAX_SIZE, + IDS_FILTERS, + dwOfnFlags); + + //Only update if the file changed. + if (0!=uRet && 0!=lstrcmpi(szTemp, lpIO->szFile)) + { + SetDlgItemText(hDlg, ID_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, ID_IO_FILEDISPLAY); + SetFocus(hWnd); + SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + } + + //Once we have a file, Display As Icon is always enabled + EnableWindow(GetDlgItem(hDlg, ID_IO_DISPLAYASICON), TRUE); + + //As well as OK + EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); + + } + } + break; + + + case IDOK: + { + HWND hListBox; + WORD iCurSel; + TCHAR szBuffer[OLEUI_CCHKEYMAX + OLEUI_CCHCLSIDSTRING]; + LPTSTR lpszCLSID; + + if ((HWND)(LOWORD(lParam)) != GetFocus()) + SetFocus((HWND)(LOWORD(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) + && (TRUE == 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, ID_IO_FILEDISPLAY); + SetFocus(hWnd); + SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + UpdateClassType(hDlg, lpIO, FALSE); + } + + return TRUE; // eat this message + } + else if ( (lpIO->dwFlags & IOF_SELECTCREATEFROMFILE) + && (FALSE == lpIO->fFileValid) ) + { + // filename is invalid - set focus back to ec + HWND hWnd; + TCHAR szFile[OLEUI_CCHPATHMAX]; + + if (0!=GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, + szFile, OLEUI_CCHPATHMAX)) + { + OpenFileError(hDlg, lpIO->nErrCode, szFile); + } + lpIO->fFileDirty = FALSE; + lpIO->fFileValid = FALSE; + hWnd = GetDlgItem(hDlg, ID_IO_FILEDISPLAY); + SetFocus(hWnd); + SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(0, (WORD)-1)); + UpdateClassType(hDlg, lpIO, FALSE); + return TRUE; // eat this message + } + + //Copy the necessary information back to the original struct + lpOIO=lpIO->lpOIO; + lpOIO->dwFlags=lpIO->dwFlags; + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + hListBox=GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + iCurSel=(WORD)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; + + SendMessage(hListBox, LB_GETTEXT, iCurSel + , (LPARAM)(LPTSTR)szBuffer); + + lpszCLSID=PointerToNthField((LPTSTR)szBuffer, 2, TEXT('\t')); + CLSIDFromStringA(lpszCLSID, &lpOIO->clsid); + + } + else // IOF_SELECTCREATEFROMFILE + { + if (lpIO->dwFlags & IOF_CHECKDISPLAYASICON) + { + // get metafile here + lpOIO->hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, + ID_IO_ICONDISPLAY, + IBXM_IMAGEGET, + 0, 0L); + + + } + else + lpOIO->hMetaPict = (HGLOBAL)NULL; + + } + + GetDlgItemText(hDlg, ID_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 ID_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)); + } + } + break; + } + + return FALSE; + } + + + + +/* + * 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) + { + LPOLEUIINSERTOBJECT lpOIO; + LPINSERTOBJECT lpIO; + RECT rc; + DWORD dw; + HFONT hFont; + HWND hList; + UINT u; + BOOL fCheck; + CHAR *pch; // pointer to current working directory + // ANSI string (to use with _getcwd) + + //1. Copy the structure at lParam into our instance memory. + lpIO=(LPINSERTOBJECT)LpvStandardInit(hDlg, sizeof(INSERTOBJECT), TRUE, &hFont); + + //PvStandardInit send a termination to us already. + if (NULL==lpIO) + return FALSE; + + lpOIO=(LPOLEUIINSERTOBJECT)lParam; + + //2. Save the original pointer and copy necessary information. + lpIO->lpOIO =lpOIO; + lpIO->dwFlags=lpOIO->dwFlags; + lpIO->clsid =lpOIO->clsid; + + if ( (lpOIO->lpszFile) && (TEXT('\0') != *lpOIO->lpszFile) ) + LSTRCPYN((LPTSTR)lpIO->szFile, lpOIO->lpszFile, OLEUI_CCHPATHMAX); + else + *(lpIO->szFile) = TEXT('\0'); + + lpIO->hMetaPictFile = (HGLOBAL)NULL; + + //3. If we got a font, send it to the necessary controls. + if (NULL!=hFont) + { + SendDlgItemMessage(hDlg, ID_IO_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L); + SendDlgItemMessage(hDlg, ID_IO_FILETYPE, WM_SETFONT, (WPARAM)hFont, 0L); + } + + + //4. Fill the Object Type listbox with entries from the reg DB. + hList=GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + UFillClassList(hList, lpOIO->cClsidExclude, lpOIO->lpClsidExclude + , (BOOL)(lpOIO->dwFlags & IOF_VERIFYSERVERSEXIST)); + + //Set the tab width in the list to push all the tabs off the side. + GetClientRect(hList, &rc); + dw=GetDialogBaseUnits(); + rc.right =(8*rc.right)/LOWORD(dw); //Convert pixels to 2x dlg units. + SendMessage(hList, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&rc.right); + + + //5. Initilize the file name display to cwd if we don't have any name. + if (TEXT('\0') == *(lpIO->szFile)) + { + TCHAR tch[OLEUI_CCHPATHMAX]; + + pch=_getcwd(NULL, OLEUI_CCHPATHMAX); + if (*(pch+strlen(pch)-1) != '\\') + strcat(pch, "\\"); // put slash on end of cwd +#ifdef UNICODE + mbstowcs(tch, pch, OLEUI_CCHPATHMAX); +#else + strcpy(tch, pch); +#endif + SetDlgItemText(hDlg, ID_IO_FILEDISPLAY, tch); + lpIO->fFileDirty = TRUE; // cwd is not a valid filename + #ifndef __TURBOC__ + free(pch); + #endif + } + else + { + SetDlgItemText(hDlg, ID_IO_FILEDISPLAY, lpIO->szFile); + + if (FValidateInsertFile(hDlg, FALSE, &lpIO->nErrCode)) + lpIO->fFileDirty = FALSE; + else + lpIO->fFileDirty = TRUE; + } + + + //6. Initialize the selected type radiobutton. + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + StandardShowDlgItem(hDlg, ID_IO_FILETEXT, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_FILETYPE, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_FILEDISPLAY, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_FILE, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_LINKFILE, SW_HIDE); + + CheckRadioButton(hDlg, ID_IO_CREATENEW, ID_IO_CREATEFROMFILE, ID_IO_CREATENEW); + + lpIO->fAsIconNew=(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)); + SetFocus(hList); + } + else + { + /* + * Use pszType as the initial File. If there's no initial + * file then we have to remove any check from Display As + * Icon. We also check Link if so indicated for this option. + */ + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPELIST, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPETEXT, SW_HIDE); + + // Don't preselect display as icon if the filename isn't valid + if (TRUE == lpIO->fFileDirty) + lpIO->dwFlags &= ~(IOF_CHECKDISPLAYASICON); + + if (IOF_DISABLELINK & lpIO->dwFlags) + StandardShowDlgItem(hDlg, ID_IO_LINKFILE, SW_HIDE); + else + { + CheckDlgButton(hDlg, ID_IO_LINKFILE + , (BOOL)(0L!=(lpIO->dwFlags & IOF_CHECKLINK))); + } + + CheckRadioButton(hDlg, ID_IO_CREATENEW, ID_IO_CREATEFROMFILE, ID_IO_CREATEFROMFILE); + + lpIO->fAsIconFile=(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)); + SetFocus(GetDlgItem(hDlg, ID_IO_FILEDISPLAY)); + } + + + //7. Initialize the Display as Icon state + fCheck=(BOOL)(lpIO->dwFlags & IOF_CHECKDISPLAYASICON); + u=fCheck ? SW_SHOWNORMAL : SW_HIDE; + + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, u); + StandardShowDlgItem(hDlg, ID_IO_ICONDISPLAY, u); + + CheckDlgButton(hDlg, ID_IO_DISPLAYASICON, fCheck); + + + //8. Show or hide the help button + if (!(lpIO->dwFlags & IOF_SHOWHELP)) + StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE); + + + //9. Initialize the result display + UpdateClassIcon(hDlg, lpIO, GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST)); + SetInsertObjectResults(hDlg, lpIO); + + //10. Change the caption + if (NULL!=lpOIO->lpszCaption) + SetWindowText(hDlg, lpOIO->lpszCaption); + + //11. Hide all DisplayAsIcon related controls if it should be disabled + if ( lpIO->dwFlags & IOF_DISABLEDISPLAYASICON ) { + StandardShowDlgItem(hDlg, ID_IO_DISPLAYASICON, SW_HIDE); + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, SW_HIDE); + StandardShowDlgItem(hDlg, ID_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; + } + + + + + + +/* + * 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) + { + DWORD dw; + UINT cStrings=0; + UINT i; + UINT cch; + HKEY hKey; + LONG lRet; + HFILE hFile; + OFSTRUCT of; + BOOL fExclude; + LPMALLOC pIMalloc; + LPTSTR pszExec; + LPTSTR pszClass; + LPTSTR pszKey; + LPTSTR pszID; + CLSID clsid; + + //Get some work buffers + if (NOERROR!=CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return (UINT)-1; + + pszExec=(LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHKEYMAX_SIZE*4); + + if (NULL==pszExec) + { + pIMalloc->lpVtbl->Release(pIMalloc); + return (UINT)-1; + } + + pszClass=pszExec+OLEUI_CCHKEYMAX; + pszKey=pszClass+OLEUI_CCHKEYMAX; + pszID=pszKey+OLEUI_CCHKEYMAX; + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + { + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszExec); + pIMalloc->lpVtbl->Release(pIMalloc); + return (UINT)-1; + } + + //Clean out the existing strings. + SendMessage(hList, LB_RESETCONTENT, 0, 0L); + + cStrings=0; + + while (TRUE) + { + 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 + 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")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + 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")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS==lRet) + { + /* + * 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. + */ + + hFile = !HFILE_ERROR; + + if (fVerify) + hFile=DoesFileExist(pszKey, &of); + + if (HFILE_ERROR!=hFile) + { + dw=OLEUI_CCHKEYMAX_SIZE; + *(pszClass+cch)=0; // set back to rootkey + // Get full user type name + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; // error getting type name--skip this class + + //Tell the code below to get the string for us. + pszID=NULL; + } + } + else + { + /* + * No \protocol\StdFileEditing\server entry. Look to see if + * there's an Insertable entry. If there is, then use the + * Clsid to look at CLSID\clsid\LocalServer and \InprocServer + */ + + lstrcpy(pszClass+cch, TEXT("\\Insertable")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; // Insertable NOT found--skip this class + + //Get memory for pszID + pszID=pIMalloc->lpVtbl->Alloc(pIMalloc, OLEUI_CCHKEYMAX_SIZE); + + if (NULL==pszID) + continue; + + *(pszClass+cch)=0; // set back to rootkey + lstrcat(pszClass+cch, TEXT("\\CLSID")); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszClass, pszID, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; // CLSID subkey not found + + lstrcpy(pszExec, TEXT("CLSID\\")); + lstrcat(pszExec, pszID); + + //CLSID\ is 6, dw contains pszID length. + cch=6+(UINT)dw; + + lstrcpy(pszExec+cch, TEXT("\\LocalServer")); + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszExec, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + { + //Try InprocServer + lstrcpy(pszExec+cch, TEXT("\\InProcServer")); + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszExec, pszKey, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; + } + + if (fVerify) + { + if (HFILE_ERROR==DoesFileExist(pszKey, &of)) + continue; + } + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet=RegQueryValue(hKey, pszExec, pszKey, &dw); + *(pszExec+cch)=0; //Remove \\*Server + + if ((LONG)ERROR_SUCCESS!=lRet) + continue; + } + + //Get CLSID to add to listbox. + if (NULL==pszID) + { + CLSIDFromProgIDA(pszClass, &clsid); + StringFromCLSIDA(&clsid, &pszID); + } + else + CLSIDFromStringA(pszID, &clsid); + + //Check if this CLSID is in the exclusion list. + fExclude=FALSE; + + for (i=0; i < cIDEx; i++) + { + if (IsEqualCLSID(&clsid, (LPCLSID)(lpIDEx+i))) + { + fExclude=TRUE; + break; + } + } + + if (fExclude) + continue; + + //We go through all the conditions, add the string. + lstrcat(pszKey, TEXT("\t")); + + // only add to listbox if not a duplicate + if (LB_ERR==SendMessage(hList,LB_FINDSTRING,0,(LPARAM)pszKey)) { + lstrcat(pszKey, pszID); + SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)pszKey); + } + + //We always allocated this regardless of the path + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszID); + } + + + //Select the first item by default + SendMessage(hList, LB_SETCURSEL, 0, 0L); + RegCloseKey(hKey); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszExec); + pIMalloc->lpVtbl->Release(pIMalloc); + + 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) + { + BOOL fTemp; + UINT uTemp; + DWORD dwTemp; + int i; + + //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, ID_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. + */ + fTemp=(IOF_SELECTCREATENEW==dwOption) ? lpIO->fAsIconNew : lpIO->fAsIconFile; + + if (fTemp) + lpIO->dwFlags |=IOF_CHECKDISPLAYASICON; + else + lpIO->dwFlags &=~IOF_CHECKDISPLAYASICON; + + CheckDlgButton(hDlg, ID_IO_DISPLAYASICON + , (BOOL)(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON))); + + EnableWindow(GetDlgItem(hDlg, ID_IO_CHANGEICON), fTemp); + + /* + * 2. Display Icon: Enabled on Create New or on Create from File if + * there is a selected file. + */ + fTemp=(IOF_SELECTCREATENEW==dwOption) ? TRUE : lpIO->fFileSelected; + EnableWindow(GetDlgItem(hDlg, ID_IO_DISPLAYASICON), fTemp); + + //OK and Link follow the same enabling as Display As Icon. + EnableWindow(GetDlgItem(hDlg, IDOK), fTemp); + EnableWindow(GetDlgItem(hDlg, ID_IO_LINKFILE), fTemp); + + //3. Enable Browse... when Create from File is selected. + fTemp=(IOF_SELECTCREATENEW==dwOption); + EnableWindow(GetDlgItem(hDlg, ID_IO_FILE), !fTemp); + EnableWindow(GetDlgItem(hDlg, ID_IO_FILEDISPLAY), !fTemp); + + /* + * 4. Switch between Object Type listbox on Create New and + * file buttons on others. + */ + uTemp=(fTemp) ? SW_SHOWNORMAL : SW_HIDE; + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPELIST, uTemp); + StandardShowDlgItem(hDlg, ID_IO_OBJECTTYPETEXT, uTemp); + + uTemp=(fTemp) ? SW_HIDE : SW_SHOWNORMAL; + StandardShowDlgItem(hDlg, ID_IO_FILETEXT, uTemp); + StandardShowDlgItem(hDlg, ID_IO_FILETYPE, uTemp); + StandardShowDlgItem(hDlg, ID_IO_FILEDISPLAY, uTemp); + StandardShowDlgItem(hDlg, ID_IO_FILE, uTemp); + + //Link is always hidden if IOF_DISABLELINK is set. + if (IOF_DISABLELINK & lpIO->dwFlags) + uTemp=SW_HIDE; + + StandardShowDlgItem(hDlg, ID_IO_LINKFILE, uTemp); //last use of uTemp + + + //5. Clear out existing any flags selection and set the new one + dwTemp=IOF_SELECTCREATENEW | IOF_SELECTCREATEFROMFILE; + lpIO->dwFlags=(lpIO->dwFlags & ~dwTemp) | dwOption; + + + /* + * 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. + */ + + i=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON) ? SW_SHOWNORMAL : SW_HIDE; + StandardShowDlgItem(hDlg, ID_IO_CHANGEICON, i); + StandardShowDlgItem(hDlg, ID_IO_ICONDISPLAY, i); + + + //6.Change result display + SetInsertObjectResults(hDlg, lpIO); + + /* + * 7. 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, ID_IO_OBJECTTYPELIST)); + SetFocus(GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST)); + } + else + { + if (lpIO->fAsIconFile && (NULL != lpIO->hMetaPictFile) ) + { + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)lpIO->hMetaPictFile, 0L); + lpIO->hMetaPictFile = 0; + } + else + UpdateClassIcon(hDlg, lpIO, NULL); + + SetFocus(GetDlgItem(hDlg, ID_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) +{ + + CLSID clsid; + TCHAR szFileName[OLEUI_CCHPATHMAX]; + TCHAR szFileType[OLEUI_CCHLABELMAX]; + + *szFileType = TEXT('\0'); + + if (fSet) + { + GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, (LPTSTR)szFileName, OLEUI_CCHPATHMAX); + + if (NOERROR == GetClassFileA(szFileName, &clsid) ) + OleStdGetUserTypeOfClass(&clsid, szFileType, OLEUI_CCHLABELMAX_SIZE, NULL); + + } + + SetDlgItemText(hDlg, ID_IO_FILETYPE, (LPTSTR)szFileType); + + return; +} + + +/* + * 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 + */ + +void UpdateClassIcon(HWND hDlg, LPINSERTOBJECT lpIO, HWND hList) + { + UINT iSel; + DWORD cb; + LPMALLOC pIMalloc; + LPTSTR pszName, pszCLSID, pszTemp; + HGLOBAL hMetaPict; + + LRESULT dwRet; + + + //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. + */ + + 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 + dwRet=SendMessage(hList, LB_GETITEMDATA, (WPARAM)iSel, 0L); + + hMetaPict=(HGLOBAL)(UINT)dwRet; + + if (hMetaPict) + { + //Yep, we've already got it, so just display it and return. + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)hMetaPict, 0L); + 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); + } + else + cb=OLEUI_CCHPATHMAX_SIZE; + + if (NOERROR!=CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return; + + pszName=(LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, cb+1*sizeof(TCHAR) ); + + if (NULL==pszName) + { + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + *pszName=0; + + //Get the clsid we want. + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + //Grab the classname string from the list + SendMessage(hList, LB_GETTEXT, iSel, (LONG)pszName); + + //Set pointer to CLSID (string) + pszCLSID=PointerToNthField(pszName, 2, TEXT('\t')); + + //Null terminate pszName string +#ifdef WIN32 + // AnsiPrev is obsolete in Win32 + pszTemp=CharPrev((LPCTSTR) pszName,(LPCTSTR) pszCLSID); +#else + pszTemp=AnsiPrev((LPCTSTR) pszName,(LPCTSTR) pszCLSID); +#endif + *pszTemp=TEXT('\0'); + CLSIDFromStringA(pszCLSID, &lpIO->clsid); + +#ifdef OLE201 + hMetaPict = GetIconOfClass(ghInst, &lpIO->clsid, NULL, TRUE); +#endif + } + + else + { + //Get the class from the filename + GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, pszName, OLEUI_CCHPATHMAX); + +#ifdef OLE201 + + hMetaPict = OleGetIconOfFileA(pszName, + lpIO->dwFlags & IOF_CHECKLINK ? TRUE : FALSE); + +#endif + + } + + //Replace the current display with this new one. + SendDlgItemMessage(hDlg, ID_IO_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)hMetaPict, 0L); + + //Enable or disable "Change Icon" button depending on whether + //we've got a valid filename or not. + EnableWindow(GetDlgItem(hDlg, ID_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, hMetaPict); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszName); + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + + + +/* + * 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) + { + LPTSTR pszT, psz1, psz2, psz3, psz4, pszTemp; + UINT i, iString1, iString2, iImage, cch; + LPMALLOC pIMalloc; + BOOL fAsIcon; + + /* + * 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. + */ + i=(UINT)SendDlgItemMessage(hDlg, ID_IO_OBJECTTYPELIST, LB_GETCURSEL, 0, 0L); + cch=512+ + (UINT)SendDlgItemMessage(hDlg, ID_IO_OBJECTTYPELIST, LB_GETTEXTLEN, i, 0L); + + if (NOERROR!=CoGetMalloc(MEMCTX_TASK, &pIMalloc)) + return; + + pszTemp=(LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, (DWORD)(4*cch*sizeof(TCHAR))); + + if (NULL==pszTemp) + { + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + psz1=pszTemp; + psz2=psz1+cch; + psz3=psz2+cch; + psz4=psz3+cch; + + fAsIcon=(0L!=(lpIO->dwFlags & IOF_CHECKDISPLAYASICON)); + + if (lpIO->dwFlags & IOF_SELECTCREATENEW) + { + 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(ghInst, iString1, psz1, cch)) + { + + // Load second string, if necessary + if ( (0 != iString2) + && (0 != LoadString(ghInst, 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) + { + SendDlgItemMessage(hDlg, ID_IO_OBJECTTYPELIST, LB_GETTEXT + , i, (LONG)psz2); + + //Null terminate at any tab (before the classname) + pszT=psz2; + while (TEXT('\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, ID_IO_RESULTTEXT, psz1); + + //Go change the image and Presto! There you have it. + SendDlgItemMessage(hDlg, ID_IO_RESULTIMAGE, RIM_IMAGESET, iImage, 0L); + + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)pszTemp); + pIMalloc->lpVtbl->Release(pIMalloc); + return; + } + + + +/* + * 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 ID_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) + { + OFSTRUCT of; + HFILE hFile; + TCHAR szFile[OLEUI_CCHPATHMAX]; + + *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. + */ + + if (0==GetDlgItemText(hDlg, ID_IO_FILEDISPLAY, szFile, OLEUI_CCHPATHMAX)) + return FALSE; // #4569 : return FALSE when there is no text in ctl + + hFile=DoesFileExist(szFile, &of); + + // if file is currently open (ie. sharing violation) OleCreateFromFile + // and OleCreateLinkToFile can still succeed; do not consider it an + // error. + if (HFILE_ERROR==hFile && 0x0020/*sharing violation*/!=of.nErrCode) + { + *lpnErrCode = of.nErrCode; + if (fTellUser) + OpenFileError(hDlg, of.nErrCode, szFile); + return FALSE; + } + + //OFSTRUCT contains an OEM name, not ANSI as we need for the edit box. + OemToAnsi(of.szPathName, of.szPathName); + + SetDlgItemText(hDlg, ID_IO_FILEDISPLAY, of.szPathName); + 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; + UINT iItems; + HGLOBAL hMetaPict; + LRESULT dwRet; + UINT i; + + hList=GetDlgItem(hDlg, ID_IO_OBJECTTYPELIST); + iItems=(UINT)SendMessage(hList, LB_GETCOUNT, 0, 0L); + + for (i=0; i < iItems; i++) + { + dwRet=SendMessage(hList, LB_GETITEMDATA, (WPARAM)i, 0L); + + //Cast of LRESULT to UINT to HGLOBAL portable to Win32. + hMetaPict=(HGLOBAL)(UINT)dwRet; + + if (hMetaPict) + OleUIMetafilePictIconFree(hMetaPict); + } + + return; + } diff --git a/private/oleutest/letest/ole2ui/insobj.dlg b/private/oleutest/letest/ole2ui/insobj.dlg new file mode 100644 index 000000000..2f81811a0 --- /dev/null +++ b/private/oleutest/letest/ole2ui/insobj.dlg @@ -0,0 +1,51 @@ +//DLGINCLUDE RCDATA DISCARDABLE +//BEGIN +// "OLE2UI.H\0" +//END + +IDD_INSERTOBJECT DIALOG 6, 18, 291, 150 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Insert Object" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Create &New", ID_IO_CREATENEW, "Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 6, 18, 67, 10 + + CONTROL "Create from &File", ID_IO_CREATEFROMFILE, "Button", + BS_AUTORADIOBUTTON | WS_TABSTOP, 6, 36, 67, 10 + + LTEXT "Object &Type:", ID_IO_OBJECTTYPETEXT, 84, 4, 110, 8 + + LISTBOX ID_IO_OBJECTTYPELIST, 82, 16, 132, 73, LBS_SORT | + LBS_USETABSTOPS | WS_VSCROLL | WS_GROUP | WS_TABSTOP + + LTEXT "Fil&e:", ID_IO_FILETEXT, 82, 24, 20, 8 + LTEXT "", ID_IO_FILETYPE, 120, 24, 80, 8 + + EDITTEXT ID_IO_FILEDISPLAY, 82, 34, 132, 12, ES_AUTOHSCROLL | ES_LOWERCASE | ES_OEMCONVERT + + PUSHBUTTON "&Browse...", ID_IO_FILE, 82, 50, 48, 14 + + CONTROL "&Link", ID_IO_LINKFILE, "Button", BS_AUTOCHECKBOX | + WS_TABSTOP, 140, 52, 40, 10 + + DEFPUSHBUTTON "OK", IDOK, 222, 6, 66, 14, WS_GROUP + + PUSHBUTTON "Cancel", IDCANCEL, 222, 24, 66, 14 + + PUSHBUTTON "&Help", ID_OLEUIHELP, 222, 42, 66, 14 + + CONTROL "&Display As Icon", ID_IO_DISPLAYASICON, "Button", + BS_AUTOCHECKBOX | WS_TABSTOP, 222, 64, 66, 10 + + CONTROL "", ID_IO_ICONDISPLAY, SZCLASSICONBOX, 0, 220, 80, 66, 46 + + PUSHBUTTON "Change &Icon...", ID_IO_CHANGEICON, 222, 127, 66, 14 + + GROUPBOX "Result", ID_STATIC, 6, 96, 210, 47, WS_GROUP + +// CONTROL "", ID_IO_RESULTIMAGE, SZCLASSRESULTIMAGE, 0, 10, 106, 42, 34 + + LTEXT "Result", ID_IO_RESULTTEXT, 56, 106, 156, 32, SS_NOPREFIX | + NOT WS_GROUP +END diff --git a/private/oleutest/letest/ole2ui/insobj.h b/private/oleutest/letest/ole2ui/insobj.h new file mode 100644 index 000000000..1958d7f4f --- /dev/null +++ b/private/oleutest/letest/ole2ui/insobj.h @@ -0,0 +1,52 @@ +/* + * INSOBJ.H + * + * Internal definitions, structures, and function prototypes for the + * OLE 2.0 UI Insert Object dialog. + * + * Copyright (c)1993 Microsoft Corporation, All Rights Reserved + */ + + +#ifndef _INSOBJ_H_ +#define _INSOBJ_H_ + +//Internally used structure +typedef struct tagINSERTOBJECT + { + LPOLEUIINSERTOBJECT lpOIO; //Original structure passed. + + /* + * 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[OLEUI_CCHPATHMAX]; + 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 + } INSERTOBJECT, *PINSERTOBJECT, FAR *LPINSERTOBJECT; + + + +//Internal function prototypes +//INSOBJ.C +BOOL CALLBACK EXPORT InsertObjectDialogProc(HWND, UINT, WPARAM, LPARAM); +BOOL FInsertObjectInit(HWND, WPARAM, LPARAM); +UINT UFillClassList(HWND, UINT, LPCLSID, BOOL); +BOOL FToggleObjectSource(HWND, LPINSERTOBJECT, DWORD); +void UpdateClassIcon(HWND, LPINSERTOBJECT, HWND); +void UpdateClassType(HWND, LPINSERTOBJECT, BOOL); +void SetInsertObjectResults(HWND, LPINSERTOBJECT); +BOOL FValidateInsertFile(HWND, BOOL, UINT FAR*); +void InsertObjectCleanup(HWND); + +#endif //_INSOBJ_H_ diff --git a/private/oleutest/letest/ole2ui/links.c b/private/oleutest/letest/ole2ui/links.c new file mode 100644 index 000000000..88c552754 --- /dev/null +++ b/private/oleutest/letest/ole2ui/links.c @@ -0,0 +1,2146 @@ +/* + * links.c + * + * Implements the OleUIEditLinks function which invokes the complete + * Edit Links dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 + +#include "ole2ui.h" +#include "common.h" +#include "edlinks.h" +#include "utility.h" +#include <commdlg.h> +#include <dlgs.h> +#include <stdlib.h> + +OLEDBGDATA + +/* +* 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) +{ + UINT uRet; + HGLOBAL hMemDlg=NULL; + + uRet=UStandardValidation((LPOLEUISTANDARD)lpEL, sizeof(OLEUIEDITLINKS) + , &hMemDlg); + + if (OLEUI_SUCCESS!=uRet) + return uRet; + + /* + * PERFORM ANY STRUCTURE-SPECIFIC VALIDATION HERE! + * ON FAILURE: + * { + * if (NULL!=hMemDlg) + * FreeResource(hMemDlg) + * + * return OLEUI_<ABBREV>ERR_<ERROR> + * } + */ + + //Now that we've validated everything, we can invoke the dialog. + uRet=UStandardInvocation(EditLinksDialogProc, (LPOLEUISTANDARD)lpEL, + hMemDlg, MAKEINTRESOURCE(IDD_EDITLINKS)); + + /* + * IF YOU ARE CREATING ANYTHING BASED ON THE RESULTS, DO IT HERE. + */ + + + return uRet; +} + + + +/* +* EditLinksDialogProc +* +* Purpose: +* Implements the OLE Edit Links dialog as invoked through the +* OleUIEditLinks function. +* +* Parameters: +* Standard +* +* Return Value: +* Standard +*/ + +BOOL CALLBACK EXPORT EditLinksDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + LPEDITLINKS lpEL = NULL; + BOOL fHook=FALSE; + UINT uRet=0; + HRESULT hErr; + static int nColPos[3]; + + //Declare Win16/Win32 compatible WM_COMMAND parameters. + COMMANDPARAMS(wID, wCode, hWndMsg); + + //This will fail under WM_INITDIALOG, where we allocate it. + 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) { + + //Free any specific allocations before calling StandardCleanup + + StandardCleanup(lpEL, hDlg); + + EndDialog(hDlg, wParam); + return TRUE; + } + + switch (iMsg) { + static int nHeightLine = -1; + static int nMaxCharWidth = -1; + + case WM_INITDIALOG: + { + RECT rc; + int nStart; + + /* calculate the column positions relative to the listbox */ + GetWindowRect(GetDlgItem(hDlg, ID_EL_LINKSLISTBOX), (LPRECT)&rc); + nStart = rc.left; + GetWindowRect(GetDlgItem(hDlg, ID_EL_COL1), (LPRECT)&rc); + nColPos[0] = rc.left - nStart; + GetWindowRect(GetDlgItem(hDlg, ID_EL_COL2), (LPRECT)&rc); + nColPos[1] = rc.left - nStart; + GetWindowRect(GetDlgItem(hDlg, ID_EL_COL3), (LPRECT)&rc); + nColPos[2] = rc.left - nStart; + + return FEditLinksInit(hDlg, wParam, lParam); + } + break; + + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT lpMIS; + + lpMIS = (LPMEASUREITEMSTRUCT)lParam; + + if (nHeightLine == -1) { + HFONT hFont; + HDC hDC; + TEXTMETRIC tm; + + /* Attempt to get font dialog. If that fails, + use system font + */ + + hFont = (HANDLE)(UINT)SendMessage(hDlg, WM_GETFONT, 0, 0L); + + if (hFont == NULL) + hFont = GetStockObject(SYSTEM_FONT); + + hDC = GetDC(hDlg); + hFont = SelectObject(hDC, hFont); + + GetTextMetrics(hDC, &tm); + nHeightLine = tm.tmHeight; + nMaxCharWidth = tm.tmMaxCharWidth; + + ReleaseDC(hDlg, hDC); + } + + lpMIS->itemHeight = nHeightLine; + } + break; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpDIS; + COLORREF crText; + LPLINKINFO lpLI; + HBRUSH hbr; + int nOldBkMode; + TCHAR tsz[OLEUI_CCHPATHMAX]; + LPTSTR lpsz; + RECT rcClip; + + lpDIS = (LPDRAWITEMSTRUCT)lParam; + lpLI = (LPLINKINFO)lpDIS->itemData; + + if ((int)lpDIS->itemID < 0) + break; + + if ((ODA_DRAWENTIRE | ODA_SELECT) & lpDIS->itemAction) { + + 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); + + nOldBkMode = SetBkMode(lpDIS->hDC, TRANSPARENT); + + if (lpLI->lpszDisplayName) { + lstrcpy((LPTSTR)tsz, lpLI->lpszDisplayName); + lpsz = ChopText( + lpDIS->hwndItem, + nColPos[1] - nColPos[0] + - (nMaxCharWidth > 0 ? nMaxCharWidth : 5), + tsz + ); + rcClip.left = lpDIS->rcItem.left + nColPos[0]; + rcClip.top = lpDIS->rcItem.top; + rcClip.right = lpDIS->rcItem.left + nColPos[1] + - (nMaxCharWidth > 0 ? 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 + nColPos[1]; + rcClip.top = lpDIS->rcItem.top; + rcClip.right = lpDIS->rcItem.left + nColPos[2] + - (nMaxCharWidth > 0 ? 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 + 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); + + } + + InitControls(hDlg, lpEL); + + if (ODA_FOCUS & lpDIS->itemAction) + DrawFocusRect(lpDIS->hDC, &lpDIS->rcItem); + + } + return TRUE; + + + case WM_DELETEITEM: + { + UINT idCtl; + LPDELETEITEMSTRUCT lpDIS; + LPLINKINFO lpLI; + + lpDIS = (LPDELETEITEMSTRUCT)lParam; + idCtl = wParam; + 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 ID_EL_CHANGESOURCE: + { + BOOL fRet = FALSE; + + /* This will bring up the file open dlg with one + edit field containing the whole link name. The file part + will (eventually) be highlighted to indicate where the + file part is. We need to hook on OK here to be able to + send the changed string to the Parse function */ + + fRet = Container_ChangeSource(hDlg, lpEL); + if (!fRet) + PopupMessage(hDlg, IDS_LINKS, IDS_FAILED, + MB_ICONEXCLAMATION | MB_OK); + InitControls(hDlg, lpEL); + } + break; + + case ID_EL_AUTOMATIC: + { + /* This is available for single or multi-select. There is + a flag in the structure that is set initially indicating + whether the link is auto or manual so that we need not + query the link each time we want to find out. + + This command will make the link automatic if not already. + It will have no effect on links already set to auto. + */ + // turn the button ON + + CheckDlgButton(hDlg, ID_EL_AUTOMATIC, 1); + CheckDlgButton(hDlg, ID_EL_MANUAL, 0); + + hErr = Container_AutomaticManual(hDlg, TRUE, lpEL); + if (hErr != NOERROR) + PopupMessage(hDlg, IDS_LINKS, IDS_FAILED, + MB_ICONEXCLAMATION | MB_OK); + + InitControls(hDlg, lpEL); + } + break; + + case ID_EL_MANUAL: + { + /* Same rules apply here as they do to auto link. + Additional note - just because something is changed does + not mean that it updates at the moment. It simply + reflects what kind of updating it does while it lives in + the document. + */ + // turn the button ON + + CheckDlgButton(hDlg, ID_EL_MANUAL, 1); + CheckDlgButton(hDlg, ID_EL_AUTOMATIC, 0); + + hErr = Container_AutomaticManual(hDlg, FALSE, lpEL); + if (hErr != NOERROR) + PopupMessage(hDlg, IDS_LINKS, IDS_FAILED, + MB_ICONEXCLAMATION | MB_OK); + + InitControls(hDlg, lpEL); + } + break; + + case ID_EL_CANCELLINK: + { + /* This is Break Link now in the dlg. This sets the + moniker to null, thereby effectively breaking the link. + The object still has its data effective at the time of + breaking, but becomes a static object. + *****It will need to be deleted from the listbox + */ + + CancelLink(hDlg,lpEL); + InitControls(hDlg, lpEL); + } + break; + + case ID_EL_UPDATENOW: + { + /* This forces an immediate update of the selected + links. This will start the server etc, so this is a very + expensive operation. + */ + hErr = Container_UpdateNow(hDlg, lpEL); + InitControls(hDlg, lpEL); + } + break; + + case ID_EL_OPENSOURCE: + { + /* This will only work on single selection. It makes no + sense to open multiple sources at the same time, since + the one opened will try to show itself and become the + primary operating target, so to speak. Button is greyed + if multi select. + + Here we do not add the break because we want to exit the + dlg in this case. + */ + hErr = Container_OpenSource(hDlg, lpEL); + if (hErr != NOERROR) { + InitControls(hDlg, lpEL); + break; // don't close dialog + } + } // fall through + + case ID_EL_CLOSE: + { + /* The user is finished with their editing - they now + return to their container document. + + */ + SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L); + } + break; + + case IDCANCEL: + { + /* This changes to CLOSE after the user does even ONE + thing in the dlg. Nothing can really effectively be undone. + */ + SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L); + } + break; + + case ID_OLEUIHELP: + { + PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp + , (WPARAM)hDlg, MAKELPARAM(IDD_EDITLINKS, 0)); + break; + } + break; + } + break; + + default: + { + if (lpEL && iMsg == lpEL->nChgSrcHelpID) { + PostMessage(lpEL->lpOEL->hWndOwner, uMsgHelp, + (WPARAM)hDlg, MAKELPARAM(IDD_CHANGESOURCE, 0)); + } + } + 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) +{ + LPEDITLINKS lpEL; + LPOLEUIEDITLINKS lpOEL; + HFONT hFont; + BOOL fDlgItem = FALSE; + DWORD dwLink = 0; + ULONG cLinks; + LPOLEUILINKCONTAINER lpOleUILinkCntr; + int n; + HWND hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX); + + + + //1. Copy the structure at lParam into our instance memory. + lpEL = (LPEDITLINKS)LpvStandardInit(hDlg, sizeof(OLEUIEDITLINKS), TRUE, + &hFont); + + //PvStandardInit send a termination to us already. + if (NULL==lpEL) + return FALSE; + + lpOEL=(LPOLEUIEDITLINKS)lParam; + + lpEL->lpOEL=lpOEL; + + lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer; + + cLinks = LoadLinkLB(hListBox, lpOleUILinkCntr); + if (cLinks < 0) + return FALSE; + + fDlgItem = (BOOL)cLinks; + lpEL->fItemsExist = (BOOL)cLinks; + + + InitControls(hDlg, lpEL); + + //Copy other information from lpOEL that we might modify. + + //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 (!(lpEL->lpOEL->dwFlags & ELF_SHOWHELP)) + StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE); + + /* + * PERFORM OTHER INITIALIZATION HERE. ON ANY LoadString + * FAILURE POST OLEUI_MSG_ENDDIALOG WITH OLEUI_ERR_LOADSTRING. + */ + + //4. If requested disable UpdateNow button + if ((lpEL->lpOEL->dwFlags & ELF_DISABLEUPDATENOW)) + StandardShowDlgItem(hDlg, ID_EL_UPDATENOW, SW_HIDE); + + //5. If requested disable OpenSource button + if ((lpEL->lpOEL->dwFlags & ELF_DISABLEOPENSOURCE)) + StandardShowDlgItem(hDlg, ID_EL_OPENSOURCE, SW_HIDE); + + //6. If requested disable UpdateNow button + if ((lpEL->lpOEL->dwFlags & ELF_DISABLECHANGESOURCE)) + StandardShowDlgItem(hDlg, ID_EL_CHANGESOURCE, SW_HIDE); + + //7. If requested disable CancelLink button + if ((lpEL->lpOEL->dwFlags & ELF_DISABLECANCELLINK)) + StandardShowDlgItem(hDlg, ID_EL_CANCELLINK, SW_HIDE); + + //8. Load 'Close' string used to rename Cancel button + n = LoadString(ghInst, 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); + + //n. Call the hook with lCustData in lParam + UStandardHook(lpEL, hDlg, WM_INITDIALOG, wParam, lpOEL->lCustData); + + return FALSE; +} + + + +/* + * ChangeSourceHook + * + * Purpose: + * Hooks the ChangeSource dialog to attempt to validate link source changes + * specified by the user. + * + * Parameters: + * hDlg HWND of the dialog + * uMsg UINT Message + * wParam WPARAM of the message + * lParam LPARAM of the message + * + * Return Value: + * UNIT Zero = Do default processing; + * Non Zero = Don't do default processing. + */ + +UINT CALLBACK EXPORT ChangeSourceHook(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LPCHANGESOURCEHOOKDATA lpCshData = NULL; + LPLINKINFO lpLI = NULL; + LPEDITLINKS lpEL = NULL; + LPOLEUILINKCONTAINER lpOleUILinkCntr; + HRESULT hErr; + UINT uRet; + ULONG ulChEaten; + HGLOBAL gh; + + //This will fail under WM_INITDIALOG, where we allocate it. + if (NULL!=(gh = GetProp(hDlg, STRUCTUREPROP))) + { + // gh was locked previously, lock and unlock to get lpv + lpCshData=(LPCHANGESOURCEHOOKDATA)GlobalLock(gh); + GlobalUnlock(gh); + if (lpCshData) + { + lpLI = lpCshData->lpOCshData->lpLI; + lpEL = lpCshData->lpOCshData->lpEL; + } + } + + //Process the temination message + if (uMsg==uMsgEndDialog) + { + if (NULL!=(gh = RemoveProp(hDlg, STRUCTUREPROP))) + { + GlobalUnlock(gh); + GlobalFree(gh); + } + return TRUE; + } + + // User pressed the OK button + if (uMsg == uMsgFileOKString) { + lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer; + + /* NOTE: trigger the focus lost of the edit control. This is + ** not necessary if the user click OK with the mouse but is + ** needed when the user just press <Enter>. If the mouse was + ** used, no extra is done as the MODIFY flag of the edit control + ** has been cleared. + */ + SendMessage(hDlg, WM_COMMAND, edt1, + MAKELPARAM(GetDlgItem(hDlg, edt1), EN_KILLFOCUS)); + if (lpCshData->bItemNameStored) { + lpCshData->nFileLength = lstrlen((LPTSTR)lpCshData->szEdit) - + lstrlen((LPTSTR)lpCshData->szItemName); + } + else { + lpCshData->nFileLength = lstrlen((LPTSTR)lpCshData->szEdit); + } + + // Try to validate link source change + OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::SetLinkSource called\r\n")); + hErr = lpOleUILinkCntr->lpVtbl->SetLinkSource( + lpOleUILinkCntr, + lpLI->dwLink, + (LPTSTR)lpCshData->szEdit, + (ULONG)lpCshData->nFileLength, + &ulChEaten, + TRUE + ); + OLEDBG_END2 + + // Link source change not validated + if (hErr != NOERROR) { + uRet =PopupMessage(hDlg, IDS_CHANGESOURCE, IDS_INVALIDSOURCE, + MB_ICONQUESTION | MB_YESNO); + + if (uRet == IDYES) { + /* User wants to correct invalid link. Set the edit + ** control selection to the invalid part of the contents. + */ + SetFocus(GetDlgItem(hDlg, edt1)); + SendDlgItemMessage(hDlg, edt1, EM_SETSEL, 0, + MAKELPARAM(ulChEaten, -1)); + return 1; // Don't close ChangeSource dialog + } + else { + /* User does not want to correct invalid link. So set + ** the link source but don't validate the link. + */ + OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::SetLinkSource called\r\n")); + hErr = lpOleUILinkCntr->lpVtbl->SetLinkSource( + lpOleUILinkCntr, + lpLI->dwLink, + (LPTSTR)lpCshData->szEdit, + (ULONG)lpCshData->nFileLength, + &ulChEaten, + FALSE + ); + OLEDBG_END2 + lpCshData->fValidLink = FALSE; + } + } + else { // Link source change validated + lpCshData->fValidLink = TRUE; + } + + if (lpCshData->bItemNameStored && lpCshData->bFileNameStored) { + HWND hListBox = GetDlgItem(lpCshData->lpOfn->hwndOwner, ID_EL_LINKSLISTBOX); + + DiffPrefix( + lpLI->lpszDisplayName, + (LPTSTR)lpCshData->szEdit, + (TCHAR FAR* FAR*)&lpCshData->lpszFrom, + (TCHAR FAR* FAR*)&lpCshData->lpszTo + ); + + /* we keep the strings if there is a difference between the + ** lpszFrom and lpszTo strings AND if the change is only + ** in the file portion otherwise free them and other + ** links won't be compared. + */ + if ( (lstrcmp(lpCshData->lpszTo, lpCshData->lpszFrom)==0) + || (lstrlen(lpCshData->lpszTo)>lpCshData->nFileLength)) { + if (lpCshData->lpszFrom) { + OleStdFree(lpCshData->lpszFrom); + lpCshData->lpszFrom = NULL; + } + if (lpCshData->lpszTo) { + OleStdFree(lpCshData->lpszTo); + lpCshData->lpszTo = NULL; + } + } + } + + // Copy OUT results to original structure + lpCshData->lpOCshData->lpszFrom = lpCshData->lpszFrom; + lpCshData->lpOCshData->lpszTo = lpCshData->lpszTo; + lpCshData->lpOCshData->fValidLink = lpCshData->fValidLink; + + SendMessage(hDlg, uMsgEndDialog, 0, 0L); // do cleanup + return 0; // Close ChangeSource dialog + } + + switch (uMsg) { + case WM_INITDIALOG: + { + LPOPENFILENAME lpOfn = (LPOPENFILENAME)lParam; + LPOLEUICHANGESOURCEHOOKDATA lpOCshData = + (LPOLEUICHANGESOURCEHOOKDATA)lpOfn->lCustData; + + gh=GlobalAlloc( + GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof(CHANGESOURCEHOOKDATA)); + if (NULL==gh) + { + // Memory allocation error; fail to bring up dialog + PostMessage(hDlg, uMsgEndDialog, 0, 0L); + return 0; + } + lpCshData = GlobalLock(gh); + SetProp(hDlg, STRUCTUREPROP, gh); + + lpCshData->lpOCshData = lpOCshData; + lpCshData->lpOfn = lpOfn; + lpLI = lpCshData->lpOCshData->lpLI; + + lpCshData->bFileNameStored = TRUE; + lpCshData->bItemNameStored = TRUE; + lpCshData->nFileLength = (int)lpLI->clenFileName; + if (lpLI->lpszDisplayName) { + LSTRCPYN((LPTSTR)lpCshData->szFileName, lpLI->lpszDisplayName, + lpCshData->nFileLength + 1); + lstrcpy((LPTSTR)lpCshData->szEdit, lpLI->lpszDisplayName); + } else { + lpCshData->szFileName[0] = TEXT('\0'); + lpCshData->szEdit[0] = TEXT('\0'); + } + if (lpLI->lpszItemName) + lstrcpy((LPTSTR)lpCshData->szItemName, lpLI->lpszItemName); + else + lpCshData->szItemName[0] = TEXT('\0'); + + return 0; + } + + case WM_COMMAND: + + // User pressed the CANCEL button + if (wParam == IDCANCEL) + { + if (lpCshData->lpszFrom) + { + OleStdFree(lpCshData->lpszFrom); + lpCshData->lpszFrom = NULL; + } + if (lpCshData->lpszTo) + { + OleStdFree(lpCshData->lpszTo); + lpCshData->lpszTo = NULL; + } + + // Copy OUT results to original structure + lpCshData->lpOCshData->lpszFrom = NULL; + lpCshData->lpOCshData->lpszTo = NULL; + lpCshData->lpOCshData->fValidLink = FALSE; + + SendMessage(hDlg, uMsgEndDialog, 0, 0L); // do cleanup + return 0; // Close ChangeSource dialog + } + + if ((wParam == lst1) && + (HIWORD(lParam) == LBN_SELCHANGE)) { + + int nIndex; + HWND hListBox = (HWND)LOWORD(lParam); + static TCHAR szFileNameBuf[OLEUI_CCHPATHMAX]; + static TCHAR szEditBuf[OLEUI_CCHPATHMAX]; + + nIndex = (int)SendMessage(hListBox, LB_GETCURSEL, 0, 0L); + SendMessage(hListBox, LB_GETTEXT, + (WPARAM)nIndex, (LPARAM)(LPTSTR)szFileNameBuf); + + /* need to build the full path filename for the moniker */ +#ifdef WIN32 + CharToOem(szFileNameBuf, szFileNameBuf); +#else + AnsiToOem(szFileNameBuf, szFileNameBuf); +#endif + _fullpath(szEditBuf, szFileNameBuf, sizeof(szEditBuf)); +#ifdef WIN32 + OemToChar(szEditBuf, szEditBuf); +#else + OemToAnsi(szEditBuf, szEditBuf); +#endif + + /* convert filename to lower case as it appears in the + ** listbox + */ +#ifdef WIN32 + CharLower(szEditBuf); +#else + AnsiLower(szEditBuf); +#endif + LSTRCPYN((LPTSTR)lpCshData->szEdit, (LPTSTR)szEditBuf, + sizeof(lpCshData->szEdit) / sizeof(TCHAR)); + LSTRCPYN((LPTSTR)lpCshData->szFileName, + (LPTSTR)lpCshData->szEdit, + sizeof(lpCshData->szFileName) / sizeof(TCHAR) ); + lpCshData->nFileLength = lstrlen((LPTSTR)lpCshData->szEdit); + if (lpCshData->bItemNameStored) + lstrcat((LPTSTR)lpCshData->szEdit, lpCshData->szItemName); + + SetDlgItemText(hDlg, edt1, (LPTSTR)lpCshData->szEdit); + lpCshData->nEditLength = lstrlen((LPTSTR)lpCshData->szEdit); + lpCshData->bFileNameStored = TRUE; + + return 1; + } + + if ((wParam == lst2) && + (HIWORD(lParam) == LBN_SELCHANGE)) { + + if (lpCshData->bItemNameStored) + SetDlgItemText(hDlg, edt1, (LPTSTR)lpCshData->szItemName); + + return 1; + } + + if ((wParam == cmb2) && + (HIWORD(lParam) == CBN_SELCHANGE)) { + + if (lpCshData->bItemNameStored) + SetDlgItemText(hDlg, edt1, (LPTSTR)lpCshData->szItemName); + + return 1; + } + + if (wParam == edt1) { + HWND hEdit = (HWND)LOWORD(lParam); + + switch (HIWORD(lParam)) { + case EN_SETFOCUS: + SendMessage(hEdit, EM_SETSEL, 0, + MAKELPARAM(0, lpCshData->nFileLength)); + return 1; + + case EN_KILLFOCUS: + if (SendMessage(hEdit, EM_GETMODIFY, 0, 0L)) { + TCHAR szTmp[OLEUI_CCHPATHMAX]; + int nItemLength = lstrlen((LPTSTR)lpCshData->szItemName); + + *(LPWORD)lpCshData->szEdit = sizeof(lpCshData->szEdit)/ + sizeof(TCHAR) - 1; + lpCshData->nEditLength = (int)SendMessage(hEdit, + EM_GETLINE, 0, (LPARAM)(LPTSTR)lpCshData->szEdit); + lpCshData->szEdit[lpCshData->nEditLength] = TEXT('\0'); + LSTRCPYN((LPTSTR)szTmp, (LPTSTR)lpCshData->szEdit, + lpCshData->nFileLength + 1); + + if (lpCshData->bFileNameStored && + !lstrcmp((LPTSTR)lpCshData->szFileName, (LPTSTR)szTmp)) { + lstrcpy((LPTSTR)lpCshData->szItemName, + (LPTSTR)lpCshData->szEdit + lpCshData->nFileLength); + lpCshData->bItemNameStored = TRUE; + } + else if (lpCshData->bItemNameStored && + !lstrcmp((LPTSTR)lpCshData->szItemName, + (LPTSTR)lpCshData->szEdit + + lpCshData->nEditLength - + nItemLength)) { + if (lpCshData->nEditLength==nItemLength) { + + lpCshData->bFileNameStored = FALSE; + } else { + LSTRCPYN((LPTSTR)lpCshData->szFileName, + (LPTSTR)lpCshData->szEdit, + lpCshData->nEditLength - + nItemLength+1); + lpCshData->bFileNameStored = TRUE; + } + } + else { + lpCshData->bItemNameStored = FALSE; + lpCshData->bFileNameStored = FALSE; + } + + SendMessage(hEdit, EM_SETMODIFY, FALSE, 0L); + } + return 0; + } + } + return 0; + + default: + return 0; + } +} + + +/* +* ChangeSource +* +* Purpose: +* Displays the standard GetOpenFileName dialog with a customized template and +* hook. +* +* Parameters: +* hWndOwner HWND owning the dialog +* lpszFile LPSTR specifying the initial file. If there is no +* initial file the first character of this string should +* be a null. +* cchFile UINT length of pszFile +* iFilterString UINT index into the stringtable for the filter string. +* lpfnBrowseHook COMMDLGHOOKPROC hook to process link source information when user +* presses OK +* lpCshData LPCHANGESOURCEHOOKDATA custom data that is accessible to the hook +* +* Return Value: +* BOOL TRUE if the user selected a file and pressed OK. +* FALSE otherwise, such as on pressing Cancel. +*/ + +BOOL WINAPI ChangeSource( + HWND hWndOwner, + LPTSTR lpszFile, + UINT cchFile, + UINT iFilterString, + COMMDLGHOOKPROC lpfnBrowseHook, + LPOLEUICHANGESOURCEHOOKDATA lpCshData +) +{ + UINT cch; + TCHAR szFilters[OLEUI_CCHPATHMAX]; + TCHAR szDir[OLEUI_CCHPATHMAX]; + TCHAR szTitle[OLEUI_CCHPATHMAX]; + OPENFILENAME ofn; + BOOL fStatus; + LPTSTR lpszFileBuffer; + + if (NULL==lpszFile || 0==cchFile) + return FALSE; + + lpszFileBuffer = (LPTSTR)OleStdMalloc(cchFile * sizeof(TCHAR)); + if (!lpszFileBuffer) + return FALSE; + + lstrcpy(lpszFileBuffer, lpszFile); + + // Get filters + if (0!=iFilterString) + cch = LoadString(ghInst, iFilterString, (LPTSTR)szFilters, + OLEUI_CCHPATHMAX); + else + { + szFilters[0]=0; + cch=1; + } + if (0==cch) { + fStatus = FALSE; + goto cleanup; + } + + ReplaceCharWithNull(szFilters, szFilters[cch-1]); + + LSTRCPYN((LPTSTR)szDir, lpszFile, OLEUI_CCHPATHMAX); + for (cch = lstrlen((LPTSTR)szDir) - 1; cch >= 0; cch--) + { + if ((szDir[cch]==TEXT('\\')) || (szDir[cch]==TEXT(':')) || (szDir[cch]==TEXT('/'))) + break; + } + if (cch < 0) + cch = 0; + + szDir[cch] = TEXT('\0'); + + LoadString(ghInst, IDS_CHANGESOURCE, (LPTSTR)szTitle, OLEUI_CCHPATHMAX); + _fmemset((LPOPENFILENAME)&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hWndOwner; + ofn.lpstrFile = lpszFileBuffer; + ofn.nMaxFile = cchFile; + ofn.lpstrFilter = (LPTSTR)szFilters; + ofn.nFilterIndex = 1; + ofn.lpstrTitle = (LPTSTR)szTitle; + ofn.lpstrInitialDir = (LPTSTR)szDir; + ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEOPEN); + ofn.lpfnHook = lpfnBrowseHook; + ofn.hInstance = ghInst; + ofn.lCustData = (LPARAM)lpCshData; + ofn.Flags = OFN_NOVALIDATE | OFN_HIDEREADONLY | + OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; + + // Only show help button if edit links dialog shows it. + if (lpCshData->lpEL->lpOEL->dwFlags & ELF_SHOWHELP) + ofn.Flags |= OFN_SHOWHELP; + + fStatus = GetOpenFileName((LPOPENFILENAME)&ofn); + +cleanup: + OleStdFree((LPVOID)lpszFileBuffer); + return fStatus; + +} + +/* +* 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) +{ + UINT uRet; + int cSelItems; + int FAR* rgIndex; + int i = 0; + LPLINKINFO lpLI; + HWND hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX); + LPOLEUILINKCONTAINER lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer; + OLEUICHANGESOURCEHOOKDATA cshData; // Data that needs to be accessed + // by the ChangeSource dialog hook + + cSelItems = GetSelectedItems(hListBox, &rgIndex); + + if (cSelItems < 0) + return FALSE; + + if (!cSelItems) + return TRUE; + + if (!lpEL->fClose) { + SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPTSTR)lpEL->szClose); + lpEL->fClose = TRUE; + } + + _fmemset((LPOLEUICHANGESOURCEHOOKDATA)&cshData, 0, sizeof(cshData)); + cshData.cbStruct=sizeof(cshData); + cshData.hWndOwner=hDlg; + cshData.lpEL = (LPEDITLINKS)lpEL; + cshData.lpszFrom = NULL; + cshData.lpszTo = NULL; + + for (i = cSelItems-1; i >=0; i--) { + SendMessage(hListBox, LB_GETTEXT, rgIndex[i], + (LPARAM) (LPLINKINFO FAR*) &lpLI); + + uRet = UStandardHook(lpEL, hDlg, uMsgBrowse, + OLEUI_CCHPATHMAX_SIZE, (LONG)(LPTSTR)lpLI->lpszDisplayName); + + if (!uRet) { + cshData.lpLI = lpLI; + /* Bring up the ChangeSource dialog after hooking it so + ** that the user specified link source is verified + ** when OK is pressed. + */ + uRet = (UINT)ChangeSource(hDlg, lpLI->lpszDisplayName, + OLEUI_CCHPATHMAX, IDS_FILTERS, ChangeSourceHook, + &cshData); + } + + /* If Cancel is pressed in any ChangeSource dialog, stop + ** the ChangeSource processing for all links. + */ + if (!uRet) { + if (rgIndex) + OleStdFree(rgIndex); + return TRUE; + } + + UpdateLinkLBItem(hListBox, rgIndex[i], lpEL, TRUE); + + if (cshData.lpszFrom && cshData.lpszTo) { + ChangeAllLinks(hListBox, lpOleUILinkCntr, cshData.lpszFrom, + cshData.lpszTo); + OleStdFree(cshData.lpszFrom); + OleStdFree(cshData.lpszTo); + } + + } // end FOR + + + if (rgIndex) + 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, ID_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; + + if (!lpEL->fClose) + SetDlgItemText(hDlg, IDCANCEL, (LPTSTR)lpEL->szClose); + + for (i = 0; i < cSelItems; i++) { + SendMessage(hListBox, LB_GETTEXT, (WPARAM)rgIndex[i], + (LPARAM) (LPLINKINFO FAR*) &lpLI); + + if (fAutoMan) { // If switching to AUTOMATIC + if (!lpLI->fIsAuto) { // Only change MANUAL links + OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::SetLinkUpdateOptions called\r\n")); + hErr=lpOleUILinkCntr->lpVtbl->SetLinkUpdateOptions( + lpOleUILinkCntr, + 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->lpVtbl->SetLinkUpdateOptions( + lpOleUILinkCntr, + 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); + + 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, ID_EL_LINKSLISTBOX); + BOOL bUpdate = FALSE; + + OleDbgAssert(lpOleUILinkCntr); + + lpmk = NULL; + + cSelItems = GetSelectedItems(hListBox, &rgIndex); + + if (cSelItems < 0) + return ResultFromScode(E_FAIL); + + if (!cSelItems) + return NOERROR; + + if (!lpEL->fClose) { + SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPTSTR)lpEL->szClose); + lpEL->fClose = TRUE; + } + + for (i = 0; i < cSelItems; i++) { + SendMessage(hListBox, LB_GETTEXT, (WPARAM)rgIndex[i], + (LPARAM)(LPLINKINFO FAR*) &lpLI); + + OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::CancelLink called\r\n")); + hErr = lpOleUILinkCntr->lpVtbl->CancelLink( + lpOleUILinkCntr, + lpLI->dwLink + ); + OLEDBG_END2 + + 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); + + } + + if (bUpdate) + RefreshLinkLB(hListBox, lpOleUILinkCntr); + + if (rgIndex) + OleStdFree((LPVOID)rgIndex); + + 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, ID_EL_LINKSLISTBOX); + BOOL bUpdate = FALSE; + + OleDbgAssert(lpOleUILinkCntr); + + cSelItems = GetSelectedItems(hListBox, &rgIndex); + + if (cSelItems < 0) + return ResultFromScode(E_FAIL); + + if (!cSelItems) + return NOERROR; + + if (!lpEL->fClose) { + SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPTSTR)lpEL->szClose); + lpEL->fClose = TRUE; + } + + for (i = 0; i < cSelItems; i++) { + SendMessage(hListBox, LB_GETTEXT, + (WPARAM)rgIndex[i], (LPARAM)(LPLINKINFO FAR*)&lpLI); + + OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::UpdateLink called\r\n")); + hErr = lpOleUILinkCntr->lpVtbl->UpdateLink( + lpOleUILinkCntr, + 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); + + 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, ID_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; + + if (!lpEL->fClose) { + SetWindowText(GetDlgItem(hDlg, IDCANCEL), (LPTSTR)lpEL->szClose); + lpEL->fClose = TRUE; + } + + SendMessage(hListBox, LB_GETTEXT, (WPARAM)rgIndex[0], + (LPARAM)(LPLINKINFO FAR*)&lpLI); + + OLEDBG_BEGIN2(TEXT("IOleUILinkContainer::OpenLinkSource called\r\n")); + hErr = lpOleUILinkCntr->lpVtbl->OpenLinkSource( + lpOleUILinkCntr, + 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); + + 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->lpVtbl->GetLinkSource( + lpOleUILinkCntr, + 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->lpVtbl->GetLinkUpdateOptions( + lpOleUILinkCntr, + 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(ghInst, IDS_LINK_AUTO, lpLI->lpszAMX, + (int)OleStdGetSize((LPVOID)lpLI->lpszAMX)); + } + else { + lpLI->fIsAuto = FALSE; + LoadString(ghInst, IDS_LINK_MANUAL, lpLI->lpszAMX, + (int)OleStdGetSize((LPVOID)lpLI->lpszAMX)); + } + } + else + LoadString(ghInst, IDS_LINK_UNKNOWN, lpLI->lpszAMX, + (int)OleStdGetSize((LPVOID)lpLI->lpszAMX)); + + 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) { +#ifdef WIN32 + // AnsiPrev is obsolete in Win32 + lpsz = CharPrev(lpLI->lpszDisplayName, lpsz); +#else + lpsz = AnsiPrev(lpLI->lpszDisplayName, lpsz); +#endif + if ((*lpsz == TEXT('\\')) || (*lpsz == TEXT('/')) || (*lpsz == TEXT(':'))) + break; + } + + if (lpsz == lpLI->lpszDisplayName) + lpLI->lpszShortFileName = lpsz; + else +#ifdef WIN32 + // AnsiNext is obsolete in Win32 + lpLI->lpszShortFileName = CharNext(lpsz); +#else + lpLI->lpszShortFileName = AnsiNext(lpsz); +#endif +} + + +/* 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[OLEUI_CCHPATHMAX]; + LPTSTR lpsz; + + + hListBox = GetDlgItem(hDlg, ID_EL_LINKSLISTBOX); + + cSelItems = GetSelectedItems(hListBox, &rgIndex); + if (cSelItems < 0) + return; + + EnableWindow(GetDlgItem(hDlg, ID_EL_AUTOMATIC), (BOOL)cSelItems); + EnableWindow(GetDlgItem(hDlg, ID_EL_MANUAL), (BOOL)cSelItems); + if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLECANCELLINK)) + EnableWindow(GetDlgItem(hDlg, ID_EL_CANCELLINK), (BOOL)cSelItems); + if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLEOPENSOURCE)) + EnableWindow(GetDlgItem(hDlg, ID_EL_OPENSOURCE), cSelItems == 1); + if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLECHANGESOURCE)) + EnableWindow(GetDlgItem(hDlg, ID_EL_CHANGESOURCE), cSelItems == 1); + if (lpEL && !(lpEL->lpOEL->dwFlags & ELF_DISABLEUPDATENOW)) + EnableWindow(GetDlgItem(hDlg, ID_EL_UPDATENOW), (BOOL)cSelItems); + + for (i = 0; i < cSelItems; i++) { + SendDlgItemMessage( + hDlg, + ID_EL_LINKSLISTBOX, + LB_GETTEXT, + (WPARAM)rgIndex[i], + (LPARAM)(LPLINKINFO FAR*)&lpLI); + + 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, ID_EL_AUTOMATIC, cAuto && !cManual); + CheckDlgButton(hDlg, ID_EL_MANUAL, !cAuto && cManual); + + /* fill full source in static text box + ** below list + */ + if (!bSameSource || !lpszSource) + lpszSource = szNULL; + lstrcpy((LPTSTR)tsz, lpszSource); + lpsz = ChopText(GetDlgItem(hDlg, ID_EL_LINKSOURCE), 0, tsz); + SetDlgItemText(hDlg, ID_EL_LINKSOURCE, lpsz); + + /* fill full link type name in static + ** "type" text box + */ + if (!bSameType || !lpszType) + lpszType = szNULL; + SetDlgItemText(hDlg, ID_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; + DWORD dwErr; + LPOLEUILINKCONTAINER lpOleUILinkCntr; + + if (!hListBox || (nIndex < 0) || !lpEL) + return; + + lpOleUILinkCntr = lpEL->lpOEL->lpOleUILinkContainer; + + dwErr = SendMessage(hListBox, LB_GETTEXT, nIndex, + (LPARAM)(LPLINKINFO FAR*) &lpLI); + + if ((dwErr == LB_ERR) || !lpLI) + 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, (WPARAM)TRUE, MAKELPARAM(nIndex, 0)); + SendMessage(hListBox, LB_SETCARETINDEX, (WPARAM)nIndex, MAKELPARAM(TRUE, 0)); + } +} + + + +/* 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 DiffPrefix(LPCTSTR lpsz1, LPCTSTR lpsz2, TCHAR FAR* FAR* lplpszPrefix1, TCHAR FAR* FAR* lplpszPrefix2) +{ + LPTSTR lpstr1; + LPTSTR lpstr2; + + OleDbgAssert(lpsz1 && lpsz2 && *lpsz1 && *lpsz2 && lplpszPrefix1 && + lplpszPrefix2); + + *lplpszPrefix1 = NULL; + *lplpszPrefix2 = NULL; +#ifdef WIN32 + *lplpszPrefix1 = OleStdMalloc((lstrlen(lpsz1)+1) * sizeof(TCHAR)); +#else + *lplpszPrefix1 = OleStdMalloc((lstrlen(lpsz1)+1) * sizeof(BYTE)); +#endif + if (!*lplpszPrefix1) + return; + +#ifdef WIN32 + *lplpszPrefix2 = OleStdMalloc((lstrlen(lpsz2)+1) * sizeof(TCHAR)); +#else + *lplpszPrefix2 = OleStdMalloc((lstrlen(lpsz2)+1) * sizeof(BYTE)); +#endif + if (!*lplpszPrefix2) { + OleStdFree(*lplpszPrefix1); + *lplpszPrefix1 = NULL; + return; + } + + lstrcpy(*lplpszPrefix1, lpsz1); + lstrcpy(*lplpszPrefix2, lpsz2); +// AnsiLower(*lplpszPrefix1); +// AnsiLower(*lplpszPrefix2); + + lpstr1 = *lplpszPrefix1 + lstrlen(*lplpszPrefix1); + lpstr2 = *lplpszPrefix2 + lstrlen(*lplpszPrefix2); + + while ((lpstr1>*lplpszPrefix1) && (lpstr2>*lplpszPrefix2)) { +#ifdef WIN32 + lpstr1 = CharPrev(*lplpszPrefix1, lpstr1); + lpstr2 = CharPrev(*lplpszPrefix2, lpstr2); +#else + lpstr1 = AnsiPrev(*lplpszPrefix1, lpstr1); + lpstr2 = AnsiPrev(*lplpszPrefix2, lpstr2); +#endif + if (*lpstr1 != *lpstr2) { +#ifdef WIN32 + // AnsiNext is obsolete in Win32 + lpstr1 = CharNext(lpstr1); + lpstr2 = CharNext(lpstr2); +#else + lpstr1 = AnsiNext(lpstr1); + lpstr2 = AnsiNext(lpstr2); +#endif + break; + } + } + + for (; *lpstr1 && *lpstr1!=TEXT('\\') && *lpstr1!=TEXT('!'); +#ifdef WIN32 + lpstr1=CharNext(lpstr1)); +#else + lpstr1=AnsiNext(lpstr1)); +#endif + for (; *lpstr2 && *lpstr2!=TEXT('\\') && *lpstr2!=TEXT('!'); +#ifdef WIN32 + lpstr2=CharNext(lpstr2)); +#else + lpstr2=AnsiNext(lpstr2)); +#endif + + *lpstr1 = TEXT('\0'); + *lpstr2 = TEXT('\0'); +} + + +/* PopupMessage + * ------------ + * + * Purpose: + * Popup s 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 PopupMessage(HWND hwndParent, UINT idTitle, UINT idMessage, UINT fuStyle) +{ + TCHAR szTitle[256]; + TCHAR szMsg[256]; + + LoadString(ghInst, idTitle, (LPTSTR)szTitle, sizeof(szTitle)/sizeof(TCHAR)); + LoadString(ghInst, idMessage, (LPTSTR)szMsg, sizeof(szMsg)/sizeof(TCHAR)); + return MessageBox(hwndParent, szMsg, szTitle, fuStyle); +} + + +/* 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; + LPTSTR szTmp[OLEUI_CCHPATHMAX]; + BOOL bFound; + + cFrom = lstrlen(lpszFrom); + + cItems = (int)SendMessage(hListBox, LB_GETCOUNT, 0, 0L); + OleDbgAssert(cItems >= 0); + + bFound = FALSE; + + 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); + + for (nIndex=0; nIndex<cItems; nIndex++) { + SendMessage(hListBox, LB_GETTEXT, nIndex, + (LPARAM)(LPLINKINFO FAR*)&lpLI); + + // 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) == TEXT('\\')) || + (*(lpLI->lpszDisplayName + cFrom) == TEXT('!'))) { + + LSTRCPYN((LPTSTR)szTmp, lpLI->lpszDisplayName, cFrom + 1); + if (!lstrcmp((LPTSTR)szTmp, lpszFrom)) { + HRESULT hErr; + int nFileLength; + ULONG ulDummy; + + if (!bFound) { + TCHAR szTitle[256]; + TCHAR szMsg[256]; + TCHAR szBuf[256]; + int uRet; + + LoadString(ghInst, IDS_CHANGESOURCE, (LPTSTR)szTitle, + sizeof(szTitle)/sizeof(TCHAR)); + LoadString(ghInst, IDS_CHANGEADDITIONALLINKS, + (LPTSTR)szMsg, sizeof(szMsg)/sizeof(TCHAR)); + wsprintf((LPTSTR)szBuf, (LPTSTR)szMsg, lpszFrom); + uRet = MessageBox(hListBox, (LPTSTR)szBuf, (LPTSTR)szTitle, + MB_ICONQUESTION | MB_YESNO); + if (uRet == IDYES) + bFound = TRUE; + else + return; // exit function + } + + lstrcpy((LPTSTR)szTmp, lpszTo); + lstrcat((LPTSTR)szTmp, lpLI->lpszDisplayName + cFrom); + nFileLength = lstrlen((LPTSTR)szTmp) - + (lpLI->lpszItemName ? lstrlen(lpLI->lpszItemName) : 0); + + + hErr = lpOleUILinkCntr->lpVtbl->SetLinkSource( + lpOleUILinkCntr, + lpLI->dwLink, + (LPTSTR)szTmp, + (ULONG)nFileLength, + (ULONG FAR*)&ulDummy, + TRUE + ); + if (hErr != NOERROR) + lpOleUILinkCntr->lpVtbl->SetLinkSource( + lpOleUILinkCntr, + lpLI->dwLink, + (LPTSTR)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->lpVtbl->GetNextLink(lpOleUILinkCntr, + dwLink)) != 0) { + lpLI = (LPLINKINFO)OleStdMalloc(sizeof(LINKINFO)); + if (NULL == lpLI) + return -1; + + lpLI->fIsMarked = FALSE; + lpLI->fIsSelected = FALSE; + lpLI->fDontFree = FALSE; + +#ifdef WIN32 + lpLI->lpszAMX = (LPTSTR)OleStdMalloc((LINKTYPELEN+1)*sizeof(TCHAR)); +#else + lpLI->lpszAMX = (LPTSTR)OleStdMalloc((LINKTYPELEN+1)*sizeof(BYTE)); +#endif + + 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++) { + SendMessage(hListBox, LB_GETTEXT, nIndex, + (LPARAM)(LPLINKINFO FAR*)&lpLI); + 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/oleutest/letest/ole2ui/links.dlg b/private/oleutest/letest/ole2ui/links.dlg new file mode 100644 index 000000000..6bc8d7258 --- /dev/null +++ b/private/oleutest/letest/ole2ui/links.dlg @@ -0,0 +1,35 @@ +// DLGINCLUDE RCDATA DISCARDABLE +// BEGIN +// "OLE2UI.H\0" +// END + +IDD_EDITLINKS DIALOG 9, 25, 320, 158 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Links" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Links:", ID_EL_COL1, 11, 11, 26, 8 + LTEXT "Type", ID_EL_COL2, 137, 12, 20, 8 + LTEXT "Update", ID_EL_COL3, 201, 12, 25, 8 + LISTBOX ID_EL_LINKSLISTBOX, 11, 23, 229, 81, LBS_OWNERDRAWFIXED + | LBS_EXTENDEDSEL | WS_VSCROLL | LBS_USETABSTOPS + | WS_TABSTOP | LBS_SORT | LBS_NOTIFY + DEFPUSHBUTTON "Cancel", IDCANCEL, 249, 11, 66, 14 + PUSHBUTTON "&Update Now", ID_EL_UPDATENOW, 249, 34, 66, 14 + PUSHBUTTON "&Open Source", ID_EL_OPENSOURCE, 249, 54, 66, 14, + WS_GROUP + PUSHBUTTON "&Change Source...", ID_EL_CHANGESOURCE, 249, 73, 66, 14, + WS_GROUP + PUSHBUTTON "&Break Link", ID_EL_CANCELLINK, 249, 96, 66, 14 + PUSHBUTTON "&Help", ID_OLEUIHELP, 249, 136, 66, 14 + CONTROL "&Automatic", ID_EL_AUTOMATIC, "Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 61, 138, 65, + 10 + CONTROL "&Manual", ID_EL_MANUAL, "Button", BS_AUTORADIOBUTTON, + 130, 138, 39, 10 + LTEXT "Source:", 219, 9, 113, 30, 8 + LTEXT "Type:", 220, 9, 125, 20, 8 + LTEXT "Update:", ID_EL_UPDATE, 9, 139, 32, 8 + LTEXT "", ID_EL_LINKSOURCE, 45, 113, 195, 8, SS_NOPREFIX + LTEXT "", ID_EL_LINKTYPE, 45, 125, 195, 8, SS_NOPREFIX +END diff --git a/private/oleutest/letest/ole2ui/makefile b/private/oleutest/letest/ole2ui/makefile new file mode 100644 index 000000000..21eedcbe0 --- /dev/null +++ b/private/oleutest/letest/ole2ui/makefile @@ -0,0 +1,12 @@ +# +# 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 +# +!ifdef NTMAKEENV +all: + echo $(BUILDMSG) +clean: all +!else +!INCLUDE $(NTMAKEENV)\makefile.def +!endif diff --git a/private/oleutest/letest/ole2ui/makefile.32 b/private/oleutest/letest/ole2ui/makefile.32 new file mode 100644 index 000000000..e69bb6ff8 --- /dev/null +++ b/private/oleutest/letest/ole2ui/makefile.32 @@ -0,0 +1,590 @@ +########################################################################## +# +# Makefile for OUTLUI.DLL +# +# Usage: NMAKE (builds DEBUG library) +# or: NMAKE RELEASE=1 (builds RELEASE library -- no debug symbols) +# or: NMAKE clean (erase all compiled files) +# +# Environment variables: +# DEVROOT_DIR=<path> (root dir for sample code development) +# +########################################################################## + +LIBNAME = outlui + +!ifndef DEVROOT_DIR +!error You must define DEVROOT_DIR (ole20 sub-tree) +!endif +!ifndef INCLUDE +!error You must define INCLUDE (non ole20 include files) +!endif +!ifndef LIB +!error You must deinfe LIB (non ole20 libraries) +!endif +!ifndef OLEBUILD +OLEBUILD=NT +!endif + +OLE2_H=$(DEVROOT_DIR)\h +OLE2_LIB=$(DEVROOT_DIR)\lib + +!ifndef SAMPLE_DIR +SAMPLE_DIR = $(DEVROOT_DIR)\samples +!endif +SRC_DIR = $(SAMPLE_DIR)\$(APP) + +MAKEFILE = makefile.32 + +# ============================================================================ +# File: M A K E F I L E +# +# NMAKE description file for the OLE2.0 User Interface DLL +# +# Copyright (C) Microsoft Corporation, 1992-1993. All Rights Reserved. +# Microsoft Confidential. +# ============================================================================ + +# ---------------------------------------------------------------------------- +# U I M A K E . I N I +# ---------------------------------------------------------------------------- + + +!if "$(OLEBUILD)" == "DOS" || "$(OLEBUILD)" == "" +DOS=1 +!endif + +!if "$(OLEBUILD)" == "NT" +NT=1 + +!if "$(MACHINE)" == "i386" || "$(MACHINE)" == "" +MACHINE = i386 +MACHINE_D = _X86_ +MACHINE_CC = cl386 +!endif + +!if "$(MACHINE)" == "MIPS" +MACHINE = mips +MACHINE_D = _MIPS_ +MACHINE_CC = cc +!endif + +!endif + +!include "uimake.ini" + +!ifndef LANG +LANG=USA +!endif + +!ifndef BUILD +BUILD=dll +!endif + +GOAL: MAKEINI + nmake -f $(MAKEFILE) PRELUDE SETFLAGS $(LIBNAME).$(BUILD) + + +MAKEINI: + nmake -f $(MAKEFILE) LIBNAME=$(LIBNAME) LANG=$(LANG) BUILD=$(BUILD) RESOURCE=RESOUCE REL_DIR=$(OLEREL_DIR) DEBUG + + +!if "$(INSTALL_DIR)"=="" +INSTALL_DIR = $(REL_DIR) +!endif + +#use src/tok pairs to build if localized version +!if ("$(LANG)"!="USA") && ("$(LANG)"!="usa") +SRCTOK=1 +!endif + +# ---------------------------------------------------------------------------- +# O B J E C T F I L E L I S T +# ---------------------------------------------------------------------------- + +UI_COBJS = \ + D^\busy.obj\ + D^\common.obj\ + D^\convert.obj\ + D^\dbgutil.obj\ + D^\drawicon.obj\ + D^\hatch.obj\ + D^\icon.obj\ + D^\iconbox.obj\ + D^\insobj.obj\ + D^\links.obj\ + D^\msgfiltr.obj\ + D^\enumfetc.obj\ + D^\objfdbk.obj\ + D^\ole2ui.obj\ + D^\olestd.obj\ + D^\targtdev.obj\ + D^\oleutl.obj\ + D^\pastespl.obj\ + D^\regdb.obj\ + D^\resimage.obj\ + D^\utility.obj\ + +UI_NOPCOBJS = \ + D^\geticon.obj\ + +UI_DLLOBJS = \ + D^\dllfuncs.obj\ + +PRECOMPOBJ=$(O)precomp.obj + +PRECOMP=$(O)precomp.pch + +# ---------------------------------------------------------------------------- +# R E S O U R C E L I S T +# ---------------------------------------------------------------------------- +RES = \ + busy.h \ + common.h \ + convert.h \ + edlinks.h \ + geticon.h \ + icon.h \ + iconbox.h \ + insobj.h \ + msgfiltr.h \ + enumfetc.h \ + ole2ui.h \ + pastespl.h \ + resimage.h \ + $(RESOURCE)\STATIC\default.ico \ + $(RESOURCE)\STATIC\bang.ico \ + $(RESOURCE)\STATIC\egares.bmp \ + $(RESOURCE)\STATIC\hivgares.bmp \ + $(RESOURCE)\STATIC\vgares.bmp \ + $(RESOURCE)\$(LANG)\strings.rc \ + $(RESOURCE)\$(LANG)\busy.dlg \ + $(RESOURCE)\$(LANG)\convert.dlg \ + $(RESOURCE)\$(LANG)\fileopen.dlg \ + $(RESOURCE)\$(LANG)\icon.dlg \ + $(RESOURCE)\$(LANG)\insobj.dlg \ + $(RESOURCE)\$(LANG)\links.dlg \ + $(RESOURCE)\$(LANG)\pastespl.dlg \ + $(RESOURCE)\$(LANG)\prompt.dlg \ + $(RESOURCE)\ole2ui.rcv \ + $(RESOURCE)\$(LANG)\verlocal.h \ + +# ---------------------------------------------------------------------------- +# D E B U G S T A T I C L I B M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +DEBUGLIB: + @echo Creating DEBUG LIB <<uimake.ini +# This is the DEBUG static .LIB UILibrary INI file +MSG=DEBUG Static LIB Version ($$(LANG)) +DEBUG=1 +MODEL=M +# Make a static library called OLE2UI.LIB +LIBNAME=OLE2UI +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=DEBUGLIB +BUILD=LIB +RESOURCE=RESOURCE +CFLAGS=-c -Od -GA2s -W3 -Zpei -A$(MODEL) -D_DEBUG +RFLAGS=-D DEBUG +LFLAGS=/MAP:FULL /CO /LINE /NOD /NOE /SE:300 +UILIBS=mlibcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +LANG=$(LANG) +LIBOBJS = $$(UI_COBJS:D^\=DEBUGLIB^\) $$(UI_NOPCOBJS:D^\=DEBUGLIB\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define OLEUICLASS1 "$(LIBNAME)Class1" +#define OLEUICLASS2 "$(LIBNAME)Class2" +<<KEEP + @echo Enter "$(MAKE)" to make Debug static LIB UILibrary + + +# ---------------------------------------------------------------------------- +# R E T A I L S T A T I C L I B M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +RETAILIB: + @echo Creating RETAIL LIB <<uimake.ini +# This is the RETAIL static .LIB UILibrary INI file +MSG=RETAIL Static LIB Version ($$(LANG)) +RETAIL=1 +MODEL=M +# Make a static library called OLE2UI.LIB +LIBNAME=OLE2UI +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=RETAILIB +BUILD=LIB +RESOURCE=RESOURCE +CFLAGS=-c -Os -GA2s -W3 -Zpe -A$(MODEL) +RFLAGS= +LFLAGS=/MAP:FULL /LINE /NOD /NOE /SE:300 +UILIBS=mlibcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +LANG=$(LANG) +LIBOBJS = $$(UI_COBJS:D^\=RETAILIB^\) $$(UI_NOPCOBJS:D^\=RETAILIB\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define OLEUICLASS1 "$(LIBNAME)Class1" +#define OLEUICLASS2 "$(LIBNAME)Class2" +<<KEEP + @echo Enter "$(MAKE)" to make Retail static LIB UILibrary + +# ---------------------------------------------------------------------------- +# D E B U G M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +!ifdef NT + +DEBUG: + @echo Creating DEBUG for NT <<uimake.ini +# This is the DEBUG UILibrary INI file +MSG=DEBUG Version ($$(LANG)) +DEBUG=1 +LIBNAME=$(LIBNAME) +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=DEBUG +RESOURCE=RESOURCE + +CC = $(MACHINE_CC) +DEFS1 = /D$(MACHINE_D) /D_DEBUG /D_DEBUGTRACE=0 /DWIN32 /DOLE2SHIP +DEFS2 = /D$(MACHINE)=1 /D_NTWIN /D_WINDOWS /DWINVER=0x030A /D_NTDLL /D_DLL +CFLAGS = $$(DEFS1) $$(DEFS2) /Z7 /Od /c /Fc /G3 /W3 /nologo $(CL) +LFLAGS = -subsystem:windows -machine:$(MACHINE) -debug:mapped,full -debugtype:both +RFLAGS = /DWIN32 /D_DEBUG +UILIBS1 = mpr.lib crtdll.lib ntdll.lib +UILIBS2 = ole2w32.lib storag32.lib +UILIBS3 = kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib comdlg32.lib +UILIBS = $$(UILIBS1) $$(UILIBS2) $$(UILIBS3) + +LK = link32 + +LANG = $(LANG) +RS = rc + +DLLOBJS = $$(UI_DLLOBJS:D^\=DEBUG^\) +LIBOBJS = $$(UI_COBJS:D^\=DEBUG^\) $$(UI_NOPCOBJS:D^\=DEBUG\NOPC^\) +<<KEEP + @echo Enter "$(MAKE)" to make Debug UILibrary + +!else + +DEBUG: + @echo Creating DEBUG <<uimake.ini +# This is the DEBUG UILibrary INI file +MSG=DEBUG DLL Version ($$(LANG)) +DEBUG=1 +MODEL=M +LIBNAME=$(LIBNAME) +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=DEBUG +BUILD=DLL +RESOURCE=RESOURCE +CFLAGS=-c -Od -GD2s -W3 -Zpei -AMw -D_DEBUG -DDLL_VER -D_WINDLL +RFLAGS=-D DEBUG -D DLL_VER +LFLAGS=/MAP:FULL /CO /LINE /NOD /NOE /SE:300 +UILIBS=mdllcew libw ole2 storage shell commdlg toolhelp +CC=cl +RS=rc +LK=link +LANG=$(LANG) +DLLOBJS = $$(UI_DLLOBJS:D^\=DEBUG^\) +LIBOBJS = $$(UI_COBJS:D^\=DEBUG^\) $$(UI_NOPCOBJS:D^\=DEBUG\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define OLEUICLASS1 "$(LIBNAME)Class1" +#define OLEUICLASS2 "$(LIBNAME)Class2" +<<KEEP + @echo Enter "$(MAKE)" to make Debug UILibrary + +!endif +# ---------------------------------------------------------------------------- +# R E T A I L D L L M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +RETAIL: + @echo Creating RETAIL <<uimake.ini +# This is the RETAIL UILibrary INI file +MSG=RETAIL DLL Version ($$(LANG)) +RETAIL=1 +MODEL=M +LIBNAME=$(LIBNAME) +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=RETAIL +BUILD=DLL +RESOURCE=RESOURCE +CFLAGS=-c -Os -GD2s -W3 -Zpe -AMw -DOPTIMIZE -DDLL_VER -D_WINDLL +RFLAGS=-D DLL_VER +LFLAGS=/MAP /NOD /NOE /SE:300 /AL:16 +UILIBS=mdllcew libw ole2 storage shell commdlg toolhelp +CC=cl +RS=rc +LK=link +LANG=$(LANG) +DLLOBJS = $$(UI_DLLOBJS:D^\=RETAIL^\) +LIBOBJS = $$(UI_COBJS:D^\=RETAIL^\) $$(UI_NOPCOBJS:D^\=RETAIL\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define OLEUICLASS1 "$(LIBNAME)Class1" +#define OLEUICLASS2 "$(LIBNAME)Class2" +<<KEEP + @echo Enter "$(MAKE)" to make Retail UILibrary + +!if [if not exist $(OBJ)\*. md $(OBJ) >nul] +!error Object subdirectory $(OBJ)\ could not be created +!endif +!if [if not exist $(OBJ)\NOPC\*. md $(OBJ)\NOPC > nul] +!error non-precompiled header object subdirectory $(OBJ)\NOPC\ could not be created +!endif + +#select language for version resource if localized version +!if ("$(LANG)"!="USA") && ("$(LANG)"!="usa") +RFLAGS=$(RFLAGS) -D VER_LOC +!endif + +!if ("$(LIBNAME)"=="PUBOLEUI") +RFLAGS=$(RFLAGS) -D PUBLISHER +!endif + +.SUFFIXES: .c .asm .obj .res .rc .def .bmp .ico .exe .dll .cod .str + +O=.\$(OBJ)^\ + +# ---------------------------------------------------------------------------- +# I N F E R E N C E R U L E S +# ---------------------------------------------------------------------------- +# compile C file without precompiled headers into object directory\NOPC +# dont compile c files etc for lcoalized builds. +!ifndef SRCTOK + +{}.c{$(O)NOPC\}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) + $(CC) -Fo$(O)NOPC\$(@B) $(@B).c +!else + $(CC) $(CFLAGS) -Fo$(O)NOPC\$(@B) $(@B).c +!endif + +# compile C file into object directory +{}.c{$(O)}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch + $(CC) -Fo$(O)$(@B) $(@B).c +!else + $(CC) $(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch -Fo$(O)$(@B) $(@B).c +!endif + +!endif +#endif SRCTOK + +{}.rc{$(O)}.res: + @echo ²²²²²²²²²²²²²²²²²²² Resource Compiling $(@B).res ²²²²²²²²²²²²²²²²²²²² + $(RS) -I $(RESOURCE)\$(LANG);$(RESOURCE)\static;$(RESOURCE) -FO $(O)$(@B).res -R $(RFLAGS) $(@B).rc + -del $(LIBNAME).dll + +!ifndef SRCTOK +{}.c.cod: + @echo ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Making $(@B).cod ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ +!ifdef DOS + SET CL=$(CFLAGS) -f -Fc + $(CC) $(@B).c +!else + $(CC) $(CFLAGS) -f- -Fc $(@B).c +!endif +!endif +#endif SRCTOK + + +# rules for creating rc & dlg files for localized verisons from src/tok pairs +!ifdef SRCTOK + +$(RESOURCE)\$(LANG)\busy.dlg : $(RESOURCE)\$(LANG)\busy.tok $(RESOURCE)\src\busy.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\convert.dlg : $(RESOURCE)\$(LANG)\convert.tok $(RESOURCE)\src\convert.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\fileopen.dlg : $(RESOURCE)\$(LANG)\fileopen.tok $(RESOURCE)\src\fileopen.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\icon.dlg : $(RESOURCE)\$(LANG)\icon.tok $(RESOURCE)\src\icon.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\insobj.dlg : $(RESOURCE)\$(LANG)\insobj.tok $(RESOURCE)\src\insobj.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\links.dlg : $(RESOURCE)\$(LANG)\links.tok $(RESOURCE)\src\links.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\pastespl.dlg : $(RESOURCE)\$(LANG)\pastespl.tok $(RESOURCE)\src\pastespl.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\prompt.dlg : $(RESOURCE)\$(LANG)\prompt.tok $(RESOURCE)\src\prompt.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\strings.rc : $(RESOURCE)\$(LANG)\strings.tok $(RESOURCE)\src\strings.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ +!endif + +# ---------------------------------------------------------------------------- +# D E P E N D F I L E C R E A T I O N +# ---------------------------------------------------------------------------- +UI_CFILE = $(UI_COBJS:.obj=.c) $(UI_DLLOBJS:.obj=.c) +UI_NOPCFILE = $(UI_NOPCOBJS:.obj=.c) +DEPEND: nul + @echo Making a NEW dependancy file. + mkdep -p $$(O) -s .obj $(UI_CFILE:D^\=) > tmp.tmp + sed "s/:/: $$(PRECOMP)/g" < tmp.tmp > depend + -del tmp.tmp + mkdep -p $$(O)NOPC\ -s .obj $(UI_NOPCFILE:D^\=) >> depend + mkdep -p $$(O) -s .pch precomp.c >> depend + +# ---------------------------------------------------------------------------- +# W E L C O M E B A N N E R +# ---------------------------------------------------------------------------- +PRELUDE: + @echo ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» + @echo º Makefile for UILibrary º + @echo ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ + @echo $(MSG) +!ifndef SRCTOK + set INCLUDE=$(OLEREL_DIR);$(INCLUDE) + set LIB=$(OLEREL_DIR);$(LIB) +!endif + +SETFLAGS: + set INCLUDE=$(INCLUDE);$(OLE2_H) + set LIB=$(LIB);$(OLE2_LIB) + + +# ---------------------------------------------------------------------------- +# G O A L T A R G E T S +# ---------------------------------------------------------------------------- +!include "depend" + +CLEAN: CleanUp GOAL + +CleanUp: MAKEINI + nmake -f $(MAKEFILE) SETFLAGS Delete + +Delete: + -echo y|del .\$(OBJ)\*.* + -del $(LIBNAME).dll + -del $(LIBNAME).lib + +!ifndef SRCTOK + +$(O)precomp.pch: precomp.c +!ifdef DOS + SET CL=$(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h + $(CC) -Fo$(O)$(@B) precomp.c +!else + $(CC) $(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h -Fo$(O)$(@B) precomp.c +!endif +!endif +#endif SRCTOK + +$(O)ole2ui.res: ole2ui.rc $(RES) + +ole2ui.rc : $(RESOURCE)\$(LANG)\strings.rc + +# +# Build .LIB static library +# + +$(LIBNAME).lib: $(LIBOBJS) $(PRECOMPOBJ) + -del $(O)$(LIBNAME).lib + lib @<< +$(O)$(LIBNAME).lib +y +$(PRECOMPOBJ: = +) $(LIBOBJS: = +) + +<< + copy $(O)$(LIBNAME).lib $(LIBNAME).lib + +# +# Build .DLL dynamic-link library +# + +!if "$(OLEBUILD)" == "NT" +!else +$(O)$(LIBNAME).lib: $(LIBOBJS) $(PRECOMPOBJS) + -del $(O)$(LIBNAME).lib + lib @<< +$(O)$(LIBNAME).lib +y +$(PRECOMPOBJ: = +) $(LIBOBJS: = +) + +<< +!endif + +!if "$(OLEBUILD)" == "NT" + +$(LIBNAME).dll: $(LIBNAME).d32 $(PRECOMPOBJS) $(LIBOBJS) $(DLLOBJS) $(O)ole2ui.res + @echo Linking ... + lib32 -out:$*.lib -def:$(LIBNAME).d32 -machine:$(MACHINE) $(LIBOBJS) $(DLLOBJS) + cvtres -$(MACHINE) $(O)ole2ui.res -o $*.rs + link32 $(LFLAGS) -entry:LibMain@12 @<<$(BUILD_DIR)\ole2util.lnk + $(LIBNAME).exp $(LIBOBJS) $(DLLOBJS) $(PRECOMPOBJ) $(UILIBS) $*.rs -out:$@ -map:$*.map -dll $(UILIBS) +<<KEEP + +!else +$(O)$(LIBNAME).exe: $(O)$(LIBNAME).lib $(DLLOBJS) $(O)ole2ui.res + @echo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄį Linking UILibrary ®ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + @echo Creating <<$(O)$(@B).lnk +$(LFLAGS) + +$(PRECOMPOBJ: = +^ +)+ +$(DLLOBJS: = +^ +)+ + +$(O)$(@B) +$(@B).map +$(UILIBS) $(O)$(LIBNAME).lib +$(LIBNAME).def +<<KEEP + + $(LK) @$(O)$(@B).lnk + $(RS) -31 $(RFLAGS) $(O)ole2ui.res $(O)$(LIBNAME).exe + +!ifndef SRCTOK +$(LIBNAME).dll: $(O)$(LIBNAME).exe ole2ui.def + copy $(O)$(LIBNAME).exe $(LIBNAME).dll + mapsym -n -l $(LIBNAME).map + implib $(LIBNAME).lib $(LIBNAME).dll +!else +$(LIBNAME).dll: $(O)ole2ui.res + copy $(RESOURCE)\USA\$(LIBNAME).dll $(LIBNAME).dll + $(RS) -31 -K $(RFLAGS) $(O)ole2ui.res $(LIBNAME).dll +!endif +!endif +#endif SRCTOK + + +install: MAKEINI + nmake -f $(MAKEFILE) SETFLAGS InstallAll + +# install built library to $(INSTALL_DIR) dir +InstallAll: + copy $(LIBNAME).dll $(INSTALL_DIR) + copy $(LIBNAME).lib $(INSTALL_DIR) + copy $(LIBNAME).sym $(INSTALL_DIR) + copy ole2ui.h $(INSTALL_DIR) + copy msgfiltr.h $(INSTALL_DIR) + copy enumfetc.h $(INSTALL_DIR) + copy regdb.h $(INSTALL_DIR) + copy olestd.h $(INSTALL_DIR) + copy geticon.h $(INSTALL_DIR) + copy ole2ui.rc $(INSTALL_DIR) + copy uiclass.h $(INSTALL_DIR) + +# EOF ======================================================================== diff --git a/private/oleutest/letest/ole2ui/makefile.old b/private/oleutest/letest/ole2ui/makefile.old new file mode 100644 index 000000000..3fadaf177 --- /dev/null +++ b/private/oleutest/letest/ole2ui/makefile.old @@ -0,0 +1,607 @@ +# ============================================================================ +# File: M A K E F I L E +# +# NMAKE description file for the OLE2.0 User Interface DLL +# +# Copyright (C) Microsoft Corporation, 1992-1993. All Rights Reserved. +# ============================================================================ +# +# Usage Notes: +# ----------- +# +# This makefile is designed to be used in two steps. The first time you +# call the makefile, it generates a file called UIMAKE.INI. The second time +# you call the makefile, it reads settings from UIMAKE.INI and actually +# performs the build. See the section below "UIMAKE.INI" for more information +# on this file. +# +# 1. Initial Step -- Before building your library for the first time, you +# need to run one of the following commands. (This step will only be needed +# to run again if you want to build a different variant of the library, for +# instance if you want to switch from a DEBUG to a RETAIL build). +# +# NMAKE DEBUG - Prepares for building DEBUG DLL version +# NMAKE RETAIL - Prepares for building RETAIL DLL version +# NMAKE DEBUGLIB - Prepares for building DEBUG static LIB version +# NMAKE RETAILIB - Prepares for building RETAIL static LIB version +# +# This step builds the UIMAKE.INI file, which contains the settings +# which specify what version of the library you want to build. +# +# 2. Build Step +# +# NMAKE +# +# This second step reads the settings in the UIMAKE.INI file and builds +# the requested library. +# +# +# UIMAKE.INI +# ---------- +# +# This file is used to specify which variant of the library to build, +# as well as details like which compiler and linker options to use. The +# file is created based on the settings in the "MAKE PARAMETERS" section +# of this makefile. +# +# For most builds, using the default settings will work fine, but if you +# need to change how you build the library, the UIMAKE.INI file is a +# simple way to make this change without changing the makefile. +# +# The following lists a few of the settings in the UIMAKE.INI file which +# you might change, and what effect those changes might have. For a +# complete listing of all the available options and how they are used, +# see the makefile below. +# +# MODEL=[S|M|C|L] -- The memory model. Only available +# on static .LIB version. This flag is +# also included (but not used) in the DLL +# version of UIMAKE.INI in order to allow +# switching between the DLL and LIB version. +# LIBNAME= -- The library name. For building your own +# library (other than the ones for the samples), +# this must be set to a unique name for your +# application. +# LANG= -- Used for international versions of this +# library. Specifies which directory the +# resources come from. Default is USA +# +# ============================================================================ + + +# ---------------------------------------------------------------------------- +# U I M A K E . I N I +# ---------------------------------------------------------------------------- +# XXXXXXX DOS=1 +!ifndef LANG +LANG=USA +!endif + +!if [if not exist uimake.ini dir uimake.ini >nul] != 0 +#!if [test -f uimake.ini] != 0 +LIBNAME= +MODEL=M +RESOURCE=RESOURCE +!ifndef REL_DIR +@echo REL_DIR not defined +REL_DIR=c:\ole2samp\release +!endif +!ifndef OLERELDIR +@echo OLEREL_DIR not defined +OLEREL_DIR=c:\ole2samp\release +!endif +GOAL: DEBUG +!else +!include "uimake.ini" +GOAL: PRELUDE $(LIBNAME).$(BUILD) +!endif + +!if "$(INSTALL_DIR)"=="" +INSTALL_DIR = $(REL_DIR) +!endif + +#use src/tok pairs to build if localized version +!if ("$(LANG)"!="USA") && ("$(LANG)"!="usa") +SRCTOK=1 +!endif +# ---------------------------------------------------------------------------- +# O B J E C T F I L E L I S T +# ---------------------------------------------------------------------------- + +UI_COBJS = \ + D^\ole2ui.obj\ + D^\busy.obj\ + D^\common.obj\ + D^\convert.obj\ + D^\dbgutil.obj\ + D^\drawicon.obj\ + D^\hatch.obj\ + D^\icon.obj\ + D^\iconbox.obj\ + D^\insobj.obj\ + D^\links.obj\ + D^\msgfiltr.obj\ + D^\enumfetc.obj\ + D^\enumstat.obj\ + D^\objfdbk.obj\ + D^\olestd.obj\ + D^\targtdev.obj\ + D^\oleutl.obj\ + D^\pastespl.obj\ + D^\regdb.obj\ + D^\resimage.obj\ + D^\utility.obj\ + +UI_NOPCOBJS = \ + D^\geticon.obj\ + D^\dballoc.obj\ + D^\suminfo.obj\ + D^\stdpal.obj\ + +UI_DLLOBJS = \ + D^\dllfuncs.obj\ + +PRECOMPOBJ= $(O)precomp.obj + +PRECOMP=$(O)precomp.pch + +# ---------------------------------------------------------------------------- +# R E S O U R C E L I S T +# ---------------------------------------------------------------------------- +RES = \ + busy.h \ + common.h \ + convert.h \ + edlinks.h \ + geticon.h \ + icon.h \ + iconbox.h \ + insobj.h \ + msgfiltr.h \ + enumfetc.h \ + ole2ui.h \ + pastespl.h \ + resimage.h \ + dballoc.h \ + suminfo.h \ + stdpal.h \ + $(RESOURCE)\STATIC\default.ico \ + $(RESOURCE)\STATIC\bang.ico \ + $(RESOURCE)\STATIC\egares.bmp \ + $(RESOURCE)\STATIC\hivgares.bmp \ + $(RESOURCE)\STATIC\vgares.bmp \ + $(RESOURCE)\$(LANG)\strings.rc \ + $(RESOURCE)\$(LANG)\busy.dlg \ + $(RESOURCE)\$(LANG)\convert.dlg \ + $(RESOURCE)\$(LANG)\fileopen.dlg \ + $(RESOURCE)\$(LANG)\icon.dlg \ + $(RESOURCE)\$(LANG)\insobj.dlg \ + $(RESOURCE)\$(LANG)\links.dlg \ + $(RESOURCE)\$(LANG)\pastespl.dlg \ + $(RESOURCE)\$(LANG)\prompt.dlg \ + $(RESOURCE)\ole2ui.rcv \ + $(RESOURCE)\$(LANG)\verlocal.h \ + +# ---------------------------------------------------------------------------- +# D E B U G S T A T I C L I B M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +DEBUGLIB: DbgUI + +DbgUI: + @echo Creating DEBUG LIB <<uimake.ini +# This is the DEBUG static .LIB UILibrary INI file +MSG=DEBUG Static LIB Version ($$(LANG)) +DEBUG=1 +MODEL=M +# Make a static library called OLE2UI.LIB +LIBNAME=OLE2UI +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=DEBUGLIB +BUILD=LIB +RESOURCE=RESOURCE + +# 16 bit CFLAGS=-c -Od -GA2s -W3 -Zpei -A$(MODEL) -D_DEBUG -DWIN32 -DUNICODE + +CFLAGS=-c -Od -Gs -W3 -Zpei -D_DEBUG -DWIN32 -DUNICODE +RFLAGS=-D DEBUG +LFLAGS=/MAP:FULL /CO /LINE /NOD /NOE /SE:300 /NOPACKCODE +UILIBS=mlibcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +LANG=$(LANG) +LIBOBJS = $$(UI_COBJS:D^\=DEBUGLIB^\) $$(UI_NOPCOBJS:D^\=DEBUGLIB\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define SZCLASSICONBOX TEXT("$(LIBNAME)IBClass") +#define SZCLASSRESULTIMAGE TEXT("$(LIBNAME)RIClass") +<<KEEP + @echo Enter "$(MAKE)" to make Debug static LIB UILibrary + + +# ---------------------------------------------------------------------------- +# R E T A I L S T A T I C L I B M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +RETAILIB: + @echo Creating RETAIL LIB <<uimake.ini +# This is the RETAIL static .LIB UILibrary INI file +MSG=RETAIL Static LIB Version ($$(LANG)) +RETAIL=1 +MODEL=M +# Make a static library called OLE2UI.LIB +LIBNAME=OLE2UI +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=RETAILIB +BUILD=LIB +RESOURCE=RESOURCE + +# 16 bit CFLAGS=-c -Os -GA2s -W3 -Zpe -A$(MODEL) -DWIN32 -DUNICODE + +CFLAGS=-c -Os -Gs -W3 -Zpe -DWIN32 -DUNICODE +RFLAGS= +LFLAGS=/MAP:FULL /LINE /NOD /NOE /SE:300 /NOPACKCODE +UILIBS=mlibcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +LANG=$(LANG) +LIBOBJS = $$(UI_COBJS:D^\=RETAILIB^\) $$(UI_NOPCOBJS:D^\=RETAILIB\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define SZCLASSICONBOX TEXT("$(LIBNAME)IBClass") +#define SZCLASSRESULTIMAGE TEXT("$(LIBNAME)RIClass") +<<KEEP + @echo Enter "$(MAKE)" to make Retail static LIB UILibrary + +# ---------------------------------------------------------------------------- +# D E B U G D L L M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +DEBUG: Dbg + +Dbg: + @echo Creating DEBUG <<uimake.ini +# This is the DEBUG UILibrary INI file +MSG=DEBUG DLL Version ($$(LANG)) +DEBUG=1 +MODEL=M +LIBNAME=$(LIBNAME) +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=DEBUG +BUILD=DLL +RESOURCE=RESOURCE +#CFLAGS=-c -Od -GD2s -W3 -Zpei -AMw -D_DEBUG -DDLL_VER -D_WINDLL + +# 16 bit CFLAGS=-c -Od -GA2s -GEd -W3 -Zpei -AMw -D_DEBUG -DDLL_VER -D_WINDLL -DWIN32 -DUNICODE + +CFLAGS=-c -Od -Gs -Gd -W3 -Zpei -AMw -D_DEBUG -DDLL_VER -D_WINDLL -DWIN32 -DUNICODE -DNOASSERT +RFLAGS=-D DEBUG -D DLL_VER + +# 16 bit LFLAGS=/MAP:FULL /CO /LINE /NOD /NOE /SE:300 /NOPACKCODE +LFLAGS=/MAP:$(LIBNAME).map /NOD /DLL /IMPLIB:$(LIBNAME).lib + +# 16 bit UILIBS=mdllcew libw ole2 storage shell commdlg toolhelp +UILIBS= $(IMPORT)\nt475\lib\objind\advapi32.lib \ + $(IMPORT)\nt475\lib\objind\comdlg32.lib \ + $(IMPORT)\nt475\lib\objind\crtdll.lib \ + $(IMPORT)\nt475\lib\objind\gdi32.lib \ + $(IMPORT)\nt475\lib\objind\kernel32.lib \ + $(IMPORT)\nt475\lib\objind\libcnt.lib \ + $(IMPORT)\nt475\lib\objind\shell32.lib \ + $(IMPORT)\nt475\lib\objind\user32.lib \ + $(COMMON)\ilib\OBJind\ole232.lib \ + $(COMMON)\types\OBJind\uuid.lib \ + $(COMMON)\ilib\OBJind\storag32.lib \ + $(COMMON)\ilib\OBJind\compob32.lib +CC=cl +RS=rc +LK=link +LANG=$(LANG) +DLLOBJS = $$(UI_DLLOBJS:D^\=DEBUG^\) +LIBOBJS = $$(UI_COBJS:D^\=DEBUG^\) $$(UI_NOPCOBJS:D^\=DEBUG\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define SZCLASSICONBOX "$(LIBNAME)IBClass" +#define SZCLASSRESULTIMAGE "$(LIBNAME)RIClass" +<<KEEP + @echo Enter "$(MAKE)" to make Debug UILibrary + +# ---------------------------------------------------------------------------- +# R E T A I L M A K E P A R A M E T E R S +# ---------------------------------------------------------------------------- +RETAIL: + @echo Creating RETAIL <<uimake.ini +# This is the RETAIL UILibrary INI file +MSG=RETAIL DLL Version ($$(LANG)) +RETAIL=1 +MODEL=M +LIBNAME=$(LIBNAME) +REL_DIR=$(REL_DIR) +OLEREL_DIR=$(OLEREL_DIR) +OBJ=RETAIL +BUILD=DLL +RESOURCE=RESOURCE +#CFLAGS=-c -Os -GD2s -W3 -Zpe -AMw -DOPTIMIZE -DDLL_VER -D_WINDLL + +# 16 bit CFLAGS=-c -Os -GA2s -GEd -W3 -Zpe -AMw -DOPTIMIZE -DDLL_VER -D_WINDLL -DWIN32 -DUNICODE + +CFLAGS=-c -Os -Gs -Gd -W3 -Zpe -DOPTIMIZE -DDLL_VER -D_WINDLL -DWIN32 -DUNICODE +RFLAGS=-D DLL_VER +LFLAGS=/MAP /NOD /NOE /SE:300 /AL:16 /NOPACKCODE +UILIBS=mdllcew libw ole2 storage shell commdlg toolhelp +CC=cl +RS=rc +LK=link +LANG=$(LANG) +DLLOBJS = $$(UI_DLLOBJS:D^\=RETAIL^\) +LIBOBJS = $$(UI_COBJS:D^\=RETAIL^\) $$(UI_NOPCOBJS:D^\=RETAIL\NOPC^\) +<<KEEP + @echo Creating <<uiclass.h +#define SZCLASSICONBOX TEXT("$(LIBNAME)IBClass") +#define SZCLASSRESULTIMAGE TEXT("$(LIBNAME)RIClass") +<<KEEP + @echo Enter "$(MAKE)" to make Retail UILibrary + +!if [if not exist $(OBJ)\*. md $(OBJ) >nul] +!error Object subdirectory $(OBJ)\ could not be created +!endif +!if [if not exist $(OBJ)\NOPC\*. md $(OBJ)\NOPC > nul] +!error non-precompiled header object subdirectory $(OBJ)\NOPC\ could not be created +!endif + +#select language for version resource if localized version +!if ("$(LANG)"!="USA") && ("$(LANG)"!="usa") +RFLAGS=$(RFLAGS) -D VER_LOC +!endif + +.SUFFIXES: .c .asm .obj .res .rc .def .bmp .ico .exe .dll .cod .str + +O=.\$(OBJ)^\ + +# ---------------------------------------------------------------------------- +# I N F E R E N C E R U L E S +# ---------------------------------------------------------------------------- +!ifndef SRCTOK + +# compile C file without precompiled headers into object directory\NOPC +# dont compile c files etc for lcoalized builds. +{}.c{$(O)NOPC\}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) + $(CC) -Fo$(O)NOPC\$(@B) $(@B).c +!else +!undef _FILE_ + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).c\" -Fo$(O)NOPC\$(@B) $(@B).c +!endif + +# compile C file into object directory +{}.c{$(O)}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch + $(CC) -Fo$(O)$(@B) $(@B).c +!else +!undef _FILE_ +# $(CC) $(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch -D_FILE_=\"$(*B).c\" -Fo$(O)$(@B) $(@B).c + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).c\" -Fo$(O)$(@B) $(@B).c +!endif + +# compile CPP file without precompiled headers into object directory\NOPC +# dont compile cpp files etc for lcoalized builds. +{}.cpp{$(O)NOPC\}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).cpp °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) + $(CC) -Fo$(O)NOPC\$(@B) $(@B).cpp +!else +!undef _FILE_ + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).cpp\" -Fo$(O)NOPC\$(@B) $(@B).cpp +!endif + +# compile CPP file into object directory +{}.cpp{$(O)}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).cpp °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch + $(CC) -Fo$(O)$(@B) $(@B).cpp +!else +!undef _FILE_ +# $(CC) $(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch -D_FILE_=\"$(*B).cpp\" -Fo$(O)$(@B) $(@B).cpp + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).cpp\" -Fo$(O)$(@B) $(@B).cpp +!endif + +!endif +#endif SRCTOK + +{}.rc{$(O)}.res: + @echo ²²²²²²²²²²²²²²²²²²² Resource Compiling $(@B).res ²²²²²²²²²²²²²²²²²²²² + $(RS) -I $(RESOURCE)\$(LANG);$(RESOURCE)\static;$(RESOURCE) -FO $(O)$(@B).res -DWIN32 -DUNICODE -R $(RFLAGS) $(@B).rc + -del $(LIBNAME).dll + +!ifndef SRCTOK +{}.c.cod: + @echo ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Making $(@B).cod ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ +!ifdef DOS + SET CL=$(CFLAGS) -f -Fc + $(CC) $(@B).c +!else +!undef _FILE_ + $(CC) $(CFLAGS) -f- -Fc -D_FILE_=\"$(*B).c\" $(@B).c +!endif +!endif + + +# rules for creating rc & dlg files for localized verisons from src/tok pairs +!ifdef SRCTOK + +$(RESOURCE)\$(LANG)\busy.dlg : $(RESOURCE)\$(LANG)\busy.tok $(RESOURCE)\src\busy.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\convert.dlg : $(RESOURCE)\$(LANG)\convert.tok $(RESOURCE)\src\convert.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\fileopen.dlg : $(RESOURCE)\$(LANG)\fileopen.tok $(RESOURCE)\src\fileopen.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\icon.dlg : $(RESOURCE)\$(LANG)\icon.tok $(RESOURCE)\src\icon.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\insobj.dlg : $(RESOURCE)\$(LANG)\insobj.tok $(RESOURCE)\src\insobj.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\links.dlg : $(RESOURCE)\$(LANG)\links.tok $(RESOURCE)\src\links.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\pastespl.dlg : $(RESOURCE)\$(LANG)\pastespl.tok $(RESOURCE)\src\pastespl.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\prompt.dlg : $(RESOURCE)\$(LANG)\prompt.tok $(RESOURCE)\src\prompt.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ + +$(RESOURCE)\$(LANG)\strings.rc : $(RESOURCE)\$(LANG)\strings.tok $(RESOURCE)\src\strings.src + tok -q -f $*.tok $(RESOURCE)\src\$(@B).src > $@ +!endif + +# ---------------------------------------------------------------------------- +# D E P E N D F I L E C R E A T I O N +# ---------------------------------------------------------------------------- +UI_CFILE = $(UI_COBJS:.obj=.c) $(UI_DLLOBJS:.obj=.c) +UI_NOPCFILE = $(UI_NOPCOBJS:.obj=.c) +DEPEND: nul + @echo Making a NEW dependancy file. + mkdep -p $$(O) -s .obj $(UI_CFILE:D^\=) > tmp.tmp + sed "s/:/: $$(PRECOMP)/g" < tmp.tmp > depend + -del tmp.tmp + mkdep -p $$(O)NOPC\ -s .obj $(UI_NOPCFILE:D^\=) >> depend + mkdep -p $$(O) -s .pch precomp.c >> depend + +# ---------------------------------------------------------------------------- +# W E L C O M E B A N N E R +# ---------------------------------------------------------------------------- +PRELUDE: + @echo ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» + @echo º Makefile for UILibrary º + @echo ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ + @echo $(MSG) +!ifndef SRCTOK + set INCLUDE=$(OLEREL_DIR);$(INCLUDE) + set LIB=$(OLEREL_DIR);$(LIB) +!endif + + +# ---------------------------------------------------------------------------- +# G O A L T A R G E T S +# ---------------------------------------------------------------------------- +!include "depend" + +CLEAN: CleanUp GOAL +CleanUp: + -echo y|del .\$(OBJ)\*.* + -del $(LIBNAME).dll + -del $(LIBNAME).lib + +!ifndef SRCTOK + +$(O)precomp.pch: precomp.c +!ifdef DOS + SET CL=$(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h + $(CC) -Fo$(O)$(@B) precomp.c +!else +!undef _FILE_ + @echo Precompiling Header Files.... + $(CC) $(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h -D_FILE_=\"precomp.c\" -Fo$(O)$(@B) precomp.c +!endif +!endif + +$(O)ole2ui.res: ole2ui.rc $(RES) + +ole2ui.rc : $(RESOURCE)\$(LANG)\strings.rc + +# +# Build .LIB static library +# + +$(LIBNAME).lib: $(LIBOBJS) $(PRECOMPOBJ) + -del $(O)$(LIBNAME).lib + lib @<< +$(O)$(LIBNAME).lib +y +$(PRECOMPOBJ: = +) $(LIBOBJS: = +) + +<< + copy $(O)$(LIBNAME).lib $(LIBNAME).lib + +# +# Build .DLL dynamic-link library +# + +# HACK! +# XXXXX +# after echo LIBRARY $(LIBNAME) INITINSTANCE +$(O)$(LIBNAME).exe: $(LIBOBJS) $(PRECOMPOBJ) $(DLLOBJS) $(O)ole2ui.res defoleui.def + @echo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄį Linking UILibrary ®ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + -del $(LIBNAME).def + @echo Creating <<$(LIBNAME).def +LIBRARY ole2ui +DESCRIPTION 'OLE 2.0 UI Support Library.' +<<KEEP + type defoleui.def >> $(LIBNAME).def + $(LK) @<< +$(LFLAGS) +$(LIBOBJS: = ^ +) +$(DLLOBJS: = ^ +) +$(O)$(LIBNAME).res +$(UILIBS) +/DEF:$(LIBNAME).def +<<KEEP +# $(RS) $(O)ole2ui.res $(O)$(LIBNAME).dll + + +#$(LIBOBJS: = +^ +#) + +#$(DLLOBJS: = +^ +#)+ +#$(PRECOMPOBJ: = +^ +#) +#$(LFLAGS) +#$(O)$(@B) +#$(@B).map +#$(UILIBS) +#$(LIBNAME).def +#<<KEEP +# $(RS) -31 -K $(RFLAGS) $(O)ole2ui.res $(O)$(LIBNAME).exe + +!ifndef SRCTOK +$(LIBNAME).dll: $(O)$(LIBNAME).exe ole2ui.def +# copy $(O)$(LIBNAME).exe $(LIBNAME).dll + mapsym -n -l $(LIBNAME).map +# implib -NOWEP $(LIBNAME).lib $(LIBNAME).dll +!else +$(LIBNAME).dll: $(O)ole2ui.res + copy $(RESOURCE)\USA\$(LIBNAME).dll $(LIBNAME).dll +# 16 bit $(RS) -31 -K $(RFLAGS) $(O)ole2ui.res $(LIBNAME).dll + $(RS) $(O)ole2ui.res $(LIBNAME).dll +!endif + + +# install built library to $(INSTALL_DIR) dir +install: + @echo Gets HERE!!!!!! + copy $(LIBNAME).dll $(RESOURCE)\USA + copy $(LIBNAME).dll $(INSTALL_DIR) + copy $(LIBNAME).lib $(INSTALL_DIR) + copy $(LIBNAME).sym $(INSTALL_DIR) + copy ole2ui.h $(INSTALL_DIR) + copy olestd.h $(INSTALL_DIR) + copy msgfiltr.h $(INSTALL_DIR) + copy enumfetc.h $(INSTALL_DIR) + copy uiclass.h $(INSTALL_DIR) + +# EOF ======================================================================== diff --git a/private/oleutest/letest/ole2ui/makelib b/private/oleutest/letest/ole2ui/makelib new file mode 100644 index 000000000..f7729d5d3 --- /dev/null +++ b/private/oleutest/letest/ole2ui/makelib @@ -0,0 +1,503 @@ +# ============================================================================ +# File: MAKELIB +# +# NMAKE description file to build STATIC version of OLE2.0 User Interface LIB +# +# Copyright (C) Microsoft Corporation, 1992-1993. All Rights Reserved. +# ============================================================================ +# +# Usage Notes: +# ----------- +# +# This makefile is designed to be used in one step. This makefile does +# NOT use the file called UIMAKE.INI. This makefile builds the following +# libraries (depending on the value of "LIBFORDLL" and "DEBUG"): +# OLE2UIX.LIB -- static RETAIL library to be used with EXE's +# OLE2UIXD.LIB -- static DEBUG library to be used with EXE's +# +# OLE2UID.LIB -- static RETAIL library to be used with DLL's +# OLE2UIDD.LIB -- static DEBUG library to be used with DLL's +# +# It is NOT necessary to build custom versions of the static +# library version of OLE2UI. Everyone can use the same static OLE2UI +# libraries as built by this makefile. +# +# NMAKE -F MAKELIB +# NMAKE -F MAKELIB DEBUG=0 +# NMAKE -F MAKELIB LIBFORDLL=1 +# NMAKE -F MAKELIB LIBFORDLL=1 DEBUG=0 +# +# +# The following lists a few of the settings in this makefile file which +# you might change, and what effect those changes might have. For a +# complete listing of all the available options and how they are used, +# see the makefile below. +# +# MODEL=[M|L] -- The memory model. (Default: M) +# DEBUG=[0|1] -- Enable DEBUG or RETAIL version (Default: 1) +# LIBFORDLL=[0|1] -- Enable DEBUG or RETAIL version (Default: 0) +# SAMPLIB_DIR -- Directory to install built .LIB file +# (Default: \ole2\samp\bin) +# SAMPINC_DIR -- Directory to install public header files +# (Default: \ole2\samp\include) +# OLELIB_DIR -- Directory for OLE2 libraries +# (Default: \ole2\bin) +# OLEINC_DIR -- Directory for OLE2 public header files +# (Default: \ole2\include) +# +# Comments: +# -------- +# +# In order to use the static library form of the OLE2UI library then you must +# include "ole2ui.rc" resource file in your applications resource file. Also +# "OleUIInitialize" must be called before calling any library functions. +# This is called typically before entering the main message loop in an EXE +# and called from LibMain for an in-proc server (DLL). Two unique strings +# should be passed as paramters to OleUIInitialize. These strings are used +# as class names for two custom controls used in the OLE2UI dialogs. +# Before shutting down "OleUIUninitialize" must be called in order to clean up +# resources used by the OLE2UI library. In an EXE, this is typically called +# after leaving the main message loop; in an DLL, this is typically called +# from the DLL's WEP function. +# If the OLE2UI library is used in DLL form then explicitly including the +# "ole2ui.rc" resource file and calling OleUIInitialize/OleUIUninitialize +# is NOT necessary. +# ============================================================================ + +DEBUG=1 +MODEL=M +LIBFORDLL=0 +NOASSERT=1 +OLE201=1 +DOS=1 + +!if "$(OPSYS)"=="DOS" +OBJDIR=objidd +!else +OBJDIR=obji1d +!endif + +!ifndef SAMPINC_DIR +SAMPINC_DIR=..\include +!endif + +!ifndef SAMPLIB_DIR +SAMPLIB_DIR=..\lib +!endif + +!ifndef OLEINC_DIR +!if "$(OPSYS)"=="DOS" +OLEINC_DIR=..\..\include;$(CAIROLE)\h\export;$(IMPORT)\CHICAGO\h;\ + $(IMPORT)\CHICAGO\h\crt;$(COMMON)\ih;$(COMMON)\types +!else +OLEINC_DIR=..\..\include;$(CAIROLE)\h\export;$(IMPORT)\$(OPSYS)\h\sdk;\ + $(IMPORT)\$(OPSYS)\h\sdk\crt;$(COMMON)\ih;$(COMMON)\types +!endif +!endif + +!ifndef OLELIB_DIR +!if "$(OPSYS)"=="DOS" +OLELIB_DIR=..\..\lib;$(CAIROLE)\ilib\$(OBJDIR);$(IMPORT)\chicago\lib +!else +OLELIB_DIR=..\..\lib;$(CAIROLE)\ilib\$(OBJDIR) +!endif +!endif + +!if ("$(OLE201)"=="1") +MISCFLAGS=/DOLE201 +!endif + +!if ("$(NOASSERT)"=="1") +MISCFLAGS=$(MISCFLAGS) /DNOASSERT +!endif + +!if ("$(DEBUG)"=="1") +MSG=DEBUG Static LIB Version +#CFLAGS=-c -Od -GA2s -W3 -Zpei -A$(MODEL) -D_DEBUG + +!ifdef WIN16 +LFLAGS=/MAP:FULL /CO /LINE /NOD /NOE /SE:300 /NOPACKCODE +!else +LFLAGS=/MAP:$(O)$(LIBNAME).map /DEBUGTYPE:CV /NOD /NOPACK +!endif + +CC=$(IMPORT)\n386\bin\cl +AS=$(IMPORT)\n386\bin\masm +RS=$(IMPORT)\n386\bin\rc +LINK=$(COMMON)\bin\link $(LFLAGS) +LIB=lib + +!if ("$(LIBFORDLL)"=="1") +# +# Build DEBUG OLE2UI library for use with DLL's (eg. in-proc server objects) +# +MSG=DEBUG Static LIB Version (for use with DLL's) +LIBNAME=OLE2UIDD +OBJ=OLE2UIDD + +CFLAGS=-c -Od -W3 -Zpei -D_DEBUG -DDLL_VER -D_WINDLL -DLIBNAME=\"$$(LIBNAME)\" +!ifdef WIN16 +CFLAGS=$(CFLAGS) -GD -GEd -AMw +UILIBS=ldllcew libw ole2 storage shell +!else +CFLAGS=$(CFLAGS) -Gd -DWIN32 -DUNICODE -D_UNICODE -D_INC_OLE -D_X86_ $(MISCFLAGS) +UILIBS=libw32.lib storag32.lib shell32.lib +!if "$(OLE201)"=="1" +UILIBS=$(UILIBS) ole2w32.lib +!else +UILIBS=$(UILIBS) ole232.lib +!endif + +!endif + +LIBOBJS = $(UI_COBJS:D^\=OLE2UIDD^\) $(UI_NOPCOBJS:D^\=OLE2UIDD\NOPC^\) +!else +# +# Build DEBUG OLE2UI library for use with EXE's +# +MSG=DEBUG Static LIB Version (for use with EXE's) +LIBNAME=OLE2UIXD +OBJ=OLE2UIXD + +CFLAGS=-c -Od -W3 -Zpei #-D_DEBUG +!ifdef WIN16 +CFLAGS=$(CFLAGS) -GA2s -A$(MODEL) +UILIBS=mlibcew libw ole2 storage shell +!else +CFLAGS=$(CFLAGS) -Gs -DWIN32 -DUNICODE -D_UNICODE -D_INC_OLE -D_X86_ $(MISCFLAGS) + +!if "$(OPSYS)"=="DOS" +UILIBS= $(IMPORT)\CHICAGO\lib\advapi32.lib \ + $(IMPORT)\CHICAGO\lib\comdlg32.lib \ + $(IMPORT)\CHICAGO\lib\crtdll.lib \ + $(IMPORT)\CHICAGO\lib\gdi32.lib \ + $(IMPORT)\CHICAGO\lib\kernel32.lib \ + $(IMPORT)\CHICAGO\lib\libcmt.lib \ + $(IMPORT)\CHICAGO\lib\shell32.lib \ + $(IMPORT)\CHICAGO\lib\user32.lib \ + $(IMPORT)\CHICAGO\lib\wsock32.lib +!else +UILIBS= $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\advapi32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\comdlg32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\crtdll.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\gdi32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\kernel32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\libcmt.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\shell32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\user32.lib +!endif +UILIBS= $(UILIBS) \ + $(CAIROLE)\ilib\$(OBJDIR)\ole2w32.lib \ + $(CAIROLE)\ilib\$(OBJDIR)\storag32.lib \ + $(CAIROLE)\ilib\$(OBJDIR)\compob32.lib + +!endif + +LIBOBJS = $(UI_COBJS:D^\=OLE2UIXD^\) $(UI_NOPCOBJS:D^\=OLE2UIXD\NOPC^\) +!endif + +!else + +#CFLAGS=-c -Os -GA2s -W3 -Zpe -A$(MODEL) + +!ifdef WIN16 +LFLAGS=/MAP:FULL /LINE /NOD /NOE /SE:300 /NOPACKCODE +!else +LFLAGS=/MAP:$(O)$(LIBNAME).map /NOD /NOPACK +!endif + +CC=$(IMPORT)\n386\bin\cl +AS=$(IMPORT)\n386\bin\masm +RS=$(IMPORT)\n386\bin\rc +LINK=$(COMMON)\bin\link $(LFLAGS) +LIB=lib + +!if ("$(LIBFORDLL)"=="1") +# +# Build RETAIL OLE2UI library for use with DLL's (eg. in-proc server objects) +# +MSG=RETAIL Static LIB Version (for use with DLL's) +LIBNAME=OLE2UID +OBJ=OLE2UID + +CFLAGS=-c -Os -D_WINDLL -W3 -Zpe +!ifdef WIN16 +CFLAGS=$(CFLAGS) -GD -GEd -A$(MODEL) +UILIBS=ldllcew libw ole2 storage shell +!else +CFLAGS=$(CFLAGS) -Gd -DWIN32 -DUNICODE -D_UNICODE -D_INC_OLE -D_X86_ $(MISCFLAGS) + +!if "$(OPSYS)"=="DOS" +UILIBS= $(IMPORT)\CHICAGO\lib\advapi32.lib \ + $(IMPORT)\CHICAGO\lib\comdlg32.lib \ + $(IMPORT)\CHICAGO\lib\crtdll.lib \ + $(IMPORT)\CHICAGO\lib\gdi32.lib \ + $(IMPORT)\CHICAGO\lib\kernel32.lib \ + $(IMPORT)\CHICAGO\lib\libcmt.lib \ + $(IMPORT)\CHICAGO\lib\shell32.lib \ + $(IMPORT)\CHICAGO\lib\user32.lib +!else +UILIBS= $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\advapi32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\comdlg32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\crtdll.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\gdi32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\kernel32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\libcmt.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\shell32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\user32.lib +!endif +UILIBS= $(UILIBS) \ + $(CAIROLE)\ilib\$(OBJDIR)\ole2w32.lib \ + $(CAIROLE)\ilib\$(OBJDIR)\storag32.lib \ + $(CAIROLE)\ilib\$(OBJDIR)\compob32.lib + +!endif + +LIBOBJS = $(UI_COBJS:D^\=OLE2UID^\) $(UI_NOPCOBJS:D^\=OLE2UID\NOPC^\) +!else +# +# Build RETAIL OLE2UI library for use with EXE's +# +MSG=RETAIL Static LIB Version (for use with EXE's) +LIBNAME=OLE2UIX +OBJ=OLE2UIX + +CFLAGS=-c -Os -W3 -Zpe +!ifdef WIN16 +CFLAGS=$(CFLAGS) -GA2s -GEs -A$(MODEL) +UILIBS=mlibcew libw ole2 storage shell +!else +CFLAGS=$(CFLAGS) -Gs -DWIN32 -DUNICODE -D_UNICODE -D_INC_OLE -D_X86_ $(MISCFLAGS) + +!if "$(OPSYS)"=="DOS" +UILIBS= $(IMPORT)\CHICAGO\lib\advapi32.lib \ + $(IMPORT)\CHICAGO\lib\comdlg32.lib \ + $(IMPORT)\CHICAGO\lib\crtdll.lib \ + $(IMPORT)\CHICAGO\lib\gdi32.lib \ + $(IMPORT)\CHICAGO\lib\kernel32.lib \ + $(IMPORT)\CHICAGO\lib\libcmt.lib \ + $(IMPORT)\CHICAGO\lib\shell32.lib \ + $(IMPORT)\CHICAGO\lib\user32.lib +!else +UILIBS= $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\advapi32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\comdlg32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\crtdll.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\gdi32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\kernel32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\libcmt.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\shell32.lib \ + $(IMPORT)\$(OPSYS)\lib\$(OBJDIR)\user32.lib +!endif +UILIBS= $(UILIBS) \ + $(CAIROLE)\ilib\$(OBJDIR)\ole2w32.lib \ + $(CAIROLE)\ilib\$(OBJDIR)\storag32.lib \ + $(CAIROLE)\ilib\$(OBJDIR)\compob32.lib + +!endif + +LIBOBJS = $(UI_COBJS:D^\=OLE2UIX^\) $(UI_NOPCOBJS:D^\=OLE2UIX\NOPC^\) +!endif + +!endif + +GOAL: PRELUDE $(LIBNAME).LIB + +# ---------------------------------------------------------------------------- +# O B J E C T F I L E L I S T +# ---------------------------------------------------------------------------- + +UI_COBJS = \ + D^\busy.obj\ + D^\common.obj\ + D^\convert.obj\ + D^\dbgutil.obj\ + D^\drawicon.obj\ + D^\hatch.obj\ + D^\icon.obj\ + D^\iconbox.obj\ + D^\insobj.obj\ + D^\links.obj\ + D^\msgfiltr.obj\ + D^\enumfetc.obj\ + D^\enumstat.obj\ + D^\objfdbk.obj\ + D^\ole2ui.obj\ + D^\olestd.obj\ + D^\targtdev.obj\ + D^\oleutl.obj\ + D^\pastespl.obj\ + D^\regdb.obj\ + D^\resimage.obj\ + D^\utility.obj\ + +UI_NOPCOBJS = \ + D^\geticon.obj\ + D^\dballoc.obj\ + D^\suminfo.obj\ + D^\stdpal.obj\ + +PRECOMPOBJ= $(O)precomp.obj + +PRECOMP=$(O)precomp.pch + +# ---------------------------------------------------------------------------- +# R E S O U R C E L I S T +# ---------------------------------------------------------------------------- +RES = \ + busy.h \ + common.h \ + convert.h \ + edlinks.h \ + geticon.h \ + icon.h \ + iconbox.h \ + insobj.h \ + msgfiltr.h \ + enumfetc.h \ + ole2ui.h \ + pastespl.h \ + resimage.h \ + dballoc.h \ + suminfo.h \ + stdpal.h \ + + +.SUFFIXES: .c .cpp .obj + +O=.\$(OBJ)^\ + +!if [if not exist $(OBJ)\*. md $(OBJ) >nul] +!error Object subdirectory $(OBJ)\ could not be created +!endif +!if [if not exist $(OBJ)\NOPC\*. md $(OBJ)\NOPC > nul] +!error non-precompiled header object subdirectory $(OBJ)\NOPC\ could not be created +!endif + +# ---------------------------------------------------------------------------- +# I N F E R E N C E R U L E S +# ---------------------------------------------------------------------------- + +# compile C file without precompiled headers into object directory\NOPC +# dont compile c files etc for lcoalized builds. +{}.c{$(O)NOPC\}.obj: + @echo Are you compiling with OLE 2.01 ?????? + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) + $(CC) -Fo$(O)NOPC\$(@B) $(@B).c +!else + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).c\" -Fo$(O)NOPC\$(@B) $(@B).c +!endif + +# compile C file into object directory +{}.c{$(O)}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch + $(CC) -Fo$(O)$(@B) $(@B).c +!else + $(CC) $(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch -D_FILE_=\"$(*B).c\" -Fo$(O)$(@B) $(@B).c +!endif + +# compile CPP file without precompiled headers into object directory\NOPC +# dont compile cpp files etc for lcoalized builds. +{}.cpp{$(O)NOPC\}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).cpp °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) + $(CC) -Fo$(O)NOPC\$(@B) $(@B).cpp +!else + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).cpp\" -Fo$(O)NOPC\$(@B) $(@B).cpp +!endif + +# compile CPP file into object directory +{}.cpp{$(O)}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).cpp °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch + $(CC) -Fo$(O)$(@B) $(@B).cpp +!else + $(CC) $(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch -D_FILE_=\"$(*B).cpp\" -Fo$(O)$(@B) $(@B).cpp +!endif + + +# ---------------------------------------------------------------------------- +# D E P E N D F I L E C R E A T I O N +# ---------------------------------------------------------------------------- +UI_CFILE = $(UI_COBJS:.obj=.c) $(UI_DLLOBJS:.obj=.c) +UI_NOPCFILE = $(UI_NOPCOBJS:.obj=.c) +DEPEND: nul + @echo Making a NEW dependancy file. + mkdep -p $$(O) -s .obj $(UI_CFILE:D^\=) > tmp.tmp + sed "s/:/: $$(PRECOMP)/g" < tmp.tmp > depend + -del tmp.tmp + mkdep -p $$(O)NOPC\ -s .obj $(UI_NOPCFILE:D^\=) >> depend + mkdep -p $$(O) -s .pch precomp.c >> depend + +# ---------------------------------------------------------------------------- +# W E L C O M E B A N N E R +# ---------------------------------------------------------------------------- +PRELUDE: + @echo ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» + @echo º Makefile for UILibrary º + @echo ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ + @echo $(MSG) +!ifndef SRCTOK + set INCLUDE=$(OLEINC_DIR);$(INCLUDE) + set LIB=$(OLELIB_DIR);$(LIB) +!endif + + +# ---------------------------------------------------------------------------- +# G O A L T A R G E T S +# ---------------------------------------------------------------------------- +!include "depend" + +CLEAN: CleanUp +CleanUp: + -echo y|del .\$(OBJ)\*.* + -echo y|del .\$(OBJ)\NOPC\*.* + -del $(LIBNAME).lib + +$(O)precomp.pch: precomp.c +!ifdef DOS + SET CL=$(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h + $(CC) -Fo$(O)$(@B) precomp.c +!else + $(CC) $(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h -D_FILE_=\"precomp.c\" -Fo$(O)$(@B) precomp.c +!endif + +# +# Build .LIB static library +# + +$(LIBNAME).lib: $(LIBOBJS) $(PRECOMPOBJ) + -del $(O)$(LIBNAME).lib +!ifdef WIN16 + lib @<< +$(O)$(LIBNAME).lib +y +$(PRECOMPOBJ: = +) $(LIBOBJS: = +) + +<< +!else + $(LINK) @<< +/OUT:$(O)$(LIBNAME).lib +/MACHINE:i386 +$(PRECOMPOBJ: = ) $(LIBOBJS: = ) $(UILIBS) + +<< +!endif + copy $(O)$(LIBNAME).lib $(LIBNAME).lib + + +# install built library and public header files to release directories +install: + copy $(LIBNAME).lib $(SAMPLIB_DIR) + copy ole2ui.h $(SAMPINC_DIR) + copy olestd.h $(SAMPINC_DIR) + copy msgfiltr.h $(SAMPINC_DIR) + copy enumfetc.h $(SAMPINC_DIR) + +# EOF ======================================================================== +
\ No newline at end of file diff --git a/private/oleutest/letest/ole2ui/msgfiltr.c b/private/oleutest/letest/ole2ui/msgfiltr.c new file mode 100644 index 000000000..562dfb802 --- /dev/null +++ b/private/oleutest/letest/ole2ui/msgfiltr.c @@ -0,0 +1,809 @@ +/* + * MSGFILTR.C + * + * This file contains a standard implementation of IMessageFilter + * interface. + * This file is part of the OLE 2.0 User Interface support library. + * + * (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved + * + */ + + +#define STRICT 1 +#include "ole2ui.h" +#include "msgfiltr.h" + +OLEDBGDATA + + +typedef struct tagOLESTDMESSAGEFILTER { + IMessageFilterVtbl FAR* m_lpVtbl; + UINT m_cRef; + HWND m_hWndParent; + DWORD m_dwInComingCallStatus; // Status to return from + // HandleIncomingCall + HANDLEINCOMINGCALLBACKPROC m_lpfnHandleInComingCallback; + // Callback function + // to selectively handle + // interface method calls + BOOL m_fEnableBusyDialog; // enable RetryRejected + // Call dialog + BOOL m_fEnableNotRespondingDialog; // enable + // MessagePending dialog + MSGPENDINGPROC m_lpfnMessagePendingCallback; // MessagePending + // Callback function + LPFNOLEUIHOOK m_lpfnBusyDialogHookCallback; // Busy dialog hook + LPTSTR m_lpszAppName; // Name of application + // installing filter + HWND m_hWndBusyDialog; // HWND of busy dialog. Used + // to tear down dialog. + BOOL m_bUnblocking; + + }OLESTDMESSAGEFILTER, FAR* LPOLESTDMESSAGEFILTER; + +/* interface IMessageFilter implementation */ +STDMETHODIMP OleStdMsgFilter_QueryInterface( + LPMESSAGEFILTER lpThis, REFIID riid, LPVOID FAR* ppvObj); +STDMETHODIMP_(ULONG) OleStdMsgFilter_AddRef(LPMESSAGEFILTER lpThis); +STDMETHODIMP_(ULONG) OleStdMsgFilter_Release(LPMESSAGEFILTER lpThis); +STDMETHODIMP_(DWORD) OleStdMsgFilter_HandleInComingCall ( + LPMESSAGEFILTER lpThis, + DWORD dwCallType, + HTASK htaskCaller, + DWORD dwTickCount, +#ifdef WIN32 + LPINTERFACEINFO dwReserved +#else + DWORD dwReserved +#endif +); +STDMETHODIMP_(DWORD) OleStdMsgFilter_RetryRejectedCall ( + LPMESSAGEFILTER lpThis, + HTASK htaskCallee, + DWORD dwTickCount, + DWORD dwRejectType +); +STDMETHODIMP_(DWORD) OleStdMsgFilter_MessagePending ( + LPMESSAGEFILTER lpThis, + HTASK htaskCallee, + DWORD dwTickCount, + DWORD dwPendingType +); + + +static IMessageFilterVtbl g_OleStdMessageFilterVtbl = { + OleStdMsgFilter_QueryInterface, + OleStdMsgFilter_AddRef, + OleStdMsgFilter_Release, + OleStdMsgFilter_HandleInComingCall, + OleStdMsgFilter_RetryRejectedCall, + OleStdMsgFilter_MessagePending +}; + + +/* GetTopWindowInWindowsTask +** ------------------------- +** Get the top most window that has focus in the given task to be +** used as the parent for the busy dialog. we do this to handle the +** case where a dialog window is currently up when we need to give +** the busy dialog. if we use the current assigned parent window +** (which typically will be the frame window of the app), then the +** busy dialog will not be modal to the current active dialog +** window. +*/ +static HWND GetTopWindowInWindowsTask(HWND hwnd) +{ + HWND hwndActive = GetActiveWindow(); + if (!hwndActive) + return hwnd; + + if (GetWindowTask(hwnd) == GetWindowTask(hwndActive)) + return hwndActive; + else + return hwnd; +} + +STDAPI_(LPMESSAGEFILTER) OleStdMsgFilter_Create( + HWND hWndParent, + LPTSTR szAppName, + MSGPENDINGPROC lpfnCallback, + LPFNOLEUIHOOK lpfnOleUIHook // Busy dialog hook callback +) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter; + LPMALLOC lpMalloc; + + if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) + return NULL; + + lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpMalloc->lpVtbl->Alloc( + lpMalloc, (sizeof(OLESTDMESSAGEFILTER))); + lpMalloc->lpVtbl->Release(lpMalloc); + if (! lpStdMsgFilter) return NULL; + + lpStdMsgFilter->m_lpVtbl = &g_OleStdMessageFilterVtbl; + lpStdMsgFilter->m_cRef = 1; + lpStdMsgFilter->m_hWndParent = hWndParent; + lpStdMsgFilter->m_dwInComingCallStatus = SERVERCALL_ISHANDLED; + lpStdMsgFilter->m_lpfnHandleInComingCallback = NULL; + lpStdMsgFilter->m_fEnableBusyDialog = TRUE; + lpStdMsgFilter->m_fEnableNotRespondingDialog = TRUE; + lpStdMsgFilter->m_lpszAppName = szAppName; + lpStdMsgFilter->m_lpfnMessagePendingCallback = lpfnCallback; + lpStdMsgFilter->m_lpfnBusyDialogHookCallback = lpfnOleUIHook; + lpStdMsgFilter->m_hWndBusyDialog = NULL; + lpStdMsgFilter->m_bUnblocking = FALSE; + + return (LPMESSAGEFILTER)lpStdMsgFilter; +} + + +/* OleStdMsgFilter_SetInComingStatus +** --------------------------------- +** This is a private function that allows the caller to control what +** value is returned from the IMessageFilter::HandleInComing method. +** +** if a HandleInComingCallbackProc is installed by a call to +** OleStdMsgFilter_SetHandleInComingCallbackProc, then this +** overrides the dwIncomingCallStatus established by a call to +** OleStdMsgFilter_SetInComingStatus. Using +** OleStdMsgFilter_SetInComingStatus allows the app to reject or +** accept ALL in coming calls. Using a HandleInComingCallbackProc +** allows the app to selectively handle or reject particular method +** calls. +*/ + +STDAPI_(void) OleStdMsgFilter_SetInComingCallStatus( + LPMESSAGEFILTER lpThis, DWORD dwInComingCallStatus) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + + if (!IsBadWritePtr((LPVOID)lpStdMsgFilter, sizeof(OLESTDMESSAGEFILTER))) + lpStdMsgFilter->m_dwInComingCallStatus = dwInComingCallStatus; + else + OleDbgAssert( + TEXT("OleStdMsgFilter_SetIncomingCallStatus: Invalid IMessageFilter*")); + +#if defined( _DEBUG ) + { + TCHAR szBuf[80]; + TCHAR *szReturn; + + switch(dwInComingCallStatus) { + case SERVERCALL_ISHANDLED: + szReturn = TEXT("SERVERCALL_ISHANDLED"); + break; + case SERVERCALL_REJECTED: + szReturn = TEXT("SERVERCALL_REJECTED"); + break; + case SERVERCALL_RETRYLATER: + szReturn = TEXT("SERVERCALL_RETRYLATER"); + break; + default: + szReturn = TEXT("** ERROR: UNKNOWN **"); + break; + } + wsprintf( + szBuf, + TEXT("OleStdMsgFilter_SetInComingCallStatus: Status set to %s.\r\n"), + (LPTSTR)szReturn + ); + OleDbgOut3(szBuf); + } +#endif + +} + + +/* OleStdMsgFilter_SetHandleInComingCallbackProc +** --------------------------------------------- +** This is a private function that allows the caller to install (or +** de-install) a special callback function to selectively +** handle/reject specific incoming method calls on particular +** interfaces. +** +** if a HandleInComingCallbackProc is installed by a call to +** OleStdMsgFilter_SetHandleInComingCallbackProc, then this +** overrides the dwIncomingCallStatus established by a call to +** OleStdMsgFilter_SetInComingStatus. Using +** OleStdMsgFilter_SetInComingStatus allows the app to reject or +** accept ALL in coming calls. Using a HandleInComingCallbackProc +** allows the app to selectively handle or reject particular method +** calls. +** +** to de-install the HandleInComingCallbackProc, call +** OleStdMsgFilter_SetHandleInComingCallbackProc(NULL); +** +** Returns previous callback proc in effect. +*/ + +STDAPI_(HANDLEINCOMINGCALLBACKPROC) + OleStdMsgFilter_SetHandleInComingCallbackProc( + LPMESSAGEFILTER lpThis, + HANDLEINCOMINGCALLBACKPROC lpfnHandleInComingCallback) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + HANDLEINCOMINGCALLBACKPROC lpfnPrevCallback = + lpStdMsgFilter->m_lpfnHandleInComingCallback; + + if (!IsBadWritePtr((LPVOID)lpStdMsgFilter, sizeof(OLESTDMESSAGEFILTER))) { + lpStdMsgFilter->m_lpfnHandleInComingCallback = + lpfnHandleInComingCallback; + } else { + OleDbgAssert( + TEXT("OleStdMsgFilter_SetIncomingCallStatus: Invalid IMessageFilter*")); + } + +#if defined( _DEBUG ) + { + if (lpfnHandleInComingCallback) + OleDbgOut3( + TEXT("OleStdMsgFilter_SetHandleInComingCallbackProc SET\r\n")); + else + OleDbgOut3( + TEXT("OleStdMsgFilter_SetHandleInComingCallbackProc CLEARED\r\n")); + + } +#endif // _DEBUG + + return lpfnPrevCallback; +} + + +/* OleStdMsgFilter_GetInComingStatus +** --------------------------------- +** This is a private function that returns the current +** incoming call status. Can be used to disable/enable options +** in the calling application. +** +** Returns: one of +** +** SERVERCALL_ISHANDLED +** SERVERCALL_REJECTED +** SERVERCALL_RETRYLATER +** or -1 for ERROR +** +*/ + +STDAPI_(DWORD) OleStdMsgFilter_GetInComingCallStatus( + LPMESSAGEFILTER lpThis) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + DWORD dwReturn; + + if (!IsBadReadPtr((LPVOID)lpStdMsgFilter, sizeof(OLESTDMESSAGEFILTER))) + dwReturn = lpStdMsgFilter->m_dwInComingCallStatus; + else + { + OleDbgAssert( + TEXT("OleStdMsgFilter_GetIncomingCallStatus: Invalid IMessageFilter*")); + dwReturn = (DWORD)-1; + } + +#if defined( _DEBUG ) + { + TCHAR szBuf[80]; + TCHAR *szReturn; + + switch(dwReturn) { + case SERVERCALL_ISHANDLED: + szReturn = TEXT("SERVERCALL_ISHANDLED"); + break; + case SERVERCALL_REJECTED: + szReturn = TEXT("SERVERCALL_REJECTED"); + break; + case SERVERCALL_RETRYLATER: + szReturn = TEXT("SERVERCALL_RETRYLATER"); + break; + default: + szReturn = TEXT("-1"); + break; + } + wsprintf( + szBuf, + TEXT("OleStdMsgFilter_GetInComingCallStatus returns %s.\r\n"), + (LPTSTR)szReturn + ); + OleDbgOut3(szBuf); + } +#endif + + return dwReturn; +} + + +/* OleStdMsgFilter_EnableBusyDialog +** -------------------------------- +** This function allows the caller to control whether +** the busy dialog is enabled. this is the dialog put up when +** IMessageFilter::RetryRejectedCall is called because the server +** responded SERVERCALL_RETRYLATER or SERVERCALL_REJECTED. +** +** if the busy dialog is NOT enabled, then the rejected call is +** immediately canceled WITHOUT prompting the user. in this situation +** OleStdMsgFilter_RetryRejectedCall always retuns +** OLESTDCANCELRETRY canceling the outgoing LRPC call. +** If the busy dialog is enabled, then the user is given the choice +** of whether to retry, switch to, or cancel. +** +** Returns previous dialog enable state +*/ + +STDAPI_(BOOL) OleStdMsgFilter_EnableBusyDialog( + LPMESSAGEFILTER lpThis, BOOL fEnable) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + BOOL fPrevEnable = lpStdMsgFilter->m_fEnableBusyDialog; + + if (!IsBadWritePtr((LPVOID)lpStdMsgFilter, sizeof(OLESTDMESSAGEFILTER))) + lpStdMsgFilter->m_fEnableBusyDialog = fEnable; + else + OleDbgAssert( + TEXT("OleStdMsgFilter_EnableBusyDialog: Invalid IMessageFilter*")); + +#if defined( _DEBUG ) + { + TCHAR szBuf[80]; + wsprintf( + szBuf, + TEXT("OleStdMsgFilter_EnableBusyDialog: Dialog is %s.\r\n"), + fEnable ? (LPTSTR) TEXT("ENABLED") : (LPTSTR) TEXT("DISABLED") + ); + OleDbgOut3(szBuf); + } +#endif + + return fPrevEnable; +} + + +/* OleStdMsgFilter_EnableNotRespondingDialog +** ----------------------------------------- +** This function allows the caller to control whether +** the app "NotResponding" (Blocked) dialog is enabled. this is the +** dialog put up when IMessageFilter::MessagePending is called. +** If the NotResponding dialog is enabled, then the user is given +** the choice of whether to retry or switch to, but NOT to cancel. +** +** Returns previous dialog enable state +*/ + +STDAPI_(BOOL) OleStdMsgFilter_EnableNotRespondingDialog( + LPMESSAGEFILTER lpThis, BOOL fEnable) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + BOOL fPrevEnable = lpStdMsgFilter->m_fEnableNotRespondingDialog; + + if (!IsBadWritePtr((LPVOID)lpStdMsgFilter, sizeof(OLESTDMESSAGEFILTER))) + lpStdMsgFilter->m_fEnableNotRespondingDialog = fEnable; + else + OleDbgAssert( + TEXT("OleStdMsgFilter_EnableNotRespondingDialog: Invalid IMessageFilter*")); + +#if defined( _DEBUG ) + { + TCHAR szBuf[80]; + wsprintf( + szBuf, + TEXT("OleStdMsgFilter_EnableNotRespondingDialog: Dialog is %s.\r\n"), + fEnable ? (LPTSTR) TEXT("ENABLED") : (LPTSTR) TEXT("DISABLED") + ); + OleDbgOut3(szBuf); + } +#endif + + return fPrevEnable; +} + + +/* OleStdMsgFilter_SetParentWindow +** ------------------------------- +** This function allows caller to set which window will be used as +** the parent for the busy dialog. +** +** OLE2NOTE: it would be inportant for an in-place active server to +** reset this to its current in-place frame window when in-place +** activated. if the hWndParent is set to NULL then the dialogs will +** be parented to the desktop. +** +** Returns: previous parent window +*/ + +STDAPI_(HWND) OleStdMsgFilter_SetParentWindow( + LPMESSAGEFILTER lpThis, HWND hWndParent) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + HWND hWndPrev = lpStdMsgFilter->m_hWndParent; + + lpStdMsgFilter->m_hWndParent = hWndParent; + return hWndPrev; +} + + +STDMETHODIMP OleStdMsgFilter_QueryInterface( + LPMESSAGEFILTER lpThis, REFIID riid, LPVOID FAR* ppvObj) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + SCODE scode; + + /* Two interfaces supported: IUnknown, IMessageFilter + */ + + if (IsEqualIID(riid, &IID_IMessageFilter) || IsEqualIID(riid, &IID_IUnknown)) { + lpStdMsgFilter->m_cRef++; // A pointer to this object is returned + *ppvObj = lpThis; + scode = S_OK; + } + else { // unsupported interface + *ppvObj = NULL; + scode = E_NOINTERFACE; + } + + return ResultFromScode(scode); +} + + +STDMETHODIMP_(ULONG) OleStdMsgFilter_AddRef(LPMESSAGEFILTER lpThis) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + return ++lpStdMsgFilter->m_cRef; +} + +STDMETHODIMP_(ULONG) OleStdMsgFilter_Release(LPMESSAGEFILTER lpThis) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + LPMALLOC lpMalloc; + + if (--lpStdMsgFilter->m_cRef != 0) // Still used by others + return lpStdMsgFilter->m_cRef; + + // Free storage + if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) + return (ULONG)0; + + lpMalloc->lpVtbl->Free(lpMalloc, lpStdMsgFilter); + lpMalloc->lpVtbl->Release(lpMalloc); + return (ULONG)0; +} + + +STDMETHODIMP_(DWORD) OleStdMsgFilter_HandleInComingCall ( + LPMESSAGEFILTER lpThis, + DWORD dwCallType, + HTASK htaskCaller, + DWORD dwTickCount, +#ifdef WIN32 + LPINTERFACEINFO dwReserved +#else + DWORD dwReserved +#endif +) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + + /* if a HandleInComingCallbackProc is in effect, then this + ** overrides dwIncomingCallStatus established by a call to + ** OleStdMsgFilter_SetInComingStatus. we will call this + ** callback to allow the app to selectively handle or reject + ** incoming method calls. the LPINTERFACEINFO parameter + ** describes which method is being called. + */ + if (lpStdMsgFilter->m_lpfnHandleInComingCallback && + !IsBadCodePtr((FARPROC)lpStdMsgFilter->m_lpfnHandleInComingCallback)){ + return lpStdMsgFilter->m_lpfnHandleInComingCallback( + dwCallType, + htaskCaller, + dwTickCount, + dwReserved + ); + } + + switch (dwCallType) { + case CALLTYPE_TOPLEVEL: + /* OLE2NOTE: we currently have NO pending outgoing call and + ** there is a new toplevel incoming call. + ** this call may be rejected. + */ + return lpStdMsgFilter->m_dwInComingCallStatus; + + case CALLTYPE_TOPLEVEL_CALLPENDING: + /* OLE2NOTE: we currently HAVE a pending outgoing call and + ** there is a new toplevel incoming call. + ** this call may be rejected. + */ + return lpStdMsgFilter->m_dwInComingCallStatus; + + case CALLTYPE_NESTED: + /* OLE2NOTE: we currently HAVE a pending outgoing call and + ** there callback on behalf of the previous outgoing + ** call. this type of call should ALWAYS be handled. + */ + return SERVERCALL_ISHANDLED; + + case CALLTYPE_ASYNC: + /* OLE2NOTE: we currently have NO pending outgoing call and + ** there is a new asyncronis incoming call. + ** this call can NEVER be rejected. OLE actually ignores + ** the return code in this case and always allows the + ** call through. + */ + return SERVERCALL_ISHANDLED; // value returned does not matter + + case CALLTYPE_ASYNC_CALLPENDING: + /* OLE2NOTE: we currently HAVE a pending outgoing call and + ** there is a new asyncronis incoming call. + ** this call can NEVER be rejected. OLE ignore the + ** return code in this case. + */ + return SERVERCALL_ISHANDLED; // value returned does not + + default: + OleDbgAssert( + TEXT("OleStdMsgFilter_HandleInComingCall: Invalid CALLTYPE")); + return lpStdMsgFilter->m_dwInComingCallStatus; + } +} + +STDMETHODIMP_(DWORD) OleStdMsgFilter_RetryRejectedCall ( + LPMESSAGEFILTER lpThis, + HTASK htaskCallee, + DWORD dwTickCount, + DWORD dwRejectType +) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + DWORD dwRet = 0; + UINT uRet; +#if defined( _DEBUG ) + TCHAR szBuf[80]; +#endif + OLEDBG_BEGIN2(TEXT("OleStdMsgFilter_RetryRejectedCall\r\n")) + + /* OLE2NOTE: we should only put up the application busy dialog when + ** the callee has responded SERVERCALL_RETRYLATER. if the + ** dwRejectType is SERVERCALL_REJECTED then there is something + ** seriously wrong with the callee (perhaps a severe low memory + ** situation). we don't want to even try to "Switch To" this app + ** or even try to "Retry". + */ + if (dwRejectType == SERVERCALL_RETRYLATER && + lpStdMsgFilter->m_fEnableBusyDialog) { + + OLEUIBUSY bz; + + /* OLE2NOTE: we do not want to put up the Busy dialog immediately + ** the when an app says RETRYLATER. we should continue retrying + ** for a while in case the app can un-busy itself in a + ** reasonable amount of time. + */ + if (dwTickCount <= (DWORD)OLESTDRETRYDELAY) { + dwRet = 500; // Retry after .5 sec + OLEDBG_END2 + return dwRet; + } + + /* + ** Set up structure for calling OLEUIBUSY dialog + */ + + bz.cbStruct = sizeof(OLEUIBUSY); + bz.dwFlags = 0L; + bz.hWndOwner =GetTopWindowInWindowsTask(lpStdMsgFilter->m_hWndParent); + bz.lpszCaption = lpStdMsgFilter->m_lpszAppName; + bz.lpfnHook = lpStdMsgFilter->m_lpfnBusyDialogHookCallback; + bz.lCustData = 0; + bz.hInstance = NULL; + bz.lpszTemplate = NULL; + bz.hResource = 0; + bz.hTask = htaskCallee; + bz.lphWndDialog = NULL; // We don't need the hDlg for this call + + uRet = OleUIBusy(&bz); + + switch (uRet) { + case OLEUI_BZ_RETRYSELECTED: + dwRet = 0; // Retry immediately + break; + + case OLEUI_CANCEL: + dwRet = OLESTDCANCELRETRY; // Cancel pending outgoing call + break; + + case OLEUI_BZERR_HTASKINVALID: + // Htask was invalid, return OLESTDRETRYDELAY anyway + dwRet = OLESTDRETRYDELAY; // Retry after <retry delay> msec + +#if defined( _DEBUG ) + wsprintf( + szBuf, + TEXT("OleStdMsgFilter_RetryRejectedCall, HTASK 0x%x invalid\r\n"), + htaskCallee + ); + OleDbgOut3(szBuf); +#endif + break; + } + } else { + dwRet = OLESTDCANCELRETRY; // Cancel pending outgoing call + } + +#if defined( _DEBUG ) + wsprintf(szBuf, + TEXT("OleStdMsgFilter_RetryRejectedCall returns %d\r\n"), + dwRet); + OleDbgOut3(szBuf); +#endif + + OLEDBG_END2 + return dwRet; +} + + + +/* a significant message is consider a mouse click or keyboard input. */ +#define IS_SIGNIFICANT_MSG(lpmsg) \ + ( \ + (PeekMessage((lpmsg), NULL, WM_LBUTTONDOWN, WM_LBUTTONDOWN, \ + PM_NOREMOVE | PM_NOYIELD)) \ + || (PeekMessage((lpmsg), NULL, WM_LBUTTONDBLCLK, WM_LBUTTONDBLCLK, \ + PM_NOREMOVE | PM_NOYIELD)) \ + || (PeekMessage((lpmsg), NULL, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, \ + PM_NOREMOVE | PM_NOYIELD)) \ + || (PeekMessage((lpmsg), NULL, WM_NCLBUTTONDBLCLK, WM_NCLBUTTONDBLCLK, \ + PM_NOREMOVE | PM_NOYIELD)) \ + || (PeekMessage((lpmsg), NULL, WM_KEYDOWN, WM_KEYDOWN, \ + PM_NOREMOVE | PM_NOYIELD)) \ + || (PeekMessage((lpmsg), NULL, WM_SYSKEYDOWN, WM_SYSKEYDOWN, \ + PM_NOREMOVE | PM_NOYIELD)) \ + ) + +STDMETHODIMP_(DWORD) OleStdMsgFilter_MessagePending ( + LPMESSAGEFILTER lpThis, + HTASK htaskCallee, + DWORD dwTickCount, + DWORD dwPendingType +) +{ + LPOLESTDMESSAGEFILTER lpStdMsgFilter = (LPOLESTDMESSAGEFILTER)lpThis; + DWORD dwReturn = PENDINGMSG_WAITDEFPROCESS; + MSG msg; + BOOL fIsSignificantMsg = IS_SIGNIFICANT_MSG(&msg); + UINT uRet; + +#if defined( _DEBUG ) + TCHAR szBuf[128]; + wsprintf( + szBuf, + TEXT("OleStdMsgFilter_MessagePending, dwTickCount = 0x%lX\r\n"), + (DWORD)dwTickCount + ); + OleDbgOut4(szBuf); +#endif + + /* OLE2NOTE: If our tick count for this call exceeds our standard retry + ** delay, then we need to put up the dialog. We will only + ** consider putting up the dialog if the user has issued a + ** "significant" event (ie. mouse click or keyboard event). a + ** simple mouse move should NOT trigger this dialog. + ** Since our call to + ** OleUIBusy below enters a DialogBox() message loop, there's a + ** possibility that another call will be initiated during the dialog, + ** and this procedure will be re-entered. Just so we don't put up + ** two dialogs at a time, we use the m_bUnblocking varable + ** to keep track of this situation. + */ + + if (dwTickCount > (DWORD)OLESTDRETRYDELAY && fIsSignificantMsg + && !lpStdMsgFilter->m_bUnblocking) + { + + if (lpStdMsgFilter->m_fEnableNotRespondingDialog) + { + OLEUIBUSY bz; + + lpStdMsgFilter->m_bUnblocking = TRUE; + + // Eat messages in our queue that we do NOT want to be dispatched + while (PeekMessage(&msg, NULL, WM_CLOSE, WM_CLOSE, PM_REMOVE | PM_NOYIELD)); + + /* Set up structure for calling OLEUIBUSY dialog, + ** using the "not responding" variety + */ + + bz.cbStruct = sizeof(OLEUIBUSY); + bz.dwFlags = BZ_NOTRESPONDINGDIALOG; + bz.hWndOwner =GetTopWindowInWindowsTask(lpStdMsgFilter->m_hWndParent); + bz.lpszCaption = lpStdMsgFilter->m_lpszAppName; + bz.lpfnHook = lpStdMsgFilter->m_lpfnBusyDialogHookCallback; + bz.lCustData = 0; + bz.hInstance = NULL; + bz.lpszTemplate = NULL; + bz.hResource = 0; + bz.hTask = htaskCallee; + + /* Set up the address to the hWnd in our MsgFilter structure. The + ** call to OleUIBusy will fill this in with the hWnd of the busy + ** dialog box + */ + + bz.lphWndDialog = (HWND FAR *)&(lpStdMsgFilter->m_hWndBusyDialog); + uRet = OleUIBusy(&bz); + + lpStdMsgFilter->m_bUnblocking = FALSE; + + return PENDINGMSG_WAITNOPROCESS; + } +#if defined( _DEBUG ) + else { + OleDbgOut3(TEXT("OleStdMsgFilter_MessagePending: BLOCKED but dialog Disabled\r\n")); + } +#endif + } + + /* If we're already unblocking, we're being re-entered. Don't + ** process message + */ + + if (lpStdMsgFilter->m_bUnblocking) + return PENDINGMSG_WAITDEFPROCESS; + + /* OLE2NOTE: If we have a callback function set up, call it with the + ** current message. If not, tell OLE LPRC mechanism to automatically + ** handle all messages. + */ + if (lpStdMsgFilter->m_lpfnMessagePendingCallback && + !IsBadCodePtr((FARPROC)lpStdMsgFilter->m_lpfnMessagePendingCallback)){ + MSG msg; + + /* OLE2NOTE: the app provided a MessagePendingCallback + ** function. we will PeekMessage for the first message in + ** the queue and pass it to the app. the app in its callback + ** function can decide to Dispatch this message or it can + ** PeekMessage on its own giving particular message filter + ** criteria. if the app returns TRUE then we return + ** PENDINGMSG_WAITNOPROCESS to OLE telling OLE to leave the + ** message in the queue. If the app returns FALSE, then we + ** return PENDINGMSG_WAITDEFPROCESS to OLE telling OLE to do + ** its default processing with the message. by default OLE + ** dispatches system messages and eats other messages and + ** beeps. + */ + if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD)) { + + if (lpStdMsgFilter->m_lpfnMessagePendingCallback(&msg)) { + /* TRUE return means that the app processed message. + ** + ** NOTE: (CHANGE FROM OLE2.0 VERSION) we leave it up to + ** the callback routine to remove the message if it + ** wants. + */ + dwReturn = PENDINGMSG_WAITNOPROCESS; + } else { + /* FALSE means that the app did not process the + ** message. we will let OLE take its + ** default action. + ** + ** NOTE: (CHANGE FROM OLE2.0 VERSION) we used to return + ** PENDINGMSG_WAITNOPROCESS to leave the message in + ** the queue; now we return PENDINGMSG_WAITDEFPROCESS + ** to let OLE do default processing. + */ + dwReturn = PENDINGMSG_WAITDEFPROCESS; + +#if defined( _DEBUG ) + wsprintf( + szBuf, + TEXT("Message (0x%x) (wParam=0x%x, lParam=0x%lx) using WAITDEFPROCESS while blocked\r\n"), + msg.message, + msg.lParam, + msg.wParam + ); + OleDbgOut2(szBuf); +#endif // _DEBUG + } + } + } + + return dwReturn; +} diff --git a/private/oleutest/letest/ole2ui/msgfiltr.h b/private/oleutest/letest/ole2ui/msgfiltr.h new file mode 100644 index 000000000..a542d5294 --- /dev/null +++ b/private/oleutest/letest/ole2ui/msgfiltr.h @@ -0,0 +1,64 @@ +/************************************************************************* +** +** OLE 2 Utility Code +** +** msgfiltr.h +** +** This file contains Private definitions, structures, types, and +** function prototypes for the OleStdMessageFilter implementation of +** the IMessageFilter interface. +** This file is part of the OLE 2.0 User Interface support library. +** +** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved +** +*************************************************************************/ + +#if !defined( _MSGFILTR_H_ ) +#define _MSGFILTR_H_ + +#ifndef RC_INVOKED +#pragma message ("INCLUDING MSGFILTR.H from " __FILE__) +#endif /* RC_INVOKED */ + +// Message Pending callback procedure +typedef BOOL (CALLBACK* MSGPENDINGPROC)(MSG FAR *); + +// HandleInComingCall callback procedure +typedef DWORD (CALLBACK* HANDLEINCOMINGCALLBACKPROC) + ( + DWORD dwCallType, + HTASK htaskCaller, + DWORD dwTickCount, + LPINTERFACEINFO lpInterfaceInfo + ); + +/* PUBLIC FUNCTIONS */ +STDAPI_(LPMESSAGEFILTER) OleStdMsgFilter_Create( + HWND hWndParent, + LPTSTR szAppName, + MSGPENDINGPROC lpfnCallback, + LPFNOLEUIHOOK lpfnOleUIHook // Busy dialog hook callback +); + +STDAPI_(void) OleStdMsgFilter_SetInComingCallStatus( + LPMESSAGEFILTER lpThis, DWORD dwInComingCallStatus); + +STDAPI_(DWORD) OleStdMsgFilter_GetInComingCallStatus( + LPMESSAGEFILTER lpThis); + +STDAPI_(HANDLEINCOMINGCALLBACKPROC) + OleStdMsgFilter_SetHandleInComingCallbackProc( + LPMESSAGEFILTER lpThis, + HANDLEINCOMINGCALLBACKPROC lpfnHandleInComingCallback); + +STDAPI_(BOOL) OleStdMsgFilter_EnableBusyDialog( + LPMESSAGEFILTER lpThis, BOOL fEnable); + +STDAPI_(BOOL) OleStdMsgFilter_EnableNotRespondingDialog( + LPMESSAGEFILTER lpThis, BOOL fEnable); + +STDAPI_(HWND) OleStdMsgFilter_SetParentWindow( + LPMESSAGEFILTER lpThis, HWND hWndParent); + + +#endif // _MSGFILTR_H_ diff --git a/private/oleutest/letest/ole2ui/objfdbk.c b/private/oleutest/letest/ole2ui/objfdbk.c new file mode 100644 index 000000000..65e30f907 --- /dev/null +++ b/private/oleutest/letest/ole2ui/objfdbk.c @@ -0,0 +1,246 @@ +/* + * OBJFDBK.C + * + * Miscellaneous API's to generate UI feedback effects for OLE objects. This + * is part of the OLE 2.0 User Interface Support Library. + * The following feedback effects are supported: + * 1. Object selection handles (OleUIDrawHandles) + * 2. Open Object window shading (OleUIDrawShading) + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" + +static void DrawHandle(HDC hdc, int x, int y, UINT cSize, BOOL bInvert, BOOL fDraw); + +/* + * OleUIDrawHandles + * + * Purpose: + * Draw handles or/and boundary around Container Object when selected + * + * Parameters: + * lpRect Dimensions of Container Object + * hdc HDC of Container Object (MM_TEXT mapping mode) + * dwFlags- + * Exclusive flags + * OLEUI_HANDLES_INSIDE Draw handles on inside of rect + * OLEUI_HANDLES_OUTSIDE Draw handles on outside of rect + * Optional flags + * OLEUI_HANDLES_NOBORDER Draw handles only, no rect + * OLEUI_HANDLES_USEINVERSE + * use invert for handles and rect, o.t. use COLOR_WINDOWTEXT + * cSize size of handle box + * fDraw Draw if TRUE, erase if FALSE + * + * Return Value: null + * + */ +STDAPI_(void) OleUIDrawHandles( + LPRECT lpRect, + HDC hdc, + DWORD dwFlags, + UINT cSize, + BOOL fDraw +) +{ + HBRUSH hbr; + RECT rc; + int bkmodeOld; + BOOL bInvert = (BOOL) (dwFlags & OLEUI_HANDLES_USEINVERSE); + + CopyRect((LPRECT)&rc, lpRect); + + bkmodeOld = SetBkMode(hdc, TRANSPARENT); + + if (dwFlags & OLEUI_HANDLES_OUTSIDE) + InflateRect((LPRECT)&rc, cSize - 1, cSize - 1); + + // Draw the handles inside the rectangle boundary + DrawHandle(hdc, rc.left, rc.top, cSize, bInvert, fDraw); + DrawHandle(hdc, rc.left, rc.top+(rc.bottom-rc.top-cSize)/2, cSize, bInvert, fDraw); + DrawHandle(hdc, rc.left, rc.bottom-cSize, cSize, bInvert, fDraw); + DrawHandle(hdc, rc.left+(rc.right-rc.left-cSize)/2, rc.top, cSize, bInvert, fDraw); + DrawHandle(hdc, rc.left+(rc.right-rc.left-cSize)/2, rc.bottom-cSize, cSize, bInvert, fDraw); + DrawHandle(hdc, rc.right-cSize, rc.top, cSize, bInvert, fDraw); + DrawHandle(hdc, rc.right-cSize, rc.top+(rc.bottom-rc.top-cSize)/2, cSize, bInvert, fDraw); + DrawHandle(hdc, rc.right-cSize, rc.bottom-cSize, cSize, bInvert, fDraw); + + if (!(dwFlags & OLEUI_HANDLES_NOBORDER)) { + if (fDraw) + hbr = GetStockObject(BLACK_BRUSH); + else + hbr = GetStockObject(WHITE_BRUSH); + + FrameRect(hdc, lpRect, hbr); + } + + SetBkMode(hdc, bkmodeOld); +} + + + +/* + * DrawHandle + * + * Purpose: + * Draw a handle box at the specified coordinate + * + * Parameters: + * hdc HDC to be drawn into + * x, y upper left corner coordinate of the handle box + * cSize size of handle box + * bInvert use InvertRect() if TRUE, otherwise use Rectangle() + * fDraw Draw if TRUE, erase if FALSE, ignored if bInvert is TRUE + * + * Return Value: null + * + */ +static void DrawHandle(HDC hdc, int x, int y, UINT cSize, BOOL bInvert, BOOL fDraw) +{ + HBRUSH hbr; + HBRUSH hbrOld; + HPEN hpen; + HPEN hpenOld; + RECT rc; + + + if (!bInvert) { + if (fDraw) { + hpen = GetStockObject(BLACK_PEN); + hbr = GetStockObject(BLACK_BRUSH); + } else { + hpen = GetStockObject(WHITE_PEN); + hbr = GetStockObject(WHITE_PEN); + } + + hpenOld = SelectObject(hdc, hpen); + hbrOld = SelectObject(hdc, hbr); + Rectangle(hdc, x, y, x+cSize, y+cSize); + SelectObject(hdc, hpenOld); + SelectObject(hdc, hbrOld); + } + else { + rc.left = x; + rc.top = y; + rc.right = x + cSize; + rc.bottom = y + cSize; + InvertRect(hdc, (LPRECT)&rc); + } +} + + +/* + * OleUIDrawShading + * + * Purpose: + * Shade the object when it is in in-place editing. Borders are drawn + * on the Object rectangle. The right and bottom edge of the rectangle + * are excluded in the drawing. + * + * Parameters: + * lpRect Dimensions of Container Object + * hdc HDC for drawing + * dwFlags- + * Exclusive flags + * OLEUI_SHADE_FULLRECT Shade the whole rectangle + * OLEUI_SHADE_BORDERIN Shade cWidth pixels inside rect + * OLEUI_SHADE_BORDEROUT Shade cWidth pixels outside rect + * Optional flags + * OLEUI_SHADE_USEINVERSE + * use PATINVERT instead of the hex value + * cWidth width of border in pixel + * + * Return Value: null + * + */ +STDAPI_(void) OleUIDrawShading(LPRECT lpRect, HDC hdc, DWORD dwFlags, UINT cWidth) +{ + HBRUSH hbr; + HBRUSH hbrOld; + HBITMAP hbm; + RECT rc; + WORD wHatchBmp[] = {0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88}; + COLORREF cvText; + COLORREF cvBk; + + hbm = CreateBitmap(8, 8, 1, 1, wHatchBmp); + hbr = CreatePatternBrush(hbm); + hbrOld = SelectObject(hdc, hbr); + + rc = *lpRect; + + if (dwFlags == OLEUI_SHADE_FULLRECT) { + cvText = SetTextColor(hdc, RGB(255, 255, 255)); + cvBk = SetBkColor(hdc, RGB(0, 0, 0)); + PatBlt(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, + 0x00A000C9L /* DPa */ ); + + } else { // either inside or outside rect + + if (dwFlags == OLEUI_SHADE_BORDEROUT) + InflateRect((LPRECT)&rc, cWidth - 1, cWidth - 1); + + cvText = SetTextColor(hdc, RGB(255, 255, 255)); + cvBk = SetBkColor(hdc, RGB(0, 0, 0)); + PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, + cWidth, 0x00A000C9L /* DPa */); + PatBlt(hdc, rc.left, rc.top, cWidth, rc.bottom - rc.top, + 0x00A000C9L /* DPa */); + PatBlt(hdc, rc.right - cWidth, rc.top, cWidth, + rc.bottom - rc.top, 0x00A000C9L /* DPa */); + PatBlt(hdc, rc.left, rc.bottom - cWidth, rc.right-rc.left, + cWidth, 0x00A000C9L /* DPa */); + } + + SetTextColor(hdc, cvText); + SetBkColor(hdc, cvBk); + SelectObject(hdc, hbrOld); + DeleteObject(hbr); + DeleteObject(hbm); +} + + +/* + * OleUIShowObject + * + * Purpose: + * Draw the ShowObject effect around the object + * + * Parameters: + * lprc rectangle for drawing + * hdc HDC for drawing + * fIsLink linked object (TRUE) or embedding object (FALSE) + * + * Return Value: null + * + */ +STDAPI_(void) OleUIShowObject(LPCRECT lprc, HDC hdc, BOOL fIsLink) +{ + HPEN hpen; + HPEN hpenOld; + HBRUSH hbrOld; + + if (!lprc || !hdc) + return; + + hpen = fIsLink ? CreatePen(PS_DASH, 1, RGB(0,0,0)) : + GetStockObject(BLACK_PEN); + + if (!hpen) + return; + + hpenOld = SelectObject(hdc, hpen); + hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH)); + + Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); + + SelectObject(hdc, hpenOld); + SelectObject(hdc, hbrOld); + + if (fIsLink) + DeleteObject(hpen); + +} diff --git a/private/oleutest/letest/ole2ui/ole2ui.c b/private/oleutest/letest/ole2ui/ole2ui.c new file mode 100644 index 000000000..fd1fc57bc --- /dev/null +++ b/private/oleutest/letest/ole2ui/ole2ui.c @@ -0,0 +1,971 @@ +/* + * OLE2UI.C + * + * Contains initialization routines and miscellaneous API implementations for + * the OLE 2.0 User Interface Support Library. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 + +#include "ole2ui.h" +#include "common.h" +#include "utility.h" +#include "resimage.h" +#include "iconbox.h" +#include <commdlg.h> + +#define WINDLL 1 // make far pointer version of stdargs.h +#include <stdarg.h> + +// NOTE: If this code is being compiled for a DLL, then we need to define +// our OLE2UI debug symbols here (with the OLEDBGDATA_MAIN macro). If we're +// compiling for a static LIB, then the application we link to must +// define these symbols -- we just need to make an external reference here +// (with the macro OLEDBGDATA). + +#ifdef DLL_VER +OLEDBGDATA_MAIN(TEXT("OLE2UI")) +#else +OLEDBGDATA +#endif + +//The DLL instance handle shared amongst all dialogs. +HINSTANCE ghInst; + +//Registered messages for use with all the dialogs, registered in LibMain +UINT uMsgHelp=0; +UINT uMsgEndDialog=0; +UINT uMsgBrowse=0; +UINT uMsgChangeIcon=0; +UINT uMsgFileOKString=0; +UINT uMsgCloseBusyDlg=0; + +//Clipboard formats used by PasteSpecial +UINT cfObjectDescriptor; +UINT cfLinkSrcDescriptor; +UINT cfEmbedSource; +UINT cfEmbeddedObject; +UINT cfLinkSource; +UINT cfOwnerLink; +UINT cfFileName; + +// local function prototypes +BOOL CALLBACK EXPORT PromptUserDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK EXPORT UpdateLinksDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); + + +// local definition +#define WM_U_UPDATELINK WM_USER + + +// 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 OLE2UI 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). + * + * lpszClassIconBox + * LPTSTR containing the name you assigned to the symbol + * SZCLASSICONBOX (this symbol is defined in UICLASS.H + * which is generated in the MAKEFILE). + * + * This name is used as the window class name + * when registering the IconBox custom control used in the + * UI dialogs. In order to handle mutliple apps running + * with this library, you must make this name unique to your + * application. + * + * For the DLL version: Do NOT call this function directly + * from your application, it is called automatically from + * the DLL's LibMain. + * + * For the static library version: This should be set to + * the symbol SZCLASSICONBOX. This symbol is defined in + * UICLASS.H. + * + * lpszClassResImage + * LPTSTR containing the name you assigned to the symbol + * SZCLASSRESULTIMAGE. See the description of + * lpszClassIconBox above for more info. + * + * Return Value: + * BOOL TRUE if initialization was successful. + * FALSE if either the "Magic Number" did not verify, or one of + * the window classes could not be registered. If the + * "Magic Number" did not verify, then the resources + * in your module are of a different version than the + * ones you compiled with. + */ + +STDAPI_(BOOL) OleUIInitialize(HINSTANCE hInstance, + HINSTANCE hPrevInst, + LPTSTR lpszClassIconBox, + LPTSTR lpszClassResImage) +{ + HRSRC hr; + HGLOBAL hg; + LPWORD lpdata; + + OleDbgOut1(TEXT("OleUIInitialize called.\r\n")); + ghInst=hInstance; + + // Verify that we have the correct resources added to our application + // by checking the "VERIFICATION" resource with the magic number we've + // compiled into our app. + + OutputDebugString(TEXT("Entering OleUIInitialize\n")); + + if ((hr = FindResource(hInstance, TEXT("VERIFICATION"), RT_RCDATA)) == NULL) + goto ResourceLoadError; + + if ((hg = LoadResource(hInstance, hr)) == NULL) + goto ResourceLoadError; + + if ((lpdata = (LPWORD)LockResource(hg)) == NULL) + goto ResourceLockError; + + if ((WORD)*lpdata != (WORD)OLEUI_VERSION_MAGIC) + goto ResourceReadError; + + // OK, resource versions match. Contine on. + UnlockResource(hg); + FreeResource(hg); + OleDbgOut1(TEXT("OleUIInitialize: Resource magic number verified.\r\n")); + + // Register messages we need for the dialogs. If + 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); + + // Register Clipboard Formats used by PasteSpecial dialog. + cfObjectDescriptor = RegisterClipboardFormat(CF_OBJECTDESCRIPTOR); + cfLinkSrcDescriptor= RegisterClipboardFormat(CF_LINKSRCDESCRIPTOR); + cfEmbedSource = RegisterClipboardFormat(CF_EMBEDSOURCE); + cfEmbeddedObject = RegisterClipboardFormat(CF_EMBEDDEDOBJECT); + cfLinkSource = RegisterClipboardFormat(CF_LINKSOURCE); + cfOwnerLink = RegisterClipboardFormat(CF_OWNERLINK); + cfFileName = RegisterClipboardFormat(CF_FILENAME); + + if (!FResultImageInitialize(hInstance, hPrevInst, lpszClassResImage)) + { + OleDbgOut1(TEXT("OleUIInitialize: FResultImageInitialize failed. Terminating.\r\n")); + return 0; + } + + if (!FIconBoxInitialize(hInstance, hPrevInst, lpszClassIconBox)) + { + OleDbgOut1(TEXT("OleUIInitialize: FIconBoxInitialize failed. Terminating.\r\n")); + return 0; + } + + return TRUE; + +ResourceLoadError: + OleDbgOut1(TEXT("OleUIInitialize: ERROR - Unable to find version verification resource.\r\n")); + return FALSE; + +ResourceLockError: + OleDbgOut1(TEXT("OleUIInitialize: ERROR - Unable to lock version verification resource.\r\n")); + FreeResource(hg); + return FALSE; + +ResourceReadError: + OleDbgOut1(TEXT("OleUIInitialize: ERROR - Version verification values did not compare.\r\n")); + + {TCHAR buf[255]; + wsprintf(buf, TEXT("resource read 0x%X, my value is 0x%X\n"), (WORD)*lpdata, (WORD)OLEUI_VERSION_MAGIC); + OutputDebugString(buf); + } + + UnlockResource(hg); + FreeResource(hg); + return FALSE; +} + + +/* + * 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(); + + 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, + LPTSTR lpszShortType, + HMENU hMenu, + UINT uPos, + UINT uIDVerbMin, + UINT uIDVerbMax, + BOOL bAddConvert, + UINT idConvert, + HMENU FAR *lphMenu) +{ + LPPERSISTSTORAGE lpPS=NULL; + LPENUMOLEVERB lpEnumOleVerb = NULL; + OLEVERB oleverb; + LPUNKNOWN lpUnk; + LPTSTR 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]; + + *lphMenu=NULL; + + // Set fAddConvertItem flag + if (bAddConvert & (idConvert != 0)) + fAddConvertItem = TRUE; + + // only need to load the strings the 1st time + if (fFirstTime) { + if (0 == LoadString(ghInst, IDS_OLE2UIEDITNOOBJCMD, + (LPTSTR)szNoObjectCmd, OLEUI_OBJECTMENUMAX)) + return FALSE; + if (0 == LoadString(ghInst, IDS_OLE2UIEDITLINKCMD_1VERB, + (LPTSTR)szLinkCmd1Verb, OLEUI_OBJECTMENUMAX)) + return FALSE; + if (0 == LoadString(ghInst, IDS_OLE2UIEDITOBJECTCMD_1VERB, + (LPTSTR)szObjectCmd1Verb, OLEUI_OBJECTMENUMAX)) + return FALSE; + + if (0 == LoadString(ghInst, IDS_OLE2UIEDITLINKCMD_NVERB, + (LPTSTR)szLinkCmdNVerb, OLEUI_OBJECTMENUMAX)) + return FALSE; + if (0 == LoadString(ghInst, IDS_OLE2UIEDITOBJECTCMD_NVERB, + (LPTSTR)szObjectCmdNVerb, OLEUI_OBJECTMENUMAX)) + return FALSE; + + if (0 == LoadString(ghInst, IDS_OLE2UIUNKNOWN, + (LPTSTR)szUnknown, OLEUI_OBJECTMENUMAX)) + return FALSE; + + if (0 == LoadString(ghInst, IDS_OLE2UIEDIT, + (LPTSTR)szEdit, OLEUI_OBJECTMENUMAX)) + return FALSE; + + if ( (0 == LoadString(ghInst, IDS_OLE2UICONVERT, + (LPTSTR)szConvert, OLEUI_OBJECTMENUMAX)) && fAddConvertItem) + return FALSE; + + fFirstTime = FALSE; + } + + // Delete whatever menu may happen to be here already. + DeleteMenu(hMenu, uPos, uFlags); + + if (!lpOleObj) + goto AVMError; + + if (! lpszShortTypeName) { + // get the Short form of the user type name for the menu + OLEDBG_BEGIN2(TEXT("IOleObject::GetUserType called\r\n")) + hrErr = CallIOleObjectGetUserTypeA( + lpOleObj, + USERCLASSTYPE_SHORT, + (LPTSTR FAR*)&lpszShortTypeName + ); + OLEDBG_END2 + + if (NOERROR != hrErr) { + OleDbgOutHResult(TEXT("IOleObject::GetUserType returned"), hrErr); + } + } + + // check if the object is a link (it is a link if it support IOleLink) + hrErr = lpOleObj->lpVtbl->QueryInterface( + lpOleObj, + &IID_IOleLink, + (LPVOID FAR*)&lpUnk + ); + if (NOERROR == hrErr) { + fIsLink = TRUE; + OleStdRelease(lpUnk); + } + + // Get the verb enumerator from the OLE object + OLEDBG_BEGIN2(TEXT("IOleObject::EnumVerbs called\r\n")) + hrErr = lpOleObj->lpVtbl->EnumVerbs( + lpOleObj, + (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) { // forever + hrErr = lpEnumOleVerb->lpVtbl->Next( + lpEnumOleVerb, + 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) + OleStdFreeString(lpszVerbName, NULL); + + CopyAndFreeOLESTR(oleverb.lpszVerbName, &lpszVerbName); + + if ( 0 == uIDVerbMax || + (uIDVerbMax >= uIDVerbMin+(UINT)oleverb.lVerb) ) { + fStatus = InsertMenu( + *lphMenu, + (UINT)-1, + MF_BYPOSITION | (UINT)oleverb.fuFlags, + uIDVerbMin+(UINT)oleverb.lVerb, + (LPTSTR)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, NULL); + uIDVerbMin = idConvert; + + // remove "..." from "Convert..." string; it will be added later + if (lpsz) { + while(*lpsz && *lpsz != TEXT('.')) + lpsz++; + *lpsz = TEXT('\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 + * + * NOTE: Localized verb menus may require a different format. + * to assist in localization of the single verb case, the + * szLinkCmd1Verb and szObjectCmd1Verb format strings start + * with either a '0' (note: NOT '\0'!) or a '1': + * leading '0' -- verb type + * leading '1' -- type verb + */ + + 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 ? (LPTSTR)szLinkCmdNVerb:(LPTSTR)szObjectCmdNVerb), + (lpszShortTypeName ? lpszShortTypeName : (LPTSTR) TEXT("")) + ); + uFlags |= MF_GRAYED; + +#if defined( OBSOLETE ) + //No verbs. Create a default using Edit as the verb. + LPTSTR lpsz = (fIsLink ? szLinkCmd1Verb : szObjectCmd1Verb); + + if (*lpsz == TEXT('0')) { + wsprintf(szBuffer, lpsz+1, (LPSTR)szEdit, + (lpszShortTypeName ? lpszShortTypeName : (LPTSTR) TEXT("")) + ); + } + else { + wsprintf(szBuffer, lpsz+1, + (lpszShortTypeName ? lpszShortTypeName : (LPTSTR) TEXT("")), + (LPTSTR)szEdit + ); + } +#endif + + fResult = FALSE; + DestroyMenu(*lphMenu); + *lphMenu = NULL; + + } + else if (cVerbs == 1) { + //One verb without Convert, one item. + LPTSTR lpsz = (fIsLink ? szLinkCmd1Verb : szObjectCmd1Verb); + + if (*lpsz == TEXT('0')) { + wsprintf(szBuffer, lpsz+1, lpszVerbName, + (lpszShortTypeName ? lpszShortTypeName : (LPTSTR) TEXT("")) + ); + } + else { + wsprintf(szBuffer, lpsz+1, + (lpszShortTypeName ? lpszShortTypeName : (LPTSTR) TEXT("")), + lpszVerbName + ); + } + + // 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 ? (LPTSTR)szLinkCmdNVerb:(LPTSTR)szObjectCmdNVerb), + (lpszShortTypeName ? lpszShortTypeName : (LPTSTR) TEXT("")) + ); + uFlags |= MF_ENABLED | MF_POPUP; + uIDVerbMin=(UINT)*lphMenu; + } + + if (!InsertMenu(hMenu, uPos, uFlags, uIDVerbMin, (LPTSTR)szBuffer)) + +AVMError: + { + InsertMenu(hMenu, uPos, MF_GRAYED | uFlags, + uIDVerbMin, (LPTSTR)szNoObjectCmd); +#if defined( OBSOLETE ) + HMENU hmenuDummy = CreatePopupMenu(); + + InsertMenu(hMenu, uPos, MF_GRAYED | MF_POPUP | uFlags, + (UINT)hmenuDummy, (LPTSTR)szNoObjectCmd); +#endif + fResult = FALSE; + } + + if (lpszVerbName) + OleStdFreeString(lpszVerbName, NULL); + if (!lpszShortType && lpszShortTypeName) + OleStdFreeString(lpszShortTypeName, NULL); + if (lpEnumOleVerb) + lpEnumOleVerb->lpVtbl->Release(lpEnumOleVerb); + return fResult; +} + + +/* 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 EXPORT PromptUserDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + switch (iMsg) { + case WM_INITDIALOG: + { + LPTSTR lpszTitle; + TCHAR szBuf[256]; + TCHAR szFormat[256]; + va_list *parglist; + + if (!lParam) { + EndDialog(hDlg, -1); + return FALSE; + } + + // + // lParam is really a va_list *. We called va_start and va_end in + // the function that calls this. + // + + parglist = (va_list *) lParam; + + lpszTitle = va_arg(*parglist, LPTSTR); + SetWindowText(hDlg, lpszTitle); + + GetDlgItemText(hDlg, ID_PU_TEXT,(LPTSTR)szFormat,sizeof(szFormat)/sizeof(TCHAR)); + wvsprintf((LPTSTR)szBuf, (LPTSTR)szFormat, *parglist); + + + SetDlgItemText(hDlg, ID_PU_TEXT, (LPTSTR)szBuf); + return TRUE; + } + case WM_COMMAND: + EndDialog(hDlg, wParam); + return TRUE; + + default: + return FALSE; + } +} + + +/* 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 + * (ID_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 EXPORT FAR CDECL OleUIPromptUser(int nTemplate, HWND hwndParent, ...) +{ + int nRet; + va_list arglist; + LPARAM lParam; + + // + // We want to pass the variable list of arguments to PrompUserDlgProc, + // but we can't just pass arglist because arglist is not always the + // same size as an LPARAM (e.g. on Alpha va_list is a structure). + // So, we pass the a pointer to the arglist instead. + // + + va_start(arglist, hwndParent); + lParam = (LPARAM) &arglist; + + nRet = DialogBoxParam(ghInst, MAKEINTRESOURCE(nTemplate), hwndParent, + PromptUserDlgProc, lParam); + + 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: + * + */ +BOOL CALLBACK EXPORT 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(GMEM_MOVEABLE|GMEM_ZEROINIT,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) { + *lplpUL = (LPUPDATELINKS)lParam; + SetWindowText(hDlg, (*lplpUL)->lpszTitle); + SetTimer(hDlg, 1, UPDATELINKS_STARTDELAY, NULL); + return TRUE; + } else { + PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC,0L); + return FALSE; + } + } + + case WM_TIMER: + KillTimer(hDlg, 1); + gh = GetProp(hDlg, STRUCTUREPROP); + + if (NULL!=gh) { + // gh was locked previously, lock and unlock to get lplpUL + lplpUL = 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->lpVtbl->GetNextLink( + lpUL->lpOleUILinkCntr, + 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->lpVtbl->GetLinkUpdateOptions( + lpUL->lpOleUILinkCntr, + lpUL->dwLink, + (LPDWORD)&dwUpdateOpt + ); + + if ((hErr == NOERROR) && (dwUpdateOpt == OLEUPDATE_ALWAYS)) { + + hErr = lpUL->lpOleUILinkCntr->lpVtbl->UpdateLink( + lpUL->lpOleUILinkCntr, + lpUL->dwLink, + FALSE, // fMessage + FALSE // ignored + ); + lpUL->fError |= (hErr != NOERROR); + lpUL->cUpdated++; + + nPercent = lpUL->cUpdated * 100 / lpUL->cLinks; + if (nPercent <= 100) { // do NOT advance % beyond 100% + // update percentage + wsprintf((LPTSTR)szPercent, TEXT("%d%%"), nPercent); + SetDlgItemText(hDlg, ID_PU_PERCENT, (LPTSTR)szPercent); + + // update indicator + hwndMeter = GetDlgItem(hDlg, ID_PU_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); + } + } + } + + 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; + } + + default: + return FALSE; + } +} + + +/* OleUIUpdateLink + * --------------- + * + * 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 + * FALSE otherwise + */ +STDAPI_(BOOL) OleUIUpdateLinks(LPOLEUILINKCONTAINER lpOleUILinkCntr, HWND hwndParent, LPTSTR lpszTitle, int cLinks) +{ + LPUPDATELINKS lpUL = (LPUPDATELINKS)OleStdMalloc(sizeof(UPDATELINKS)); + BOOL fError; + + 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(ghInst, MAKEINTRESOURCE(IDD_UPDATELINKS), + hwndParent, UpdateLinksDlgProc, (LPARAM)lpUL); + + fError = lpUL->fError; + OleStdFree((LPVOID)lpUL); + + return !fError; +} diff --git a/private/oleutest/letest/ole2ui/ole2ui.h b/private/oleutest/letest/ole2ui/ole2ui.h new file mode 100644 index 000000000..9990c79e0 --- /dev/null +++ b/private/oleutest/letest/ole2ui/ole2ui.h @@ -0,0 +1,958 @@ +/* + * OLE2UI.H + * + * Published definitions, structures, types, and function prototypes for the + * OLE 2.0 User Interface support library. + * + * Copyright (c)1993 Microsoft Corporation, All Rights Reserved + */ + + +#ifndef _OLE2UI_H_ +#define _OLE2UI_H_ + +#undef UNICODE +#undef _UNICODE + +#if DBG == 1 +// Lazy way to avoid going through all the files and changing to the +// new standard. +#define _DEBUG 1 +#endif // DBG == 1 + +#ifndef RC_INVOKED +#pragma message ("Including OLE2UI.H from " __FILE__) +#endif //RC_INVOKED + +// Macro to ensure strings to be UNICODEd in OLE +#ifdef UNICODE + #define OLETEXT(quote) TEXT(quote) +#else + #define OLETEXT(quote) L##quote +#endif + +#if !defined(__cplusplus) && !defined( __TURBOC__) +// #define NONAMELESSUNION // use strict ANSI standard (for DVOBJ.H) +#endif + +#ifndef INC_OLE2 + #define INC_OLE2 +#endif +#include <windows.h> +#include <shellapi.h> +#include <ole2.h> +#include <string.h> +#include <dlgs.h> //For fileopen dlg; standard include +#include "olestd.h" +#include <olethunk.h> + +#ifdef __TURBOC__ +#define _getcwd getcwd +#define _itoa itoa +#define __max max +#define _find_t find_t +#endif // __TURBOC__ + +#ifdef WIN32 + #define _fmemset memset + #define _fmemcpy memcpy + #define _fmemcmp memcmp + + #ifdef UNICODE + // UNICODE stuff + #define _fstrcpy wcscpy + #define _fstrlen wcslen + #define _fstrrchr wcschr + #define _fstrtok wcstok + + #define _fstrchr wcscpy + #define _fstrcpy wcscpy + + // BUGBUG32: isspace function does not seem to work properly + // + // XXXXX + // create a wide character image to match the ANSI isspace + #undef isspace + #undef iswspace + #define iswspace(j) (j==TEXT(' ') || j==TEXT('\t') || j==TEXT('\n')) + #define isspace(j) (j==' ' || j=='\t' || j=='\n') + + #else + // Win32 doesn't support the following _fstrxxx functions + #define _fstrcpy strcpy + #define _fstrlen strlen + #define _fstrrchr strrchr + #define _fstrtok strtok + + #define _fstrchr strchr + #define _fstrcpy strcpy + + #endif // UNICODE + +#endif // WIN32 + +#if !defined( EXPORT ) +#ifdef WIN32 +#define EXPORT +#else +#define EXPORT __export +#endif // WIN32 +#endif // !EXPORT + +/* + * Initialization / Uninitialization routines. OleUIInitialize + * must be called prior to using any functions in OLE2UI, and OleUIUnInitialize + * must be called before you app shuts down and when you are done using the + * library. + * + * NOTE: If you are using the DLL version of this library, these functions + * are automatically called in the DLL's LibMain and WEP, so you should + * not call them directly from your application. + */ + +// Backward compatibility with older library +#define OleUIUninitialize OleUIUnInitialize + +STDAPI_(BOOL) OleUIInitialize(HINSTANCE hInstance, + HINSTANCE hPrevInst, + LPTSTR lpszClassIconBox, + LPTSTR lpszClassResImage); +STDAPI_(BOOL) OleUIUninitialize(void); + +//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_FILEOPEN 1005 +#define IDD_BUSY 1006 +#define IDD_UPDATELINKS 1007 +#define IDD_CANNOTUPDATELINK 1008 +#define IDD_CHANGESOURCE 1009 +#define IDD_INSERTFILEBROWSE 1010 +#define IDD_CHANGEICONBROWSE 1011 + +// The following Dialogs are message dialogs used by OleUIPromptUser API +#define IDD_LINKSOURCEUNAVAILABLE 1020 +#define IDD_SERVERNOTREG 1021 +#define IDD_LINKTYPECHANGED 1022 +#define IDD_SERVERNOTFOUND 1023 +#define IDD_OUTOFMEMORY 1024 + +// Stringtable identifers +#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 +// def. icon label (usu. "Document") +#define IDS_DEFICONLABEL 310 +#define IDS_OLE2UIPASTELINKEDTYPE 311 + + +#define IDS_FILTERS 64 +#define IDS_ICONFILTERS 65 +#define IDS_BROWSE 66 + +//Resource identifiers for bitmaps +#define IDB_RESULTSEGA 10 +#define IDB_RESULTSVGA 11 +#define IDB_RESULTSHIRESVGA 12 + + +//Missing from windows.h +#ifndef PVOID +typedef VOID *PVOID; +#endif + + +//Hook type used in all structures. +typedef UINT (CALLBACK *LPFNOLEUIHOOK)(HWND, UINT, WPARAM, LPARAM); + + +//Strings for registered messages +#define SZOLEUI_MSG_HELP TEXT("OLEUI_MSG_HELP") +#define SZOLEUI_MSG_ENDDIALOG TEXT("OLEUI_MSG_ENDDIALOG") +#define SZOLEUI_MSG_BROWSE TEXT("OLEUI_MSG_BROWSE") +#define SZOLEUI_MSG_CHANGEICON TEXT("OLEUI_MSG_CHANGEICON") +#define SZOLEUI_MSG_CLOSEBUSYDIALOG TEXT("OLEUI_MSG_CLOSEBUSYDIALOG") +#define SZOLEUI_MSG_FILEOKSTRING TEXT("OLEUI_MSG_FILEOKSTRING") + +//Standard error definitions +#define OLEUI_FALSE 0 +#define OLEUI_SUCCESS 1 //No error, same as OLEUI_OK +#define OLEUI_OK 1 //OK button pressed +#define OLEUI_CANCEL 2 //Cancel button pressed + +#define OLEUI_ERR_STANDARDMIN 100 +#define OLEUI_ERR_STRUCTURENULL 101 //Standard field validation +#define OLEUI_ERR_STRUCTUREINVALID 102 +#define OLEUI_ERR_CBSTRUCTINCORRECT 103 +#define OLEUI_ERR_HWNDOWNERINVALID 104 +#define OLEUI_ERR_LPSZCAPTIONINVALID 105 +#define OLEUI_ERR_LPFNHOOKINVALID 106 +#define OLEUI_ERR_HINSTANCEINVALID 107 +#define OLEUI_ERR_LPSZTEMPLATEINVALID 108 +#define OLEUI_ERR_HRESOURCEINVALID 109 + +#define OLEUI_ERR_FINDTEMPLATEFAILURE 110 //Initialization errors +#define OLEUI_ERR_LOADTEMPLATEFAILURE 111 +#define OLEUI_ERR_DIALOGFAILURE 112 +#define OLEUI_ERR_LOCALMEMALLOC 113 +#define OLEUI_ERR_GLOBALMEMALLOC 114 +#define OLEUI_ERR_LOADSTRING 115 + +#define OLEUI_ERR_STANDARDMAX 116 //Start here for specific errors. + + + +//Help Button Identifier +#define ID_OLEUIHELP 99 + +// Help button for fileopen.dlg (need this for resizing) 1038 is pshHelp +#undef IDHELP +#define IDHELP 1038 + +// Static text control (use this instead of -1 so things work correctly for +// localization +#define ID_STATIC 98 + +/****************** + * The followings are defined in the fashion that the first + * definition is the number of CHARACTERS, while the second one (XXX_SIZE) + * is the number of bytes. The number of bytes definition is needed for + * UNICODE handling purpose. + * Also, please note the prefix of variables cch means that it is the + * count of characters and cb means the count of bytes. + ******************/ + +//Maximum key size we read from the RegDB. +#define OLEUI_CCHKEYMAX 256 // make any changes to this in geticon.c too +#define OLEUI_CCHKEYMAX_SIZE OLEUI_CCHKEYMAX*sizeof(TCHAR) // # of bytes + +//Maximum verb length and length of Object menu +#define OLEUI_CCHVERBMAX 32 +#define OLEUI_CCHVERBMAX_SIZE OLEUI_CCHVERBMAX*sizeof(TCHAR) // # of bytes +#define OLEUI_OBJECTMENUMAX 256 +#define OLEUI_OBJECTMENUMAX_SIZE OLEUI_OBJECTMENUMAX*sizeof(TCHAR) // # of bytes + +//Maximum MS-DOS pathname. +#define OLEUI_CCHPATHMAX 256 // make any changes to this in geticon.c too +#define OLEUI_CCHPATHMAX_SIZE OLEUI_CCHPATHMAX*sizeof(TCHAR) // # of bytes +#define OLEUI_CCHFILEMAX 13 +#define OLEUI_CCHFILEMAX_SIZE OLEUI_CCHFILEMAX*sizeof(TCHAR) // # of bytes + +//Icon label length +#define OLEUI_CCHLABELMAX 40 // make any changes to this in geticon.c too +#define OLEUI_CCHLABELMAX_SIZE OLEUI_CCHLABELMAX*sizeof(TCHAR) // # of bytes + +//Length of the CLSID string +#define OLEUI_CCHCLSIDSTRING 39 +#define OLEUI_CCHCLSIDSTRING_SIZE OLEUI_CCHCLSIDSTRING*sizeof(TCHAR) // # of bytes + + +/* + * What follows here are first function prototypes for general utility + * functions, then sections laid out by dialog. Each dialog section + * defines the dialog structure, the API prototype, flags for the dwFlags + * field, the dialog-specific error values, and dialog control IDs (for + * hooks and custom templates. + */ + + +//Miscellaneous utility functions. +STDAPI_(BOOL) OleUIAddVerbMenu(LPOLEOBJECT lpOleObj, + LPTSTR lpszShortType, + HMENU hMenu, + UINT uPos, + UINT uIDVerbMin, + UINT uIDVerbMax, + BOOL bAddConvert, + UINT idConvert, + HMENU FAR *lphMenu); + +//Metafile utility functions +#ifndef WIN32 +STDAPI_(HGLOBAL) OleUIMetafilePictFromIconAndLabel(HICON, LPTSTR, LPTSTR, UINT); +#endif +STDAPI_(void) OleUIMetafilePictIconFree(HGLOBAL); +STDAPI_(BOOL) OleUIMetafilePictIconDraw(HDC, LPRECT, HGLOBAL, BOOL); +STDAPI_(UINT) OleUIMetafilePictExtractLabel(HGLOBAL, LPTSTR, UINT, LPDWORD); +STDAPI_(HICON) OleUIMetafilePictExtractIcon(HGLOBAL); +STDAPI_(BOOL) OleUIMetafilePictExtractIconSource(HGLOBAL,LPTSTR,UINT FAR *); + + + + + +/************************************************************************* +** INSERT OBJECT DIALOG +*************************************************************************/ + + +typedef struct tagOLEUIINSERTOBJECT + { + //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 OLEUIINSERTOBJECT. All are IN-OUT unless otherwise spec. + CLSID clsid; //Return space for class ID + LPTSTR lpszFile; //Filename for inserts or links + UINT cchFile; //Size of lpszFile buffer: OLEUI_CCHPATHMAX + UINT cClsidExclude; //IN only: CLSIDs in lpClsidExclude + LPCLSID lpClsidExclude; //List of CLSIDs to exclude from listing. + + //Specific to create objects if flags say so + IID iid; //Requested interface on creation. + DWORD oleRender; //Rendering option + LPFORMATETC lpFormatEtc; //Desired format + LPOLECLIENTSITE lpIOleClientSite; //Site to be use for the object. + LPSTORAGE lpIStorage; //Storage used for the object + LPVOID FAR *ppvObj; //Where the object is returned. + SCODE sc; //Result of creation calls. + HGLOBAL hMetaPict; //OUT: METAFILEPICT containing iconic aspect. + //IFF we couldn't stuff it in the cache. + } OLEUIINSERTOBJECT, *POLEUIINSERTOBJECT, FAR *LPOLEUIINSERTOBJECT; + +//API prototype +STDAPI_(UINT) OleUIInsertObject(LPOLEUIINSERTOBJECT); + + +//Insert Object flags +#define IOF_SHOWHELP 0x00000001L +#define IOF_SELECTCREATENEW 0x00000002L +#define IOF_SELECTCREATEFROMFILE 0x00000004L +#define IOF_CHECKLINK 0x00000008L +#define IOF_CHECKDISPLAYASICON 0x00000010L +#define IOF_CREATENEWOBJECT 0x00000020L +#define IOF_CREATEFILEOBJECT 0x00000040L +#define IOF_CREATELINKOBJECT 0x00000080L +#define IOF_DISABLELINK 0x00000100L +#define IOF_VERIFYSERVERSEXIST 0x00000200L +#define IOF_DISABLEDISPLAYASICON 0x00000400L + + +//Insert Object specific error codes +#define OLEUI_IOERR_LPSZFILEINVALID (OLEUI_ERR_STANDARDMAX+0) +#define OLEUI_IOERR_LPSZLABELINVALID (OLEUI_ERR_STANDARDMAX+1) +#define OLEUI_IOERR_HICONINVALID (OLEUI_ERR_STANDARDMAX+2) +#define OLEUI_IOERR_LPFORMATETCINVALID (OLEUI_ERR_STANDARDMAX+3) +#define OLEUI_IOERR_PPVOBJINVALID (OLEUI_ERR_STANDARDMAX+4) +#define OLEUI_IOERR_LPIOLECLIENTSITEINVALID (OLEUI_ERR_STANDARDMAX+5) +#define OLEUI_IOERR_LPISTORAGEINVALID (OLEUI_ERR_STANDARDMAX+6) +#define OLEUI_IOERR_SCODEHASERROR (OLEUI_ERR_STANDARDMAX+7) +#define OLEUI_IOERR_LPCLSIDEXCLUDEINVALID (OLEUI_ERR_STANDARDMAX+8) +#define OLEUI_IOERR_CCHFILEINVALID (OLEUI_ERR_STANDARDMAX+9) + + +//Insert Object Dialog identifiers +#define ID_IO_CREATENEW 2100 +#define ID_IO_CREATEFROMFILE 2101 +#define ID_IO_LINKFILE 2102 +#define ID_IO_OBJECTTYPELIST 2103 +#define ID_IO_DISPLAYASICON 2104 +#define ID_IO_CHANGEICON 2105 +#define ID_IO_FILE 2106 +#define ID_IO_FILEDISPLAY 2107 +#define ID_IO_RESULTIMAGE 2108 +#define ID_IO_RESULTTEXT 2109 +#define ID_IO_ICONDISPLAY 2110 +#define ID_IO_OBJECTTYPETEXT 2111 +#define ID_IO_FILETEXT 2112 +#define ID_IO_FILETYPE 2113 + +// Strings in OLE2UI resources +#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 + +/************************************************************************* +** PASTE SPECIAL DIALOG +*************************************************************************/ + +// Maximum number of link types +#define PS_MAXLINKTYPES 8 + +//NOTE: OLEUIPASTEENTRY and OLEUIPASTEFLAG structs are defined in OLESTD.H + +typedef struct tagOLEUIPASTESPECIAL + { + //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 OLEUIPASTESPECIAL. + + //IN fields + LPDATAOBJECT lpSrcDataObj; //Source IDataObject* (on the + // clipboard) for data to paste + + LPOLEUIPASTEENTRY arrPasteEntries; //OLEUIPASTEENTRY array which + // specifies acceptable formats. See + // OLEUIPASTEENTRY for more info. + int cPasteEntries; //No. of OLEUIPASTEENTRY array entries + + UINT FAR *arrLinkTypes; //List of link types that are + // acceptable. Link types are referred + // to using OLEUIPASTEFLAGS in + // arrPasteEntries + int cLinkTypes; //Number of link types + UINT cClsidExclude; //Number of CLSIDs in lpClsidExclude + LPCLSID lpClsidExclude; //List of CLSIDs to exclude from list. + + //OUT fields + int nSelectedIndex; //Index of arrPasteEntries[] that the + // user selected + BOOL fLink; //Indicates if Paste or Paste Link was + // selected by the user + HGLOBAL hMetaPict; //Handle to Metafile containing icon + // and icon title selected by the user + // Use the Metafile utility functions + // defined in this header to + // manipulate hMetaPict + SIZEL sizel; // size of object/link in its source + // if the display aspect chosen by + // the user matches the aspect + // displayed in the source. if + // different aspect is chosen then + // sizel.cx=sizel.cy=0 is returned. + // sizel displayed in source is + // retrieved from the + // ObjectDescriptor if fLink is FALSE + // LinkSrcDescriptor if fLink is TRUE + } OLEUIPASTESPECIAL, *POLEUIPASTESPECIAL, FAR *LPOLEUIPASTESPECIAL; + + +//API to bring up PasteSpecial dialog +STDAPI_(UINT) OleUIPasteSpecial(LPOLEUIPASTESPECIAL); + + +//Paste Special flags +// Show Help button. IN flag. +#define PSF_SHOWHELP 0x00000001L + +//Select Paste radio button at dialog startup. This is the default if +// PSF_SELECTPASTE or PSF_SELECTPASTELINK are not specified. Also specifies +// state of button on dialog termination. IN/OUT flag. +#define PSF_SELECTPASTE 0x00000002L + +//Select PasteLink radio button at dialog startup. Also specifies state of +// button on dialog termination. IN/OUT flag. +#define PSF_SELECTPASTELINK 0x00000004L + +//Specfies if DisplayAsIcon button was checked on dialog termination. OUT flag +#define PSF_CHECKDISPLAYASICON 0x00000008L +#define PSF_DISABLEDISPLAYASICON 0x00000010L + + +//Paste Special specific error codes +#define OLEUI_IOERR_SRCDATAOBJECTINVALID (OLEUI_ERR_STANDARDMAX+0) +#define OLEUI_IOERR_ARRPASTEENTRIESINVALID (OLEUI_ERR_STANDARDMAX+1) +#define OLEUI_IOERR_ARRLINKTYPESINVALID (OLEUI_ERR_STANDARDMAX+2) +#define OLEUI_PSERR_CLIPBOARDCHANGED (OLEUI_ERR_STANDARDMAX+3) + +//Paste Special Dialog identifiers +#define ID_PS_PASTE 500 +#define ID_PS_PASTELINK 501 +#define ID_PS_SOURCETEXT 502 +#define ID_PS_PASTELIST 503 +#define ID_PS_PASTELINKLIST 504 +#define ID_PS_DISPLAYLIST 505 +#define ID_PS_DISPLAYASICON 506 +#define ID_PS_ICONDISPLAY 507 +#define ID_PS_CHANGEICON 508 +#define ID_PS_RESULTIMAGE 509 +#define ID_PS_RESULTTEXT 510 +#define ID_PS_RESULTGROUP 511 +#define ID_PS_STXSOURCE 512 +#define ID_PS_STXAS 513 + +// Paste Special String IDs +#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 + + +/************************************************************************* +** EDIT LINKS DIALOG +*************************************************************************/ + + + +/* IOleUILinkContainer Interface +** ----------------------------- +** This interface must be implemented by container applications that +** want to use the EditLinks dialog. the EditLinks dialog calls back +** to the container app to perform the OLE functions to manipulate +** the links within the container. +*/ + +#define LPOLEUILINKCONTAINER IOleUILinkContainer FAR* + +#undef INTERFACE +#define INTERFACE IOleUILinkContainer + +DECLARE_INTERFACE_(IOleUILinkContainer, IUnknown) +{ + //*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + STDMETHOD_(DWORD,GetNextLink) (THIS_ DWORD dwLink) PURE; + STDMETHOD(SetLinkUpdateOptions) (THIS_ DWORD dwLink, DWORD dwUpdateOpt) PURE; + STDMETHOD(GetLinkUpdateOptions) (THIS_ DWORD dwLink, DWORD FAR* lpdwUpdateOpt) PURE; + STDMETHOD(SetLinkSource) (THIS_ + DWORD dwLink, + LPTSTR lpszDisplayName, + ULONG lenFileName, + ULONG FAR* pchEaten, + BOOL fValidateSource) PURE; + STDMETHOD(GetLinkSource) (THIS_ + DWORD dwLink, + LPTSTR FAR* lplpszDisplayName, + ULONG FAR* lplenFileName, + LPTSTR FAR* lplpszFullLinkType, + LPTSTR FAR* lplpszShortLinkType, + BOOL FAR* lpfSourceAvailable, + BOOL FAR* lpfIsSelected) PURE; + STDMETHOD(OpenLinkSource) (THIS_ DWORD dwLink) PURE; + STDMETHOD(UpdateLink) (THIS_ + DWORD dwLink, + BOOL fErrorMessage, + BOOL fErrorAction) PURE; + STDMETHOD(CancelLink) (THIS_ DWORD dwLink) PURE; +}; + + +typedef struct tagOLEUIEDITLINKS + { + //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. + + LPOLEUILINKCONTAINER lpOleUILinkContainer; //IN: Interface to manipulate + //links in the container + } OLEUIEDITLINKS, *POLEUIEDITLINKS, FAR *LPOLEUIEDITLINKS; + + +//API Prototype +STDAPI_(UINT) OleUIEditLinks(LPOLEUIEDITLINKS); + + +// Edit Links flags +#define ELF_SHOWHELP 0x00000001L +#define ELF_DISABLEUPDATENOW 0x00000002L +#define ELF_DISABLEOPENSOURCE 0x00000004L +#define ELF_DISABLECHANGESOURCE 0x00000008L +#define ELF_DISABLECANCELLINK 0x00000010L + +// Edit Links Dialog identifiers +#define ID_EL_CHANGESOURCE 201 +#define ID_EL_AUTOMATIC 202 +#define ID_EL_CLOSE 208 +#define ID_EL_CANCELLINK 209 +#define ID_EL_UPDATENOW 210 +#define ID_EL_OPENSOURCE 211 +#define ID_EL_MANUAL 212 +#define ID_EL_LINKSOURCE 216 +#define ID_EL_LINKTYPE 217 +#define ID_EL_UPDATE 218 +#define ID_EL_NULL -1 +#define ID_EL_LINKSLISTBOX 206 +#define ID_EL_COL1 220 +#define ID_EL_COL2 221 +#define ID_EL_COL3 222 + + + +/************************************************************************* +** CHANGE ICON DIALOG +*************************************************************************/ + +typedef struct tagOLEUICHANGEICON + { + //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 OLEUICHANGEICON. All are IN-OUT unless otherwise spec. + HGLOBAL hMetaPict; //Current and final image. Source of the + //icon is embedded in the metafile itself. + CLSID clsid; //IN only: class used to get Default icon + TCHAR szIconExe[OLEUI_CCHPATHMAX]; + int cchIconExe; + } OLEUICHANGEICON, *POLEUICHANGEICON, FAR *LPOLEUICHANGEICON; + + +//API prototype +STDAPI_(UINT) OleUIChangeIcon(LPOLEUICHANGEICON); + + +//Change Icon flags +#define CIF_SHOWHELP 0x00000001L +#define CIF_SELECTCURRENT 0x00000002L +#define CIF_SELECTDEFAULT 0x00000004L +#define CIF_SELECTFROMFILE 0x00000008L +#define CIF_USEICONEXE 0x0000000aL + + +//Change Icon specific error codes +#define OLEUI_CIERR_MUSTHAVECLSID (OLEUI_ERR_STANDARDMAX+0) +#define OLEUI_CIERR_MUSTHAVECURRENTMETAFILE (OLEUI_ERR_STANDARDMAX+1) +#define OLEUI_CIERR_SZICONEXEINVALID (OLEUI_ERR_STANDARDMAX+2) + + +//Change Icon Dialog identifiers +#define ID_GROUP 120 +#define ID_CURRENT 121 +#define ID_CURRENTICON 122 +#define ID_DEFAULT 123 +#define ID_DEFAULTICON 124 +#define ID_FROMFILE 125 +#define ID_FROMFILEEDIT 126 +#define ID_ICONLIST 127 +#define ID_LABEL 128 +#define ID_LABELEDIT 129 +#define ID_BROWSE 130 +#define ID_RESULTICON 132 +#define ID_RESULTLABEL 133 + +// Stringtable defines for Change Icon +#define IDS_CINOICONSINFILE 288 +#define IDS_CIINVALIDFILE 289 +#define IDS_CIFILEACCESS 290 +#define IDS_CIFILESHARE 291 +#define IDS_CIFILEOPENFAIL 292 + + + +/************************************************************************* +** CONVERT DIALOG +*************************************************************************/ + +typedef struct tagOLEUICONVERT + { + //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 OLEUICONVERT. All are IN-OUT unless otherwise spec. + CLSID clsid; //Class ID sent in to dialog: IN only + CLSID clsidConvertDefault; //Class ID to use as convert default: IN only + CLSID clsidActivateDefault; //Class ID to use as activate default: IN only + + CLSID clsidNew; //Selected Class ID: OUT only + DWORD dvAspect; //IN-OUT, either DVASPECT_CONTENT or + //DVASPECT_ICON + WORD wFormat; //Original data format + BOOL fIsLinkedObject; //IN only; true if object is linked + HGLOBAL hMetaPict; //IN-OUT: METAFILEPICT containing iconic aspect. + LPTSTR lpszUserType; //IN-OUT: user type name of original class. + // We'll do lookup if it's NULL. + // This gets freed on exit. + BOOL fObjectsIconChanged; // OUT; TRUE if ChangeIcon was called (and not cancelled) + LPTSTR lpszDefLabel; //IN-OUT: default label to use for icon. + // if NULL, the short user type name + // will be used. if the object is a + // link, the caller should pass the + // DisplayName of the link source + // This gets freed on exit. + + UINT cClsidExclude; //IN: No. of CLSIDs in lpClsidExclude + LPCLSID lpClsidExclude; //IN: List of CLSIDs to exclude from list + } OLEUICONVERT, *POLEUICONVERT, FAR *LPOLEUICONVERT; + + +//API prototype +STDAPI_(UINT) OleUIConvert(LPOLEUICONVERT); + +// Determine if there is at least one class that can Convert or ActivateAs +// the given clsid. +STDAPI_(BOOL) OleUICanConvertOrActivateAs( + REFCLSID rClsid, + BOOL fIsLinkedObject, + WORD wFormat +); + +//Convert Dialog flags + +// IN only: Shows "HELP" button +#define CF_SHOWHELPBUTTON 0x00000001L + +// IN only: lets you set the convert default object - the one that is +// selected as default in the convert listbox. +#define CF_SETCONVERTDEFAULT 0x00000002L + + +// IN only: lets you set the activate default object - the one that is +// selected as default in the activate listbox. + +#define CF_SETACTIVATEDEFAULT 0x00000004L + + +// IN/OUT: Selects the "Convert To" radio button, is set on exit if +// this button was selected +#define CF_SELECTCONVERTTO 0x00000008L + +// IN/OUT: Selects the "Activate As" radio button, is set on exit if +// this button was selected +#define CF_SELECTACTIVATEAS 0x00000010L +#define CF_DISABLEDISPLAYASICON 0x00000020L +#define CF_DISABLEACTIVATEAS 0x00000040L + + +//Convert specific error codes +#define OLEUI_CTERR_CLASSIDINVALID (OLEUI_ERR_STANDARDMAX+1) +#define OLEUI_CTERR_DVASPECTINVALID (OLEUI_ERR_STANDARDMAX+2) +#define OLEUI_CTERR_CBFORMATINVALID (OLEUI_ERR_STANDARDMAX+3) +#define OLEUI_CTERR_HMETAPICTINVALID (OLEUI_ERR_STANDARDMAX+4) +#define OLEUI_CTERR_STRINGINVALID (OLEUI_ERR_STANDARDMAX+5) + + +//Convert Dialog identifiers +#define IDCV_OBJECTTYPE 150 +#define IDCV_DISPLAYASICON 152 +#define IDCV_CHANGEICON 153 +#define IDCV_ACTIVATELIST 154 +#define IDCV_CONVERTTO 155 +#define IDCV_ACTIVATEAS 156 +#define IDCV_RESULTTEXT 157 +#define IDCV_CONVERTLIST 158 +#define IDCV_ICON 159 +#define IDCV_ICONLABEL1 160 +#define IDCV_ICONLABEL2 161 +#define IDCV_STXCURTYPE 162 +#define IDCV_GRPRESULT 163 +#define IDCV_STXCONVERTTO 164 + +// String IDs for Convert dialog +#define IDS_CVRESULTCONVERTLINK 500 +#define IDS_CVRESULTCONVERTTO 501 +#define IDS_CVRESULTNOCHANGE 502 +#define IDS_CVRESULTDISPLAYASICON 503 +#define IDS_CVRESULTACTIVATEAS 504 +#define IDS_CVRESULTACTIVATEDIFF 505 + + +/************************************************************************* +** BUSY DIALOG +*************************************************************************/ + +typedef struct tagOLEUIBUSY + { + //These IN fields are standard across all OLEUI dialog functions. + DWORD cbStruct; //Structure Size + DWORD dwFlags; //IN-OUT: Flags ** NOTE ** this dialog has no 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 OLEUIBUSY. + HTASK hTask; //IN: HTask which is blocking + HWND FAR * lphWndDialog; //IN: Dialog's HWND is placed here + } OLEUIBUSY, *POLEUIBUSY, FAR *LPOLEUIBUSY; + +//API prototype +STDAPI_(UINT) OleUIBusy(LPOLEUIBUSY); + +// Flags for this dialog + +// IN only: Disables "Cancel" button +#define BZ_DISABLECANCELBUTTON 0x00000001L + +// IN only: Disables "Switch To..." button +#define BZ_DISABLESWITCHTOBUTTON 0x00000002L + +// IN only: Disables "Retry" button +#define BZ_DISABLERETRYBUTTON 0x00000004L + +// IN only: Generates a "Not Responding" dialog as opposed to the +// "Busy" dialog. The wording in the text is slightly different, and +// the "Cancel" button is grayed out if you set this flag. +#define BZ_NOTRESPONDINGDIALOG 0x00000008L + +// Busy specific error/return codes +#define OLEUI_BZERR_HTASKINVALID (OLEUI_ERR_STANDARDMAX+0) + +// SWITCHTOSELECTED is returned when user hit "switch to" +#define OLEUI_BZ_SWITCHTOSELECTED (OLEUI_ERR_STANDARDMAX+1) + +// RETRYSELECTED is returned when user hit "retry" +#define OLEUI_BZ_RETRYSELECTED (OLEUI_ERR_STANDARDMAX+2) + +// CALLUNBLOCKED is returned when call has been unblocked +#define OLEUI_BZ_CALLUNBLOCKED (OLEUI_ERR_STANDARDMAX+3) + +// Busy dialog identifiers +#define IDBZ_RETRY 600 +#define IDBZ_ICON 601 +#define IDBZ_MESSAGE1 602 +#define IDBZ_SWITCHTO 604 + +// Busy dialog stringtable defines +#define IDS_BZRESULTTEXTBUSY 601 +#define IDS_BZRESULTTEXTNOTRESPONDING 602 + +// Links dialog stringtable defines +#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 + + +/************************************************************************* +** PROMPT USER DIALOGS +*************************************************************************/ +#define ID_PU_LINKS 900 +#define ID_PU_TEXT 901 +#define ID_PU_CONVERT 902 +#define ID_PU_BROWSE 904 +#define ID_PU_METER 905 +#define ID_PU_PERCENT 906 +#define ID_PU_STOP 907 + +// used for -1 ids in dialogs: +#define ID_DUMMY 999 + +/* inside ole2ui.c */ +#ifdef __cplusplus +extern "C" +#endif +int EXPORT FAR CDECL OleUIPromptUser(int nTemplate, HWND hwndParent, ...); + +#define UPDATELINKS_STARTDELAY 2000 // Delay before 1st link updates + // to give the user a chance to + // dismiss the dialog before any + // links update. + +STDAPI_(BOOL) OleUIUpdateLinks( + LPOLEUILINKCONTAINER lpOleUILinkCntr, + HWND hwndParent, + LPTSTR lpszTitle, + int cLinks); + + +/************************************************************************* +** OLE OBJECT FEEDBACK EFFECTS +*************************************************************************/ + +#define OLEUI_HANDLES_USEINVERSE 0x00000001L +#define OLEUI_HANDLES_NOBORDER 0x00000002L +#define OLEUI_HANDLES_INSIDE 0x00000004L +#define OLEUI_HANDLES_OUTSIDE 0x00000008L + + +#define OLEUI_SHADE_FULLRECT 1 +#define OLEUI_SHADE_BORDERIN 2 +#define OLEUI_SHADE_BORDEROUT 3 + +/* objfdbk.c function prototypes */ +STDAPI_(void) OleUIDrawHandles(LPRECT lpRect, HDC hdc, DWORD dwFlags, UINT cSize, BOOL fDraw); +STDAPI_(void) OleUIDrawShading(LPRECT lpRect, HDC hdc, DWORD dwFlags, UINT cWidth); +STDAPI_(void) OleUIShowObject(LPCRECT lprc, HDC hdc, BOOL fIsLink); + + +/************************************************************************* +** Hatch window definitions and prototypes ** +*************************************************************************/ +#define DEFAULT_HATCHBORDER_WIDTH 4 + +STDAPI_(BOOL) RegisterHatchWindowClass(HINSTANCE hInst); +STDAPI_(HWND) CreateHatchWindow(HWND hWndParent, HINSTANCE hInst); +STDAPI_(UINT) GetHatchWidth(HWND hWndHatch); +STDAPI_(void) GetHatchRect(HWND hWndHatch, LPRECT lpHatchRect); +STDAPI_(void) SetHatchRect(HWND hWndHatch, LPRECT lprcHatchRect); +STDAPI_(void) SetHatchWindowSize( + HWND hWndHatch, + LPRECT lprcIPObjRect, + LPRECT lprcClipRect, + LPPOINT lpptOffset +); + + + +/************************************************************************* +** VERSION VERIFICATION INFORMATION +*************************************************************************/ + +// The following magic number is used to verify that the resources we bind +// to our EXE are the same "version" as the LIB (or DLL) file which +// contains these routines. This is not the same as the Version information +// resource that we place in OLE2UI.RC, this is a special ID that we will +// have compiled in to our EXE. Upon initialization of OLE2UI, we will +// look in our resources for an RCDATA called "VERIFICATION" (see OLE2UI.RC), +// and make sure that the magic number there equals the magic number below. + +#define OLEUI_VERSION_MAGIC 0x4D42 + +#endif //_OLE2UI_H_ diff --git a/private/oleutest/letest/ole2ui/ole2ui.mak b/private/oleutest/letest/ole2ui/ole2ui.mak new file mode 100644 index 000000000..f8308fa23 --- /dev/null +++ b/private/oleutest/letest/ole2ui/ole2ui.mak @@ -0,0 +1,272 @@ +# ============================================================================ +# File: OLE2UI.MAK +# +# NMAKE description file to build STATIC version of OLE2.0 User Interface LIB +# +# Copyright (C) Microsoft Corporation, 1992-1993. All Rights Reserved. +# ============================================================================ +# +# Usage Notes: +# ----------- +# +# This makefile is designed to be used in one step. This makefile does +# NOT use the file called UIMAKE.INI. This makefile builds the OLE2UI.LIB +# library. It is NOT necessary to build custom versions of the static +# library version of OLE2UI. Everyone can use the same OLE2UI.LIB library +# as built by this makefile. +# +# NMAKE -F OLE2UI.MAK +# +# +# The following lists a few of the settings in this makefile file which +# you might change, and what effect those changes might have. For a +# complete listing of all the available options and how they are used, +# see the makefile below. +# +# MODEL=[S|M|C|L] -- The memory model. +# +# ============================================================================ + + +# ---------------------------------------------------------------------------- +# U I M A K E . I N I +# ---------------------------------------------------------------------------- +DOS=1 + +# Make a static library called OLE2UI.LIB +DEBUG=0 +MODEL=M +RESOURCE=RESOURCE + +!ifndef REL_DIR +REL_DIR=c:\ole2samp\release +!endif +!ifndef OLERELDIR +OLEREL_DIR=c:\ole2samp\release +!endif + +!if "$(INSTALL_DIR)"=="" +INSTALL_DIR = $(REL_DIR) +!endif + +# ---------------------------------------------------------------------------- +# O B J E C T F I L E L I S T +# ---------------------------------------------------------------------------- + +UI_COBJS = \ + D^\busy.obj\ + D^\common.obj\ + D^\convert.obj\ + D^\dbgutil.obj\ + D^\drawicon.obj\ + D^\hatch.obj\ + D^\icon.obj\ + D^\iconbox.obj\ + D^\insobj.obj\ + D^\links.obj\ + D^\msgfiltr.obj\ + D^\enumfetc.obj\ + D^\enumstat.obj\ + D^\objfdbk.obj\ + D^\ole2ui.obj\ + D^\olestd.obj\ + D^\targtdev.obj\ + D^\oleutl.obj\ + D^\pastespl.obj\ + D^\regdb.obj\ + D^\resimage.obj\ + D^\utility.obj\ + +UI_NOPCOBJS = \ + D^\geticon.obj\ + D^\dballoc.obj\ + D^\suminfo.obj\ + D^\stdpal.obj\ + +PRECOMPOBJ= $(O)precomp.obj + +PRECOMP=$(O)precomp.pch + +!if ("$(DEBUG)"=="1") +MSG=DEBUG Static LIB Version +LIBNAME=$(MODEL)OLE2UID +CFLAGS=-c -Od -GA2s -W3 -Zpei -A$(MODEL) -D_DEBUG +RFLAGS=-D DEBUG +LFLAGS=/MAP:FULL /CO /LINE /NOD /NOE /SE:300 /NOPACKCODE +UILIBS=mlibcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +OBJ=DEBUGLIB +LIBOBJS = $(UI_COBJS:D^\=DEBUGLIB^\) $(UI_NOPCOBJS:D^\=DEBUGLIB\NOPC^\) + +!else + +MSG=RETAIL Static LIB Version +LIBNAME=$(MODEL)OLE2UI +CFLAGS=-c -Os -GA2s -W3 -Zpe -A$(MODEL) +RFLAGS= +LFLAGS=/MAP:FULL /LINE /NOD /NOE /SE:300 /NOPACKCODE +UILIBS=mlibcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +OBJ=RETAILIB +LIBOBJS = $(UI_COBJS:D^\=RETAILIB^\) $(UI_NOPCOBJS:D^\=RETAILIB\NOPC^\) + +!endif + +!if [if not exist $(OBJ)\*. md $(OBJ) >nul] +!error Object subdirectory $(OBJ)\ could not be created +!endif +!if [if not exist $(OBJ)\NOPC\*. md $(OBJ)\NOPC > nul] +!error non-precompiled header object subdirectory $(OBJ)\NOPC\ could not be created +!endif + +# ---------------------------------------------------------------------------- +# R E S O U R C E L I S T +# ---------------------------------------------------------------------------- +RES = \ + busy.h \ + common.h \ + convert.h \ + edlinks.h \ + geticon.h \ + icon.h \ + iconbox.h \ + insobj.h \ + msgfiltr.h \ + enumfetc.h \ + ole2ui.h \ + pastespl.h \ + resimage.h \ + dballoc.h \ + suminfo.h \ + stdpal.h \ + + +.SUFFIXES: .c .cpp .obj + +O=.\$(OBJ)^\ + +GOAL: PRELUDE $(LIBNAME).LIB + +# ---------------------------------------------------------------------------- +# I N F E R E N C E R U L E S +# ---------------------------------------------------------------------------- + +# compile C file without precompiled headers into object directory\NOPC +# dont compile c files etc for lcoalized builds. +{}.c{$(O)NOPC\}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) + $(CC) -Fo$(O)NOPC\$(@B) $(@B).c +!else + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).c\" -Fo$(O)NOPC\$(@B) $(@B).c +!endif + +# compile C file into object directory +{}.c{$(O)}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).c °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch + $(CC) -Fo$(O)$(@B) $(@B).c +!else + $(CC) $(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch -D_FILE_=\"$(*B).c\" -Fo$(O)$(@B) $(@B).c +!endif + +# compile CPP file without precompiled headers into object directory\NOPC +# dont compile cpp files etc for lcoalized builds. +{}.cpp{$(O)NOPC\}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).cpp °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) + $(CC) -Fo$(O)NOPC\$(@B) $(@B).cpp +!else + $(CC) $(CFLAGS) -D_FILE_=\"$(*B).cpp\" -Fo$(O)NOPC\$(@B) $(@B).cpp +!endif + +# compile CPP file into object directory +{}.cpp{$(O)}.obj: + @echo °°°°°°°°°°°°°°°°°°°°°°°°° Compiling $(@B).cpp °°°°°°°°°°°°°°°°°°°°°°°°° +!ifdef DOS + SET CL=$(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch + $(CC) -Fo$(O)$(@B) $(@B).cpp +!else + $(CC) $(CFLAGS) -Yuole2ui.h -Fp$(O)precomp.pch -D_FILE_=\"$(*B).cpp\" -Fo$(O)$(@B) $(@B).cpp +!endif + + +# ---------------------------------------------------------------------------- +# D E P E N D F I L E C R E A T I O N +# ---------------------------------------------------------------------------- +UI_CFILE = $(UI_COBJS:.obj=.c) $(UI_DLLOBJS:.obj=.c) +UI_NOPCFILE = $(UI_NOPCOBJS:.obj=.c) +DEPEND: nul + @echo Making a NEW dependancy file. + mkdep -p $$(O) -s .obj $(UI_CFILE:D^\=) > tmp.tmp + sed "s/:/: $$(PRECOMP)/g" < tmp.tmp > depend + -del tmp.tmp + mkdep -p $$(O)NOPC\ -s .obj $(UI_NOPCFILE:D^\=) >> depend + mkdep -p $$(O) -s .pch precomp.c >> depend + +# ---------------------------------------------------------------------------- +# W E L C O M E B A N N E R +# ---------------------------------------------------------------------------- +PRELUDE: + @echo ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» + @echo º Makefile for UILibrary º + @echo ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ + @echo $(MSG) +!ifndef SRCTOK + set INCLUDE=$(OLEREL_DIR);$(INCLUDE) + set LIB=$(OLEREL_DIR);$(LIB) +!endif + + +# ---------------------------------------------------------------------------- +# G O A L T A R G E T S +# ---------------------------------------------------------------------------- +!include "depend" + +CLEAN: CleanUp GOAL +CleanUp: + -echo y|del .\$(OBJ)\*.* + -del $(LIBNAME).lib + +$(O)precomp.pch: precomp.c +!ifdef DOS + SET CL=$(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h + $(CC) -Fo$(O)$(@B) precomp.c +!else + $(CC) $(CFLAGS) -Fp$(O)precomp.pch -Ycole2ui.h -D_FILE_=\"precomp.c\" -Fo$(O)$(@B) precomp.c +!endif + +# +# Build .LIB static library +# + +$(LIBNAME).lib: $(LIBOBJS) $(PRECOMPOBJ) + -del $(O)$(LIBNAME).lib + lib @<< +$(O)$(LIBNAME).lib +y +$(PRECOMPOBJ: = +) $(LIBOBJS: = +) + +<< + copy $(O)$(LIBNAME).lib $(LIBNAME).lib + + +# install built library to $(INSTALL_DIR) dir +install: + copy $(LIBNAME).lib $(INSTALL_DIR) + copy ole2ui.h $(INSTALL_DIR) + copy olestd.h $(INSTALL_DIR) + copy msgfiltr.h $(INSTALL_DIR) + copy enumfetc.h $(INSTALL_DIR) + copy uiclass.h $(INSTALL_DIR) + +# EOF ======================================================================== diff --git a/private/oleutest/letest/ole2ui/ole2ui.rc b/private/oleutest/letest/ole2ui/ole2ui.rc new file mode 100644 index 000000000..469608e3d --- /dev/null +++ b/private/oleutest/letest/ole2ui/ole2ui.rc @@ -0,0 +1,65 @@ +/* + * OLE2UI.RC + * + * Icon, menus, strings, and dialogs for the OLE 2.0 UI Support Library. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#undef PURE + +//fix bug when building on daytona 567 +//BUGBUG: this is hacky, we need a better long term solution, the basic +//problem is that the rpc header file makes rc choke and die +#define __RPCNDR_H__ + +#include "ole2ui.h" + +#if defined( IBCLS ) +#define SZCLASSICONBOX IBCLS +#define SZCLASSRESULTIMAGE RICLS +#endif + +/* If "IBCLS" and "RICLS" are NOT defined as command line arguments to the + * RC command, then we assume there is a "uiclass.h" file which defines the + * two symbols "SZCLASSICONBOX" and "SZCLASSRESULTIMAGE". These need to be + * unique strings; they are normally built by composing the name of the + * "LIBNAME" or "APPNAME" with the strings "IBCls" and "RICls" + * respectively. + */ +#if !defined( SZCLASSICONBOX ) +#include "uiclass.h" +#endif + +//Default 'document' icon +//DefIcon ICON default.ico + +//Bitmaps for ResultImage control +IDB_RESULTSEGA BITMAP egares.bmp +IDB_RESULTSVGA BITMAP vgares.bmp +IDB_RESULTSHIRESVGA BITMAP hivgares.bmp + +// Version Verification Resource (see OLE2UI.H) +VERIFICATION RCDATA + BEGIN + OLEUI_VERSION_MAGIC + END + +//Include string tables here. +#include "strings.rc" + +//Include each dialog template here. +#include "insobj.dlg" +#include "icon.dlg" +#include "links.dlg" +#include "pastespl.dlg" +#include "busy.dlg" +#include "convert.dlg" +#include "fileopen.dlg" +#include "prompt.dlg" + +// Only include the version resource if we are compiling the DLL version +#ifdef DLL_VER +//Version Information +#include "OLE2UI.RCV" +#endif diff --git a/private/oleutest/letest/ole2ui/olestd.c b/private/oleutest/letest/ole2ui/olestd.c new file mode 100644 index 000000000..d41a42b8d --- /dev/null +++ b/private/oleutest/letest/ole2ui/olestd.c @@ -0,0 +1,3048 @@ +/************************************************************************* +** +** 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 +** +*************************************************************************/ + +// #define NONAMELESSUNION // use strict ANSI standard (for DVOBJ.H) + +#define STRICT 1 +#include "ole2ui.h" +#include <stdlib.h> +#include <ctype.h> +#include <shellapi.h> +#include "regdb.h" +#include "geticon.h" +#include "common.h" + +OLEDBGDATA + +static TCHAR szAssertMemAlloc[] = TEXT("CoGetMalloc failed"); + +static int IsCloseFormatEtc(FORMATETC FAR* pFetcLeft, FORMATETC FAR* pFetcRight); + + +/* OleStdSetupAdvises +** ------------------ +** Setup the standard View advise required by a standard, +** compound document-oriented container. Such a container relies on +** Ole to manage the presentation of the Ole object. The container +** call IViewObject::Draw to render (display) the object. +** +** This helper routine performs the following tasks: +** setup View advise +** Call IOleObject::SetHostNames +** Call OleSetContainedObject +** +** fCreate should be set to TRUE if the object is being created. if +** an existing object is being loaded, then fCreate should be FALSE. +** if it is a creation situation, then the ADVF_PRIMEFIRST flag is +** used when settinp up the IViewObject::Advise. This will result in +** the immediate sending of the initial picture. +** +** OLE2NOTE: the standard container does NOT need to set up an OLE +** Advise (IOleObject::Advise). this routine does NOT set up an OLE +** Advise (a previous version of this function used to setup this +** advise, but it was not useful). +*/ +STDAPI_(BOOL) OleStdSetupAdvises(LPOLEOBJECT lpOleObject, DWORD dwDrawAspect, + LPTSTR lpszContainerApp, LPTSTR lpszContainerObj, + LPADVISESINK lpAdviseSink, BOOL fCreate) +{ + LPVIEWOBJECT lpViewObject; + HRESULT hrErr; + BOOL fStatus = TRUE; +#if defined( SPECIAL_CONTAINER ) + DWORD dwTemp; +#endif + + hrErr = lpOleObject->lpVtbl->QueryInterface( + lpOleObject, + &IID_IViewObject, + (LPVOID FAR*)&lpViewObject + ); + + /* Setup View advise */ + if (hrErr == NOERROR) { + + OLEDBG_BEGIN2(TEXT("IViewObject::SetAdvise called\r\n")) + lpViewObject->lpVtbl->SetAdvise( + lpViewObject, + dwDrawAspect, + (fCreate ? ADVF_PRIMEFIRST : 0), + lpAdviseSink + ); + OLEDBG_END2 + + OleStdRelease((LPUNKNOWN)lpViewObject); + } else { + fStatus = FALSE; + } + +#if defined( SPECIAL_CONTAINER ) + /* Setup OLE advise. + ** OLE2NOTE: normally containers do NOT need to setup an OLE + ** advise. this advise connection is only useful for the OLE's + ** DefHandler and the OleLink object implementation. some + ** special container's might need to setup this advise for + ** programatic reasons. + ** + ** NOTE: this advise will be torn down automatically by the + ** server when we release the object, therefore we do not need + ** to store the connection id. + */ + OLEDBG_BEGIN2(TEXT("IOleObject::Advise called\r\n")) + hrErr = lpOleObject->lpVtbl->Advise( + lpOleObject, + lpAdviseSink, + (DWORD FAR*)&dwTemp + ); + OLEDBG_END2 + if (hrErr != NOERROR) fStatus = FALSE; +#endif + + /* Setup the host names for the OLE object. */ + OLEDBG_BEGIN2(TEXT("IOleObject::SetHostNames called\r\n")) + + hrErr = CallIOleObjectSetHostNamesA( + lpOleObject, + lpszContainerApp, + lpszContainerObj + ); + + OLEDBG_END2 + + if (hrErr != NOERROR) fStatus = FALSE; + + /* Inform the loadded object's handler/inproc-server that it is in + ** its embedding container's process. + */ + OLEDBG_BEGIN2(TEXT("OleSetContainedObject(TRUE) called\r\n")) + OleSetContainedObject((LPUNKNOWN)lpOleObject, TRUE); + OLEDBG_END2 + + return fStatus; +} + + +/* OleStdSwitchDisplayAspect +** ------------------------- +** Switch the currently cached display aspect between DVASPECT_ICON +** and DVASPECT_CONTENT. +** +** NOTE: when setting up icon aspect, any currently cached content +** cache is discarded and any advise connections for content aspect +** are broken. +** +** RETURNS: +** S_OK -- new display aspect setup successfully +** E_INVALIDARG -- IOleCache interface is NOT supported (this is +** required). +** <other SCODE> -- any SCODE that can be returned by +** IOleCache::Cache method. +** NOTE: if an error occurs then the current display aspect and +** cache contents unchanged. +*/ +STDAPI OleStdSwitchDisplayAspect( + LPOLEOBJECT lpOleObj, + LPDWORD lpdwCurAspect, + DWORD dwNewAspect, + HGLOBAL hMetaPict, + BOOL fDeleteOldAspect, + BOOL fSetupViewAdvise, + LPADVISESINK lpAdviseSink, + BOOL FAR* lpfMustUpdate +) +{ + LPOLECACHE lpOleCache = NULL; + LPVIEWOBJECT lpViewObj = NULL; + LPENUMSTATDATA lpEnumStatData = NULL; + STATDATA StatData; + FORMATETC FmtEtc; + STGMEDIUM Medium; + DWORD dwAdvf; + DWORD dwNewConnection; + DWORD dwOldAspect = *lpdwCurAspect; + HRESULT hrErr; + + if (lpfMustUpdate) + *lpfMustUpdate = FALSE; + + lpOleCache = (LPOLECACHE)OleStdQueryInterface( + (LPUNKNOWN)lpOleObj,&IID_IOleCache); + + // if IOleCache* is NOT available, do nothing + if (! lpOleCache) + return ResultFromScode(E_INVALIDARG); + + // Setup new cache with the new aspect + FmtEtc.cfFormat = (CLIPFORMAT) NULL; // whatever is needed to draw + FmtEtc.ptd = NULL; + FmtEtc.dwAspect = dwNewAspect; + FmtEtc.lindex = -1; + FmtEtc.tymed = TYMED_NULL; + + /* OLE2NOTE: if we are setting up Icon aspect with a custom icon + ** then we do not want DataAdvise notifications to ever change + ** the contents of the data cache. thus we set up a NODATA + ** advise connection. otherwise we set up a standard DataAdvise + ** connection. + */ + if (dwNewAspect == DVASPECT_ICON && hMetaPict) + dwAdvf = ADVF_NODATA; + else + dwAdvf = ADVF_PRIMEFIRST; + + OLEDBG_BEGIN2(TEXT("IOleCache::Cache called\r\n")) + hrErr = lpOleCache->lpVtbl->Cache( + lpOleCache, + (LPFORMATETC)&FmtEtc, + dwAdvf, + (LPDWORD)&dwNewConnection + ); + OLEDBG_END2 + + if (! SUCCEEDED(hrErr)) { + OleDbgOutHResult(TEXT("IOleCache::Cache returned"), hrErr); + OleStdRelease((LPUNKNOWN)lpOleCache); + return hrErr; + } + + *lpdwCurAspect = dwNewAspect; + + /* OLE2NOTE: if we are setting up Icon aspect with a custom icon, + ** then stuff the icon into the cache. otherwise the cache must + ** be forced to be updated. set the *lpfMustUpdate flag to tell + ** caller to force the object to Run so that the cache will be + ** updated. + */ + if (dwNewAspect == DVASPECT_ICON && hMetaPict) { + + FmtEtc.cfFormat = CF_METAFILEPICT; + FmtEtc.ptd = NULL; + FmtEtc.dwAspect = DVASPECT_ICON; + FmtEtc.lindex = -1; + FmtEtc.tymed = TYMED_MFPICT; + + Medium.tymed = TYMED_MFPICT; + Medium.hGlobal = hMetaPict; + Medium.pUnkForRelease = NULL; + + OLEDBG_BEGIN2(TEXT("IOleCache::SetData called\r\n")) + hrErr = lpOleCache->lpVtbl->SetData( + lpOleCache, + (LPFORMATETC)&FmtEtc, + (LPSTGMEDIUM)&Medium, + FALSE /* fRelease */ + ); + OLEDBG_END2 + } else { + if (lpfMustUpdate) + *lpfMustUpdate = TRUE; + } + + if (fSetupViewAdvise && lpAdviseSink) { + /* OLE2NOTE: re-establish the ViewAdvise connection */ + lpViewObj = (LPVIEWOBJECT)OleStdQueryInterface( + (LPUNKNOWN)lpOleObj,&IID_IViewObject); + + if (lpViewObj) { + + OLEDBG_BEGIN2(TEXT("IViewObject::SetAdvise called\r\n")) + lpViewObj->lpVtbl->SetAdvise( + lpViewObj, + dwNewAspect, + 0, + lpAdviseSink + ); + OLEDBG_END2 + + OleStdRelease((LPUNKNOWN)lpViewObj); + } + } + + /* OLE2NOTE: remove any existing caches that are set up for the old + ** display aspect. It WOULD be possible to retain the caches set + ** up for the old aspect, but this would increase the storage + ** space required for the object and possibly require additional + ** overhead to maintain the unused cachaes. For these reasons the + ** strategy to delete the previous caches is prefered. if it is a + ** requirement to quickly switch between Icon and Content + ** display, then it would be better to keep both aspect caches. + */ + + if (fDeleteOldAspect) { + OLEDBG_BEGIN2(TEXT("IOleCache::EnumCache called\r\n")) + hrErr = lpOleCache->lpVtbl->EnumCache( + lpOleCache, + (LPENUMSTATDATA FAR*)&lpEnumStatData + ); + OLEDBG_END2 + + while(hrErr == NOERROR) { + hrErr = lpEnumStatData->lpVtbl->Next( + lpEnumStatData, + 1, + (LPSTATDATA)&StatData, + NULL + ); + if (hrErr != NOERROR) + break; // DONE! no more caches. + + if (StatData.formatetc.dwAspect == dwOldAspect) { + + // Remove previous cache with old aspect + OLEDBG_BEGIN2(TEXT("IOleCache::Uncache called\r\n")) + lpOleCache->lpVtbl->Uncache(lpOleCache,StatData.dwConnection); + OLEDBG_END2 + } + } + + if (lpEnumStatData) { + OleStdVerifyRelease( + (LPUNKNOWN)lpEnumStatData, + TEXT("OleStdSwitchDisplayAspect: Cache enumerator NOT released") + ); + } + } + + if (lpOleCache) + OleStdRelease((LPUNKNOWN)lpOleCache); + + return NOERROR; +} + + +/* OleStdSetIconInCache +** -------------------- +** SetData a new icon into the existing DVASPECT_ICON cache. +** +** RETURNS: +** HRESULT returned from IOleCache::SetData +*/ +STDAPI OleStdSetIconInCache(LPOLEOBJECT lpOleObj, HGLOBAL hMetaPict) +{ + LPOLECACHE lpOleCache = NULL; + FORMATETC FmtEtc; + STGMEDIUM Medium; + HRESULT hrErr; + + if (! hMetaPict) + return FALSE; // invalid icon + + lpOleCache = (LPOLECACHE)OleStdQueryInterface( + (LPUNKNOWN)lpOleObj,&IID_IOleCache); + if (! lpOleCache) + return FALSE; // if IOleCache* is NOT available, do nothing + + FmtEtc.cfFormat = CF_METAFILEPICT; + FmtEtc.ptd = NULL; + FmtEtc.dwAspect = DVASPECT_ICON; + FmtEtc.lindex = -1; + FmtEtc.tymed = TYMED_MFPICT; + + // stuff the icon into the cache. + Medium.tymed = TYMED_MFPICT; + Medium.hGlobal = hMetaPict; + Medium.pUnkForRelease = NULL; + + OLEDBG_BEGIN2(TEXT("IOleCache::SetData called\r\n")) + hrErr = lpOleCache->lpVtbl->SetData( + lpOleCache, + (LPFORMATETC)&FmtEtc, + (LPSTGMEDIUM)&Medium, + FALSE /* fRelease */ + ); + OLEDBG_END2 + + OleStdRelease((LPUNKNOWN)lpOleCache); + + return hrErr; +} + + + +/* OleStdDoConvert +** --------------- +** Do the container-side responsibilities for converting an object. +** This function would be used in conjunction with the OleUIConvert +** dialog. If the user selects to convert an object then the +** container must do the following: +** 1. unload the object. +** 2. write the NEW CLSID and NEW user type name +** string into the storage of the object, +** BUT write the OLD format tag. +** 3. force an update of the object to force the actual +** conversion of the data bits. +** +** This function takes care of step 2. +*/ +STDAPI OleStdDoConvert(LPSTORAGE lpStg, REFCLSID rClsidNew) +{ + HRESULT error; + CLSID clsidOld; + CLIPFORMAT cfOld; + LPTSTR lpszOld = NULL; + TCHAR szNew[OLEUI_CCHKEYMAX]; + + if ((error = ReadClassStg(lpStg, &clsidOld)) != NOERROR) { + clsidOld = CLSID_NULL; + goto errRtn; + } + + // read old fmt/old user type; sets out params to NULL on error + { + LPOLESTR polestr; + + error = ReadFmtUserTypeStg(lpStg, &cfOld, &polestr); + + CopyAndFreeOLESTR(polestr, &lpszOld); + } + + OleDbgAssert(error == NOERROR || (cfOld == 0 && lpszOld == NULL)); + + // get new user type name; if error, set to NULL string + if (OleStdGetUserTypeOfClass( + // (LPCLSID) + rClsidNew, szNew,sizeof(szNew),NULL /* hKey */) == 0) + szNew[0] = TEXT('\0'); + + // write class stg + if ((error = WriteClassStg(lpStg, rClsidNew)) != NOERROR) + goto errRtn; + + // write old fmt/new user type; +#ifdef UNICODE + if ((error = WriteFmtUserTypeStg(lpStg, cfOld, szNew)) != NOERROR) + goto errRewriteInfo; +#else + { + // Chicago OLE is using UNICODE, so we need to convert the string to + // UNICODE. + WCHAR szNewT[OLEUI_CCHKEYMAX]; + mbstowcs(szNewT, szNew, sizeof(szNew)); + if ((error = WriteFmtUserTypeStg(lpStg, cfOld, szNewT)) != NOERROR) + goto errRewriteInfo; + } +#endif + + // set convert bit + if ((error = SetConvertStg(lpStg, TRUE)) != NOERROR) + goto errRewriteInfo; + + goto okRtn; + +errRewriteInfo: + (void)WriteClassStg(lpStg, &clsidOld); + + (void)WriteFmtUserTypeStgA(lpStg, cfOld, lpszOld); + +errRtn: + +okRtn: + OleStdFreeString(lpszOld, NULL); + return error; +} + + +/* OleStdGetTreatAsFmtUserType +** --------------------------- +** Determine if the application should perform a TreatAs (ActivateAs +** object or emulation) operation for the object that is stored in +** the storage. +** +** if the CLSID written in the storage is not the same as the +** application's own CLSID (clsidApp), then a TreatAs operation +** should take place. if so determine the format the data should be +** written and the user type name of the object the app should +** emulate (ie. pretend to be). if this information is not written +** in the storage then it is looked up in the REGDB. if it can not +** be found in the REGDB, then the TreatAs operation can NOT be +** executed. +** +** RETURNS: TRUE -- if TreatAs should be performed. +** valid lpclsid, lplpszType, lpcfFmt to TreatAs are returned +** (NOTE: lplpszType must be freed by caller) +** FALSE -- NO TreatAs. lpszType will be NULL. +** lpclsid = CLSID_NULL; lplpszType = lpcfFmt = NULL; +*/ +STDAPI_(BOOL) OleStdGetTreatAsFmtUserType( + REFCLSID rclsidApp, + LPSTORAGE lpStg, + CLSID FAR* lpclsid, + CLIPFORMAT FAR* lpcfFmt, + LPTSTR FAR* lplpszType +) +{ + HRESULT hrErr; + HKEY hKey; + LONG lRet; + UINT lSize; + TCHAR szBuf[OLEUI_CCHKEYMAX]; + + *lpclsid = CLSID_NULL; + *lpcfFmt = 0; + *lplpszType = NULL; + + hrErr = ReadClassStg(lpStg, lpclsid); + if (hrErr == NOERROR && + ! IsEqualCLSID(lpclsid, &CLSID_NULL) && + ! IsEqualCLSID(lpclsid, rclsidApp)) { + + hrErr = ReadFmtUserTypeStgA(lpStg,(CLIPFORMAT FAR*)lpcfFmt, lplpszType); + + if (hrErr == NOERROR && lplpszType && *lpcfFmt != 0) + return TRUE; // Do TreatAs. info was in lpStg. + + /* read info from REGDB + ** *lpcfFmt = value of field: CLSID\{...}\DataFormats\DefaultFile + ** *lplpszType = value of field: CLSID\{...} + */ + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + if (lRet != (LONG)ERROR_SUCCESS) + return FALSE; + *lpcfFmt = OleStdGetDefaultFileFormatOfClass(lpclsid, hKey); + if (*lpcfFmt == 0) + return FALSE; + lSize = OleStdGetUserTypeOfClass(lpclsid,szBuf,sizeof(szBuf),hKey); + if (lSize == 0) + return FALSE; + *lplpszType = OleStdCopyString(szBuf, NULL); + } else { + return FALSE; // NO TreatAs + } +} + + + +/* OleStdDoTreatAsClass +** -------------------- +** Do the container-side responsibilities for "ActivateAs" (aka. +** TreatAs) for an object. +** This function would be used in conjunction with the OleUIConvert +** dialog. If the user selects to ActivateAs an object then the +** container must do the following: +** 1. unload ALL objects of the OLD class that app knows about +** 2. add the TreatAs tag in the registration database +** by calling CoTreatAsClass(). +** 3. lazily it can reload the objects; when the objects +** are reloaded the TreatAs will take effect. +** +** This function takes care of step 2. +*/ +STDAPI OleStdDoTreatAsClass(LPTSTR lpszUserType, REFCLSID rclsid, REFCLSID rclsidNew) +{ + HRESULT hrErr; + LPTSTR lpszCLSID = NULL; + LONG lRet; + HKEY hKey; + + OLEDBG_BEGIN2(TEXT("CoTreatAsClass called\r\n")) + hrErr = CoTreatAsClass(rclsid, rclsidNew); + OLEDBG_END2 + + if ((hrErr != NOERROR) && lpszUserType) { + lRet = RegOpenKey(HKEY_CLASSES_ROOT, (LPCTSTR) TEXT("CLSID"), + (HKEY FAR *)&hKey); + StringFromCLSIDA(rclsid, &lpszCLSID); + + RegSetValue(hKey, lpszCLSID, REG_SZ, lpszUserType, + lstrlen(lpszUserType)); + + if (lpszCLSID) + OleStdFreeString(lpszCLSID, NULL); + + hrErr = CoTreatAsClass(rclsid, rclsidNew); + RegCloseKey(hKey); + } + + return hrErr; +} + + + +/* 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) +{ + LPOLELINK lpOleLink; + + lpOleLink = (LPOLELINK)OleStdQueryInterface(lpUnk, &IID_IOleLink); + + if (lpOleLink) { + OleStdRelease((LPUNKNOWN)lpOleLink); + return TRUE; + } else + 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->lpVtbl->QueryInterface( + lpUnk, + 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->lpVtbl->GetData( + lpDataObj, + (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->lpVtbl->Alloc(pmalloc, ulSize); + + if (pmalloc != NULL) { + ULONG refs = pmalloc->lpVtbl->Release(pmalloc); + } + + 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->lpVtbl->Realloc(pmalloc, pmem, ulSize); + + if (pmalloc != NULL) { + ULONG refs = pmalloc->lpVtbl->Release(pmalloc); + } + + 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; + } + + pmalloc->lpVtbl->Free(pmalloc, pmem); + + if (pmalloc != NULL) { + ULONG refs = pmalloc->lpVtbl->Release(pmalloc); + } +} + + +/* 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->lpVtbl->GetSize(pmalloc, pmem); + + if (pmalloc != NULL) { + ULONG refs = pmalloc->lpVtbl->Release(pmalloc); + } + + return ulSize; +} + + +/* OleStdFreeString +** ---------------- +** Free a string that was allocated with the currently active +** IMalloc* allocator. +** +** if the caller has the current IMalloc* handy, then it can be +** passed as a argument, otherwise this function will retrieve the +** active allocator and use it. +*/ +STDAPI_(void) OleStdFreeString(LPTSTR lpsz, LPMALLOC lpMalloc) +{ + BOOL fMustRelease = FALSE; + + if (! lpMalloc) { + if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) != NOERROR) + return; + fMustRelease = TRUE; + } + + lpMalloc->lpVtbl->Free(lpMalloc, lpsz); + + if (fMustRelease) + lpMalloc->lpVtbl->Release(lpMalloc); +} + + +/* OleStdCopyString +** ---------------- +** Copy a string into memory allocated with the currently active +** IMalloc* allocator. +** +** if the caller has the current IMalloc* handy, then it can be +** passed as a argument, otherwise this function will retrieve the +** active allocator and use it. +*/ +STDAPI_(LPTSTR) OleStdCopyString(LPTSTR lpszSrc, LPMALLOC lpMalloc) +{ + LPTSTR lpszDest = NULL; + BOOL fMustRelease = FALSE; + UINT lSize = lstrlen(lpszSrc); + + if (! lpMalloc) { + if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) != NOERROR) + return NULL; + fMustRelease = TRUE; + } + + lpszDest = lpMalloc->lpVtbl->Alloc(lpMalloc, (lSize+1)*sizeof(TCHAR)); + + if (lpszDest) + lstrcpy(lpszDest, lpszSrc); + + if (fMustRelease) + lpMalloc->lpVtbl->Release(lpMalloc); + return lpszDest; +} + + +/* + * OleStdCreateStorageOnHGlobal() + * + * Purpose: + * Create a memory based IStorage*. + * + * OLE2NOTE: if fDeleteOnRelease==TRUE, then the ILockBytes is created + * such that it will delete them memory on its last release. + * the IStorage on created on top of the ILockBytes in NOT + * created with STGM_DELETEONRELEASE. when the IStorage receives + * its last release, it will release the ILockBytes which will + * in turn free the memory. it is in fact an error to specify + * STGM_DELETEONRELEASE in this situation. + * + * Parameters: + * hGlobal -- handle to MEM_SHARE allocated memory. may be NULL and + * memory will be automatically allocated. + * fDeleteOnRelease -- controls if the memory is freed on the last release. + * grfMode -- flags passed to StgCreateDocfileOnILockBytes + * + * NOTE: if hGlobal is NULL, then a new IStorage is created and + * STGM_CREATE flag is passed to StgCreateDocfileOnILockBytes. + * if hGlobal is non-NULL, then it is assumed that the hGlobal already + * has an IStorage inside it and STGM_CONVERT flag is passed + * to StgCreateDocfileOnILockBytes. + * + * Return Value: + * SCODE - S_OK if successful + */ +STDAPI_(LPSTORAGE) OleStdCreateStorageOnHGlobal( + HANDLE hGlobal, + BOOL fDeleteOnRelease, + DWORD grfMode +) +{ + DWORD grfCreateMode=grfMode | (hGlobal==NULL ? STGM_CREATE:STGM_CONVERT); + HRESULT hrErr; + LPLOCKBYTES lpLockBytes = NULL; + DWORD reserved = 0; + LPSTORAGE lpStg = NULL; + + hrErr = CreateILockBytesOnHGlobal( + hGlobal, + fDeleteOnRelease, + (LPLOCKBYTES FAR*)&lpLockBytes + ); + if (hrErr != NOERROR) + return NULL; + + hrErr = StgCreateDocfileOnILockBytes( + lpLockBytes, + grfCreateMode, + reserved, + (LPSTORAGE FAR*)&lpStg + ); + if (hrErr != NOERROR) { + OleStdRelease((LPUNKNOWN)lpLockBytes); + return NULL; + } + return lpStg; +} + + + +/* + * OleStdCreateTempStorage() + * + * Purpose: + * Create a temporay IStorage* that will DeleteOnRelease. + * this can be either memory based or file based. + * + * Parameters: + * fUseMemory -- controls if memory-based or file-based stg is created + * grfMode -- storage mode flags + * + * Return Value: + * LPSTORAGE - if successful, NULL otherwise + */ +STDAPI_(LPSTORAGE) OleStdCreateTempStorage(BOOL fUseMemory, DWORD grfMode) +{ + LPSTORAGE lpstg; + HRESULT hrErr; + DWORD reserved = 0; + + if (fUseMemory) { + lpstg = OleStdCreateStorageOnHGlobal( + NULL, /* auto allocate */ + TRUE, /* delete on release */ + grfMode + ); + } else { + /* allocate a temp docfile that will delete on last release */ + hrErr = StgCreateDocfile( + NULL, + grfMode | STGM_DELETEONRELEASE | STGM_CREATE, + reserved, + &lpstg + ); + if (hrErr != NOERROR) + return NULL; + } + return lpstg; +} + + +/* OleStdGetOleObjectData +** ---------------------- +** Render CF_EMBEDSOURCE/CF_EMBEDDEDOBJECT data on an TYMED_ISTORAGE +** medium by asking the object to save into the storage. +** the object must support IPersistStorage. +** +** if lpMedium->tymed == TYMED_NULL, then a delete-on-release +** storage is allocated (either file-based or memory-base depending +** the value of fUseMemory). this is useful to support an +** IDataObject::GetData call where the callee must allocate the +** medium. +** +** if lpMedium->tymed == TYMED_ISTORAGE, then the data is writen +** into the passed in IStorage. this is useful to support an +** IDataObject::GetDataHere call where the caller has allocated his +** own IStorage. +*/ +STDAPI OleStdGetOleObjectData( + LPPERSISTSTORAGE lpPStg, + LPFORMATETC lpformatetc, + LPSTGMEDIUM lpMedium, + BOOL fUseMemory +) +{ + LPSTORAGE lpstg = NULL; + DWORD reserved = 0; + SCODE sc = S_OK; + HRESULT hrErr; + + lpMedium->pUnkForRelease = NULL; + + if (lpMedium->tymed == TYMED_NULL) { + + if (lpformatetc->tymed & TYMED_ISTORAGE) { + + /* allocate a temp docfile that will delete on last release */ + lpstg = OleStdCreateTempStorage( + TRUE /*fUseMemory*/, + STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE + ); + if (!lpstg) + return ResultFromScode(E_OUTOFMEMORY); + + lpMedium->pstg = lpstg; + lpMedium->tymed = TYMED_ISTORAGE; + lpMedium->pUnkForRelease = NULL; + } else { + return ResultFromScode(DATA_E_FORMATETC); + } + } else if (lpMedium->tymed == TYMED_ISTORAGE) { + lpMedium->tymed = TYMED_ISTORAGE; + } else { + return ResultFromScode(DATA_E_FORMATETC); + } + + // OLE2NOTE: even if OleSave returns an error you should still call + // SaveCompleted. + + OLEDBG_BEGIN2(TEXT("OleSave called\r\n")) + hrErr = OleSave(lpPStg, lpMedium->pstg, FALSE /* fSameAsLoad */); + OLEDBG_END2 + + if (hrErr != NOERROR) { + OleDbgOutHResult(TEXT("WARNING: OleSave returned"), hrErr); + sc = GetScode(hrErr); + } + OLEDBG_BEGIN2(TEXT("IPersistStorage::SaveCompleted called\r\n")) + hrErr = lpPStg->lpVtbl->SaveCompleted(lpPStg, NULL); + OLEDBG_END2 + + if (hrErr != NOERROR) { + OleDbgOutHResult(TEXT("WARNING: SaveCompleted returned"),hrErr); + if (sc == S_OK) + sc = GetScode(hrErr); + } + + return ResultFromScode(sc); +} + + +STDAPI OleStdGetLinkSourceData( + LPMONIKER lpmk, + LPCLSID lpClsID, + LPFORMATETC lpformatetc, + LPSTGMEDIUM lpMedium +) +{ + LPSTREAM lpstm = NULL; + DWORD reserved = 0; + HRESULT hrErr; + + if (lpMedium->tymed == TYMED_NULL) { + if (lpformatetc->tymed & TYMED_ISTREAM) { + hrErr = CreateStreamOnHGlobal( + NULL, /* auto allocate */ + TRUE, /* delete on release */ + (LPSTREAM FAR*)&lpstm + ); + if (hrErr != NOERROR) { + lpMedium->pUnkForRelease = NULL; + return ResultFromScode(E_OUTOFMEMORY); + } + lpMedium->pstm = lpstm; + lpMedium->tymed = TYMED_ISTREAM; + lpMedium->pUnkForRelease = NULL; + } else { + lpMedium->pUnkForRelease = NULL; + return ResultFromScode(DATA_E_FORMATETC); + } + } else { + if (lpMedium->tymed == TYMED_ISTREAM) { + lpMedium->tymed = TYMED_ISTREAM; + lpMedium->pstm = lpMedium->pstm; + lpMedium->pUnkForRelease = NULL; + } else { + lpMedium->pUnkForRelease = NULL; + return ResultFromScode(DATA_E_FORMATETC); + } + } + + hrErr = OleSaveToStream((LPPERSISTSTREAM)lpmk, lpMedium->pstm); + if (hrErr != NOERROR) return hrErr; + return WriteClassStm(lpMedium->pstm, lpClsID); +} + +/* + * 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 lpszFullUserTypeNameA, + LPTSTR lpszSrcOfCopyA +) +{ + HGLOBAL hMem = NULL; + IBindCtx FAR *pbc = NULL; + LPOBJECTDESCRIPTOR lpOD; + DWORD dwObjectDescSize, dwFullUserTypeNameLen, dwSrcOfCopyLen; + LPOLESTR lpszFullUserTypeName, + lpszSrcOfCopy; + + // convert out strings to UNICODE + + if( lpszSrcOfCopyA ) + { + lpszSrcOfCopy = CreateOLESTR(lpszSrcOfCopyA); + } + + lpszFullUserTypeName = CreateOLESTR(lpszFullUserTypeNameA); + + // Get the length of Full User Type Name; Add 1 for the null terminator + dwFullUserTypeNameLen = lpszFullUserTypeName ? wcslen(lpszFullUserTypeName)+1 : 0; + + // Get the Source of Copy string and it's length; Add 1 for the null terminator + if (lpszSrcOfCopy) + dwSrcOfCopyLen = wcslen(lpszSrcOfCopy)+1; + else { + // No src moniker so use user type name as source string. + lpszSrcOfCopy = lpszFullUserTypeName; + dwSrcOfCopyLen = dwFullUserTypeNameLen; + } + + // Allocate space for OBJECTDESCRIPTOR and the additional string data + dwObjectDescSize = sizeof(OBJECTDESCRIPTOR); + hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, dwObjectDescSize + + (dwFullUserTypeNameLen + dwSrcOfCopyLen)*sizeof(OLECHAR)); + if (NULL == hMem) + goto error; + + lpOD = (LPOBJECTDESCRIPTOR)GlobalLock(hMem); + + // Set the FullUserTypeName offset and copy the string + if (lpszFullUserTypeName) + { + lpOD->dwFullUserTypeName = dwObjectDescSize; + wcscpy((LPOLESTR)(((BYTE FAR *)lpOD)+lpOD->dwFullUserTypeName), + lpszFullUserTypeName); + } + 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); + wcscpy((LPOLESTR)(((BYTE FAR *)lpOD)+lpOD->dwSrcOfCopy), lpszSrcOfCopy); + } + 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); + + FREEOLESTR(lpszFullUserTypeName); + FREEOLESTR(lpszSrcOfCopy); + + return hMem; + +error: + if (hMem) + { + GlobalUnlock(hMem); + GlobalFree(hMem); + } + return NULL; +} + +/* + * OleStdGetObjectDescriptorDataFromOleObject + * + * Purpose: + * Fills and returns a OBJECTDESCRIPTOR structure. Information for the structure is + * obtained from an OLEOBJECT. + * See OBJECTDESCRIPTOR for more information. + * + * Parameters: + * lpOleObj LPOLEOBJECT OleObject from which ONJECTDESCRIPTOR info + * is obtained. + * lpszSrcOfCopy LPSTR string to identify source of copy. + * May be NULL in which case IOleObject::GetMoniker is called + * to get the moniker of the object. if the object is loaded + * as part of a data transfer document, then usually + * lpOleClientSite==NULL is passed to OleLoad when loading + * the object. in this case the IOleObject:GetMoniker call + * will always fail (it tries to call back to the object's + * client site). in this situation a non-NULL lpszSrcOfCopy + * parameter should be passed. + * dwDrawAspect DWORD Display Aspect of object + * pointl POINTL Offset from upper-left corner of object where + * mouse went down for drag. Meaningful only when drag-drop + * is used. + * lpSizelHim SIZEL (optional) If the object is being scaled in its + * container, then the container should pass the extents + * that it is using to display the object. + * May be NULL if the object is NOT being scaled. in this + * case, IViewObject2::GetExtent will be called to get the + * extents from the object. + * + * Return Value: + * HBGLOBAL Handle to OBJECTDESCRIPTOR structure. + */ + +STDAPI_(HGLOBAL) OleStdGetObjectDescriptorDataFromOleObject( + LPOLEOBJECT lpOleObj, + LPTSTR lpszSrcOfCopy, + DWORD dwDrawAspect, + POINTL pointl, + LPSIZEL lpSizelHim +) +{ + CLSID clsid; + LPTSTR lpszFullUserTypeName = NULL; + LPMONIKER lpSrcMonikerOfCopy = NULL; + HGLOBAL hObjDesc; + IBindCtx FAR *pbc = NULL; + HRESULT hrErr; + SIZEL sizelHim; + BOOL fFreeSrcOfCopy = FALSE; + LPOLELINK lpOleLink = (LPOLELINK) + OleStdQueryInterface((LPUNKNOWN)lpOleObj,&IID_IOleLink); + +#ifdef OLE201 + LPVIEWOBJECT2 lpViewObj2 = (LPVIEWOBJECT2) + OleStdQueryInterface((LPUNKNOWN)lpOleObj, &IID_IViewObject2); +#endif + + BOOL fIsLink = (lpOleLink ? TRUE : FALSE); + TCHAR szLinkedTypeFmt[80]; + LPTSTR lpszBuf = NULL; + DWORD dwStatus = 0; + + // Get CLSID + OLEDBG_BEGIN2(TEXT("IOleObject::GetUserClassID called\r\n")) + hrErr = lpOleObj->lpVtbl->GetUserClassID(lpOleObj, &clsid); + OLEDBG_END2 + if (hrErr != NOERROR) + clsid = CLSID_NULL; + + // Get FullUserTypeName + OLEDBG_BEGIN2(TEXT("IOleObject::GetUserType called\r\n")) + { + LPOLESTR polestr; + + hrErr = lpOleObj->lpVtbl->GetUserType( + lpOleObj, + USERCLASSTYPE_FULL, + &polestr + ); + + CopyAndFreeOLESTR(polestr, &lpszFullUserTypeName); + } + + OLEDBG_END2 + +// REVIEW: added IDS_OLE2UILINKEDTYPE to strings.rc + /* if object is a link, then expand usertypename to be "Linked %s" */ + if (fIsLink && lpszFullUserTypeName) { + if (0 == LoadString(ghInst, IDS_OLE2UIPASTELINKEDTYPE, + (LPTSTR)szLinkedTypeFmt, sizeof(szLinkedTypeFmt)/sizeof(TCHAR))) + lstrcpy(szLinkedTypeFmt, (LPTSTR) TEXT("Linked %s")); + lpszBuf = OleStdMalloc( + (lstrlen(lpszFullUserTypeName)+lstrlen(szLinkedTypeFmt)+1) * + sizeof(TCHAR)); + if (lpszBuf) { + wsprintf(lpszBuf, szLinkedTypeFmt, lpszFullUserTypeName); + OleStdFreeString(lpszFullUserTypeName, NULL); + lpszFullUserTypeName = lpszBuf; + } + } + + /* Get Source Of Copy + ** if the object is an embedding, then get the object's moniker + ** if the object is a link, then get the link source moniker + */ + if (fIsLink) { + + OLEDBG_BEGIN2(TEXT("IOleLink::GetSourceDisplayName called\r\n")) + + { + LPOLESTR polestr; + + hrErr = lpOleLink->lpVtbl->GetSourceDisplayName( + lpOleLink, &polestr ); + + CopyAndFreeOLESTR(polestr, &lpszSrcOfCopy); + } + OLEDBG_END2 + fFreeSrcOfCopy = TRUE; + + } else { + + if (lpszSrcOfCopy == NULL) { + OLEDBG_BEGIN2(TEXT("IOleObject::GetMoniker called\r\n")) + hrErr = lpOleObj->lpVtbl->GetMoniker( + lpOleObj, + OLEGETMONIKER_TEMPFORUSER, + OLEWHICHMK_OBJFULL, + (LPMONIKER FAR*)&lpSrcMonikerOfCopy + ); + OLEDBG_END2 + if (hrErr == NOERROR) + { +#ifdef OLE201 + CreateBindCtx(0, (LPBC FAR*)&pbc); +#endif + CallIMonikerGetDisplayNameA( + lpSrcMonikerOfCopy, pbc, NULL, &lpszSrcOfCopy); + + pbc->lpVtbl->Release(pbc); + fFreeSrcOfCopy = TRUE; + } + } + } + + // Get SIZEL + if (lpSizelHim) { + // Use extents passed by the caller + sizelHim = *lpSizelHim; + } else if (lpViewObj2) { + // Get the current extents from the object + OLEDBG_BEGIN2(TEXT("IViewObject2::GetExtent called\r\n")) + hrErr = lpViewObj2->lpVtbl->GetExtent( + lpViewObj2, + dwDrawAspect, + -1, /*lindex*/ + NULL, /*ptd*/ + (LPSIZEL)&sizelHim + ); + OLEDBG_END2 + if (hrErr != NOERROR) + sizelHim.cx = sizelHim.cy = 0; + } else { + sizelHim.cx = sizelHim.cy = 0; + } + + // Get DWSTATUS + OLEDBG_BEGIN2(TEXT("IOleObject::GetMiscStatus called\r\n")) + hrErr = lpOleObj->lpVtbl->GetMiscStatus( + lpOleObj, + dwDrawAspect, + &dwStatus + ); + OLEDBG_END2 + if (hrErr != NOERROR) + dwStatus = 0; + + // Get OBJECTDESCRIPTOR + hObjDesc = OleStdGetObjectDescriptorData( + clsid, + dwDrawAspect, + sizelHim, + pointl, + dwStatus, + lpszFullUserTypeName, + lpszSrcOfCopy + ); + if (! hObjDesc) + goto error; + + // Clean up + if (lpszFullUserTypeName) + OleStdFreeString(lpszFullUserTypeName, NULL); + if (fFreeSrcOfCopy && lpszSrcOfCopy) + OleStdFreeString(lpszSrcOfCopy, NULL); + if (lpSrcMonikerOfCopy) + OleStdRelease((LPUNKNOWN)lpSrcMonikerOfCopy); + if (lpOleLink) + OleStdRelease((LPUNKNOWN)lpOleLink); + if (lpViewObj2) + OleStdRelease((LPUNKNOWN)lpViewObj2); + + return hObjDesc; + +error: + if (lpszFullUserTypeName) + OleStdFreeString(lpszFullUserTypeName, NULL); + if (fFreeSrcOfCopy && lpszSrcOfCopy) + OleStdFreeString(lpszSrcOfCopy, NULL); + if (lpSrcMonikerOfCopy) + OleStdRelease((LPUNKNOWN)lpSrcMonikerOfCopy); + if (lpOleLink) + OleStdRelease((LPUNKNOWN)lpOleLink); + if (lpViewObj2) + OleStdRelease((LPUNKNOWN)lpViewObj2); + + return NULL; +} + +/* + * 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; + LPMALLOC pIMalloc = 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 + if (hMem = OleStdGetData( + lpDataObject, + (CLIPFORMAT) cfObjectDescriptor, + NULL, + DVASPECT_CONTENT, + lpmedium)) + { + *lpcfFmt = 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 if (hMem = OleStdGetData( + lpDataObject, + (CLIPFORMAT) cfOwnerLink, + NULL, + DVASPECT_CONTENT, + lpmedium)) + { + *lpcfFmt = 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); + + hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); + if (hrErr != NOERROR) + goto error; + + // 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)pIMalloc->lpVtbl->Alloc(pIMalloc, + (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, &dw) != ERROR_SUCCESS) + goto error; + + // Build up SrcOfCopy string from FullUserTypeName, DocumentName & ItemName + lpsz = szSrcOfCopy; + lstrcpy(lpsz, szFullUserTypeName); + nFullUserTypeName = lstrlen(szFullUserTypeName); + lpsz[nFullUserTypeName]= TEXT(' '); + lpsz += nFullUserTypeName+1; + lstrcpy(lpsz, szDocName); + lpsz[nDocName] = TEXT(' '); + lpsz += nDocName+1; + lstrcpy(lpsz, szItemName); + + sizelHim.cx = sizelHim.cy = 0; + pointl.x = pointl.y = 0; + + CLSIDFromProgIDA(szClassName, &clsid); + + hObjDesc = OleStdGetObjectDescriptorData( + clsid, + DVASPECT_CONTENT, + sizelHim, + pointl, + 0, + szFullUserTypeName, + szSrcOfCopy + ); + if (!hObjDesc) + goto error; + } + // Check if object is CF_FILENAME + else if (hMem = OleStdGetData( + lpDataObject, + (CLIPFORMAT) cfFileName, + NULL, + DVASPECT_CONTENT, + lpmedium)) + { + *lpcfFmt = cfFileName; + lpsz = (LPTSTR)GlobalLock(hMem); + + hrErr = GetClassFileA(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) + CLSIDFromProgIDA("Package", &clsid); + sizelHim.cx = sizelHim.cy = 0; + pointl.x = pointl.y = 0; + + hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); + if (hrErr != NOERROR) + goto error; + szBuf = (LPTSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, (DWORD)OLEUI_CCHKEYMAX_SIZE); + if (NULL == szBuf) + goto error; + + OleStdGetUserTypeOfClass(&clsid, szBuf, OLEUI_CCHKEYMAX_SIZE, NULL); + + hObjDesc = OleStdGetObjectDescriptorData( + clsid, + DVASPECT_CONTENT, + sizelHim, + pointl, + 0, + szBuf, + lpsz + ); + if (!hObjDesc) + goto error; + } + else goto error; + + // Clean up + if (szBuf) + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)szBuf); + if (pIMalloc) + pIMalloc->lpVtbl->Release(pIMalloc); + if (hMem) + { + GlobalUnlock(hMem); + GlobalFree(hMem); + } + if (hKey) + RegCloseKey(hKey); + return hObjDesc; + +error: + if (szBuf) + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)szBuf); + if (pIMalloc) + pIMalloc->lpVtbl->Release(pIMalloc); + if (hMem) + { + GlobalUnlock(hMem); + GlobalFree(hMem); + } + if (hKey) + RegCloseKey(hKey); + return NULL; +} + + +#if defined( OBSOLETE ) + +/************************************************************************* +** The following API's have been converted into macros: +** OleStdQueryOleObjectData +** OleStdQueryLinkSourceData +** OleStdQueryObjectDescriptorData +** OleStdQueryFormatMedium +** OleStdCopyMetafilePict +** OleStdGetDropEffect +** +** These macros are defined in olestd.h +*************************************************************************/ + +STDAPI OleStdQueryOleObjectData(LPFORMATETC lpformatetc) +{ + if (lpformatetc->tymed & TYMED_ISTORAGE) { + return NOERROR; + } else { + return ResultFromScode(DATA_E_FORMATETC); + } +} + + +STDAPI OleStdQueryLinkSourceData(LPFORMATETC lpformatetc) +{ + if (lpformatetc->tymed & TYMED_ISTREAM) { + return NOERROR; + } else { + return ResultFromScode(DATA_E_FORMATETC); + } +} + + +STDAPI OleStdQueryObjectDescriptorData(LPFORMATETC lpformatetc) +{ + if (lpformatetc->tymed & TYMED_HGLOBAL) { + return NOERROR; + } else { + return ResultFromScode(DATA_E_FORMATETC); + } +} + + +STDAPI OleStdQueryFormatMedium(LPFORMATETC lpformatetc, TYMED tymed) +{ + if (lpformatetc->tymed & tymed) { + return NOERROR; + } else { + return ResultFromScode(DATA_E_FORMATETC); + } +} + + +/* + * OleStdCopyMetafilePict() + * + * Purpose: + * Make an independent copy of a MetafilePict + * Parameters: + * + * Return Value: + * TRUE if successful, else FALSE. + */ +STDAPI_(BOOL) OleStdCopyMetafilePict(HANDLE hpictin, HANDLE FAR* phpictout) +{ + HANDLE hpictout; + LPMETAFILEPICT ppictin, ppictout; + + if (hpictin == NULL || phpictout == NULL) { + OleDbgAssert(hpictin == NULL || phpictout == NULL); + return FALSE; + } + + *phpictout = NULL; + + if ((ppictin = (LPMETAFILEPICT)GlobalLock(hpictin)) == NULL) { + return FALSE; + } + + hpictout = GlobalAlloc(GHND|GMEM_SHARE, sizeof(METAFILEPICT)); + + if (hpictout && (ppictout = (LPMETAFILEPICT)GlobalLock(hpictout))){ + ppictout->hMF = CopyMetaFile(ppictin->hMF, NULL); + ppictout->xExt = ppictin->xExt; + ppictout->yExt = ppictin->yExt; + ppictout->mm = ppictin->mm; + GlobalUnlock(hpictout); + } + + *phpictout = hpictout; + + return TRUE; + +} + + +/* OleStdGetDropEffect +** ------------------- +** +** Convert a keyboard state into a DROPEFFECT. +** +** returns the DROPEFFECT value derived from the key state. +** the following is the standard interpretation: +** no modifier -- Default Drop (NULL is returned) +** CTRL -- DROPEFFECT_COPY +** SHIFT -- DROPEFFECT_MOVE +** CTRL-SHIFT -- DROPEFFECT_LINK +** +** Default Drop: this depends on the type of the target application. +** this is re-interpretable by each target application. a typical +** interpretation is if the drag is local to the same document +** (which is source of the drag) then a MOVE operation is +** performed. if the drag is not local, then a COPY operation is +** performed. +*/ +STDAPI_(DWORD) OleStdGetDropEffect( DWORD grfKeyState ) +{ + + if (grfKeyState & MK_CONTROL) { + + if (grfKeyState & MK_SHIFT) + return DROPEFFECT_LINK; + else + return DROPEFFECT_COPY; + + } else if (grfKeyState & MK_SHIFT) + return DROPEFFECT_MOVE; + + return 0; // no modifier -- do default operation +} +#endif // OBSOLETE + + +/* + * OleStdGetMetafilePictFromOleObject() + * + * Purpose: + * Generate a MetafilePict by drawing the OLE object. + * Parameters: + * lpOleObj LPOLEOBJECT pointer to OLE Object + * dwDrawAspect DWORD Display Aspect of object + * lpSizelHim SIZEL (optional) If the object is being scaled in its + * container, then the container should pass the extents + * that it is using to display the object. + * May be NULL if the object is NOT being scaled. in this + * case, IViewObject2::GetExtent will be called to get the + * extents from the object. + * ptd TARGETDEVICE FAR* (optional) target device to render + * metafile for. May be NULL. + * + * Return Value: + * HANDLE -- handle of allocated METAFILEPICT + */ +STDAPI_(HANDLE) OleStdGetMetafilePictFromOleObject( + LPOLEOBJECT lpOleObj, + DWORD dwDrawAspect, + LPSIZEL lpSizelHim, + DVTARGETDEVICE FAR* ptd +) +{ + LPVIEWOBJECT2 lpViewObj2 = NULL; + HDC hDC; + HMETAFILE hmf; + HANDLE hMetaPict; + LPMETAFILEPICT lpPict; + RECT rcHim; + RECTL rclHim; + SIZEL sizelHim; + HRESULT hrErr; + SIZE size; + POINT point; + +#ifdef OLE201 + lpViewObj2 = (LPVIEWOBJECT2)OleStdQueryInterface( + (LPUNKNOWN)lpOleObj, &IID_IViewObject2); +#endif + + if (! lpViewObj2) + return NULL; + + // Get SIZEL + if (lpSizelHim) { + // Use extents passed by the caller + sizelHim = *lpSizelHim; + } else { + // Get the current extents from the object + OLEDBG_BEGIN2(TEXT("IViewObject2::GetExtent called\r\n")) + hrErr = lpViewObj2->lpVtbl->GetExtent( + lpViewObj2, + dwDrawAspect, + -1, /*lindex*/ + ptd, /*ptd*/ + (LPSIZEL)&sizelHim + ); + OLEDBG_END2 + if (hrErr != NOERROR) + sizelHim.cx = sizelHim.cy = 0; + } + + hDC = CreateMetaFile(NULL); + + rclHim.left = 0; + rclHim.top = 0; + rclHim.right = sizelHim.cx; + rclHim.bottom = sizelHim.cy; + + rcHim.left = (int)rclHim.left; + rcHim.top = (int)rclHim.top; + rcHim.right = (int)rclHim.right; + rcHim.bottom = (int)rclHim.bottom; + + SetWindowOrgEx(hDC, rcHim.left, rcHim.top, &point); + SetWindowExtEx(hDC, rcHim.right-rcHim.left, rcHim.bottom-rcHim.top,&size); + + OLEDBG_BEGIN2(TEXT("IViewObject::Draw called\r\n")) + hrErr = lpViewObj2->lpVtbl->Draw( + lpViewObj2, + dwDrawAspect, + -1, + NULL, + ptd, + NULL, + hDC, + (LPRECTL)&rclHim, + (LPRECTL)&rclHim, + NULL, + 0 + ); + OLEDBG_END2 + + OleStdRelease((LPUNKNOWN)lpViewObj2); + if (hrErr != NOERROR) { + OleDbgOutHResult(TEXT("IViewObject::Draw returned"), hrErr); + } + + hmf = CloseMetaFile(hDC); + + hMetaPict = GlobalAlloc(GHND|GMEM_SHARE, sizeof(METAFILEPICT)); + + if (hMetaPict && (lpPict = (LPMETAFILEPICT)GlobalLock(hMetaPict))){ + lpPict->hMF = hmf; + lpPict->xExt = (int)sizelHim.cx ; + lpPict->yExt = (int)sizelHim.cy ; + lpPict->mm = MM_ANISOTROPIC; + GlobalUnlock(hMetaPict); + } + + return hMetaPict; +} + + +/* Call Release on the object that is expected to go away. +** if the refcnt of the object did no go to 0 then give a debug message. +*/ +STDAPI_(ULONG) OleStdVerifyRelease(LPUNKNOWN lpUnk, LPTSTR lpszMsg) +{ + ULONG cRef; + + cRef = lpUnk->lpVtbl->Release(lpUnk); + +#if defined( _DEBUG ) + if (cRef != 0) { + TCHAR szBuf[80]; + if (lpszMsg) + MessageBox(NULL, lpszMsg, NULL, MB_ICONEXCLAMATION | MB_OK); + wsprintf( + (LPTSTR)szBuf, + TEXT("refcnt (%ld) != 0 after object (0x%lx) release\n"), + cRef, + lpUnk + ); + if (lpszMsg) + OleDbgOut1(lpszMsg); + OleDbgOut1((LPTSTR)szBuf); + OleDbgAssertSz(cRef == 0, (LPTSTR)szBuf); + } else { + TCHAR szBuf[80]; + wsprintf( + (LPTSTR)szBuf, + TEXT("refcnt = 0 after object (0x%lx) release\n"), lpUnk + ); + OleDbgOut4((LPTSTR)szBuf); + } +#endif + return cRef; +} + + +/* Call Release on the object that is NOT necessarily expected to go away. +*/ +STDAPI_(ULONG) OleStdRelease(LPUNKNOWN lpUnk) +{ + ULONG cRef; + + cRef = lpUnk->lpVtbl->Release(lpUnk); + +#if defined( _DEBUG ) + { + TCHAR szBuf[80]; + wsprintf( + (LPTSTR)szBuf, + TEXT("refcnt = %ld after object (0x%lx) release\n"), + cRef, + lpUnk + ); + OleDbgOut4((LPTSTR)szBuf); + } +#endif + return cRef; +} + + +/* OleStdInitVtbl +** -------------- +** +** Initialize an interface Vtbl to ensure that there are no NULL +** function pointers in the Vtbl. All entries in the Vtbl are +** set to a valid funtion pointer (OleStdNullMethod) that issues +** debug assert message (message box) and returns E_NOTIMPL if called. +** +** NOTE: this funtion does not initialize the Vtbl with usefull +** function pointers, only valid function pointers to avoid the +** horrible run-time crash when a call is made through the Vtbl with +** a NULL function pointer. this API is only necessary when +** initializing the Vtbl's in C. C++ guarantees that all interface +** functions (in C++ terms -- pure virtual functions) are implemented. +*/ + +STDAPI_(void) OleStdInitVtbl(LPVOID lpVtbl, UINT nSizeOfVtbl) +{ + LPVOID FAR* lpFuncPtrArr = (LPVOID FAR*)lpVtbl; + UINT nMethods = nSizeOfVtbl/sizeof(VOID FAR*); + UINT i; + + for (i = 0; i < nMethods; i++) { + lpFuncPtrArr[i] = OleStdNullMethod; + } +} + + +/* OleStdCheckVtbl +** --------------- +** +** Check if all entries in the Vtbl are properly initialized with +** valid function pointers. If any entries are either NULL or +** OleStdNullMethod, then this function returns FALSE. If compiled +** for _DEBUG this function reports which function pointers are +** invalid. +** +** RETURNS: TRUE if all entries in Vtbl are valid +** FALSE otherwise. +*/ + +STDAPI_(BOOL) OleStdCheckVtbl(LPVOID lpVtbl, UINT nSizeOfVtbl, LPTSTR lpszIface) +{ + LPVOID FAR* lpFuncPtrArr = (LPVOID FAR*)lpVtbl; + UINT nMethods = nSizeOfVtbl/sizeof(VOID FAR*); + UINT i; + BOOL fStatus = TRUE; + int nChar = 0; + + for (i = 0; i < nMethods; i++) { + if (lpFuncPtrArr[i] == NULL || lpFuncPtrArr[i] == OleStdNullMethod) { +#if defined( _DEBUG ) + TCHAR szBuf[256]; + wsprintf(szBuf, TEXT("%s::method# %d NOT valid!"), lpszIface, i); + OleDbgOut1((LPTSTR)szBuf); +#endif + fStatus = FALSE; + } + } + return fStatus; +} + + +/* OleStdNullMethod +** ---------------- +** Dummy method used by OleStdInitVtbl to initialize an interface +** Vtbl to ensure that there are no NULL function pointers in the +** Vtbl. All entries in the Vtbl are set to this function. this +** function issues a debug assert message (message box) and returns +** E_NOTIMPL if called. If all is done properly, this function will +** NEVER be called! +*/ +STDMETHODIMP OleStdNullMethod(LPUNKNOWN lpThis) +{ + MessageBox( + NULL, + TEXT("ERROR: INTERFACE METHOD NOT IMPLEMENTED!\r\n"), + NULL, + MB_SYSTEMMODAL | MB_ICONHAND | MB_OK + ); + + return ResultFromScode(E_NOTIMPL); +} + + + +static BOOL GetFileTimes(LPTSTR lpszFileName, FILETIME FAR* pfiletime) +{ +#ifdef WIN32 + WIN32_FIND_DATA fd; + HANDLE hFind; + hFind = FindFirstFile(lpszFileName,&fd); + if (hFind == NULL || hFind == INVALID_HANDLE_VALUE) { + return FALSE; + } + FindClose(hFind); + *pfiletime = fd.ftLastWriteTime; + return TRUE; +#else // !Win32 + static char sz[256]; + static struct _find_t fileinfo; + + LSTRCPYN((LPTSTR)sz, lpszFileName, sizeof(sz)-1); + sz[sizeof(sz)-1]= TEXT('\0'); + AnsiToOem(sz, sz); + return (_dos_findfirst(sz,_A_NORMAL|_A_HIDDEN|_A_SUBDIR|_A_SYSTEM, + (struct _find_t *)&fileinfo) == 0 && + CoDosDateTimeToFileTime(fileinfo.wr_date,fileinfo.wr_time,pfiletime)); +#endif // Win32 +} + + + +/* OleStdRegisterAsRunning +** ----------------------- +** Register a moniker in the RunningObjectTable. +** if there is an existing registration (*lpdwRegister!=NULL), then +** first revoke that registration. +** +** new dwRegister key is returned via *lpdwRegister parameter. +*/ +STDAPI_(void) OleStdRegisterAsRunning(LPUNKNOWN lpUnk, LPMONIKER lpmkFull, DWORD FAR* lpdwRegister) +{ + LPRUNNINGOBJECTTABLE lpROT; + HRESULT hrErr; + DWORD dwOldRegister = *lpdwRegister; + + OLEDBG_BEGIN2(TEXT("OleStdRegisterAsRunning\r\n")) + + OLEDBG_BEGIN2(TEXT("GetRunningObjectTable called\r\n")) + hrErr = GetRunningObjectTable(0,(LPRUNNINGOBJECTTABLE FAR*)&lpROT); + OLEDBG_END2 + + if (hrErr == NOERROR) { + + /* register as running if a valid moniker is passed + ** + ** OLE2NOTE: we deliberately register the new moniker BEFORE + ** revoking the old moniker just in case the object + ** currently has no external locks. if the object has no + ** locks then revoking it from the running object table will + ** cause the object's StubManager to initiate shutdown of + ** the object. + */ + if (lpmkFull) { + + OLEDBG_BEGIN2(TEXT("IRunningObjectTable::Register called\r\n")) + lpROT->lpVtbl->Register(lpROT, 0, lpUnk,lpmkFull,lpdwRegister); + OLEDBG_END2 + +#if defined(_DEBUG) + { + TCHAR szBuf[512]; + LPTSTR lpszDisplay; + LPBC lpbc; + +#ifdef OLE201 + CreateBindCtx(0, (LPBC FAR*)&lpbc); +#endif + + CallIMonikerGetDisplayNameA( + lpmkFull, + lpbc, + NULL, + &lpszDisplay + ); + OleStdRelease((LPUNKNOWN)lpbc); + wsprintf( + szBuf, + TEXT("Moniker '%s' REGISTERED as [0x%lx] in ROT\r\n"), + lpszDisplay, + *lpdwRegister + ); + OleDbgOut2(szBuf); + OleStdFreeString(lpszDisplay, NULL); + } +#endif // _DEBUG + + } + + // if already registered, revoke + if (dwOldRegister != 0) { + +#if defined(_DEBUG) + { + TCHAR szBuf[512]; + + wsprintf( + szBuf, + TEXT("Moniker [0x%lx] REVOKED from ROT\r\n"), + dwOldRegister + ); + OleDbgOut2(szBuf); + } +#endif // _DEBUG + + OLEDBG_BEGIN2(TEXT("IRunningObjectTable::Revoke called\r\n")) + lpROT->lpVtbl->Revoke(lpROT, dwOldRegister); + OLEDBG_END2 + } + + OleStdRelease((LPUNKNOWN)lpROT); + } else { + OleDbgAssertSz( + lpROT != NULL, + TEXT("OleStdRegisterAsRunning: GetRunningObjectTable FAILED\r\n") + ); + } + + OLEDBG_END2 +} + + + +/* OleStdRevokeAsRunning +** --------------------- +** Revoke a moniker from the RunningObjectTable if there is an +** existing registration (*lpdwRegister!=NULL). +** +** *lpdwRegister parameter will be set to NULL. +*/ +STDAPI_(void) OleStdRevokeAsRunning(DWORD FAR* lpdwRegister) +{ + LPRUNNINGOBJECTTABLE lpROT; + HRESULT hrErr; + + OLEDBG_BEGIN2(TEXT("OleStdRevokeAsRunning\r\n")) + + // if still registered, then revoke + if (*lpdwRegister != 0) { + + OLEDBG_BEGIN2(TEXT("GetRunningObjectTable called\r\n")) + hrErr = GetRunningObjectTable(0,(LPRUNNINGOBJECTTABLE FAR*)&lpROT); + OLEDBG_END2 + + if (hrErr == NOERROR) { + +#if defined(_DEBUG) + { + TCHAR szBuf[512]; + + wsprintf( + szBuf, + TEXT("Moniker [0x%lx] REVOKED from ROT\r\n"), + *lpdwRegister + ); + OleDbgOut2(szBuf); + } +#endif // _DEBUG + + OLEDBG_BEGIN2(TEXT("IRunningObjectTable::Revoke called\r\n")) + lpROT->lpVtbl->Revoke(lpROT, *lpdwRegister); + OLEDBG_END2 + + *lpdwRegister = 0; + + OleStdRelease((LPUNKNOWN)lpROT); + } else { + OleDbgAssertSz( + lpROT != NULL, + TEXT("OleStdRevokeAsRunning: GetRunningObjectTable FAILED\r\n") + ); + } + } + OLEDBG_END2 +} + + +/* OleStdNoteFileChangeTime +** ------------------------ +** Note the time a File-Based object has been saved in the +** RunningObjectTable. These change times are used as the basis for +** IOleObject::IsUpToDate. +** It is important to set the time of the file-based object +** following a save operation to exactly the time of the saved file. +** this helps IOleObject::IsUpToDate to give the correct answer +** after a file has been saved. +*/ +STDAPI_(void) OleStdNoteFileChangeTime(LPTSTR lpszFileName, DWORD dwRegister) +{ + if (dwRegister != 0) { + + LPRUNNINGOBJECTTABLE lprot; + FILETIME filetime; + + if (GetFileTimes(lpszFileName, &filetime) && + GetRunningObjectTable(0,&lprot) == NOERROR) + { + lprot->lpVtbl->NoteChangeTime( lprot, dwRegister, &filetime ); + lprot->lpVtbl->Release(lprot); + + OleDbgOut2(TEXT("IRunningObjectTable::NoteChangeTime called\r\n")); + } + } +} + + +/* OleStdNoteObjectChangeTime +** -------------------------- +** Set the last change time of an object that is registered in the +** RunningObjectTable. These change times are used as the basis for +** IOleObject::IsUpToDate. +** +** every time the object sends out a OnDataChange notification, it +** should update the Time of last change in the ROT. +** +** NOTE: this function set the change time to the current time. +*/ +STDAPI_(void) OleStdNoteObjectChangeTime(DWORD dwRegister) +{ + if (dwRegister != 0) { + + LPRUNNINGOBJECTTABLE lprot; + FILETIME filetime; + + if (GetRunningObjectTable(0,&lprot) == NOERROR) + { +#ifdef OLE201 + CoFileTimeNow( &filetime ); + lprot->lpVtbl->NoteChangeTime( lprot, dwRegister, &filetime ); +#endif + lprot->lpVtbl->Release(lprot); + + OleDbgOut2(TEXT("IRunningObjectTable::NoteChangeTime called\r\n")); + } + } +} + + +/* OleStdCreateTempFileMoniker +** --------------------------- +** return the next available FileMoniker that can be used as the +** name of an untitled document. +** the FileMoniker is built of the form: +** <lpszPrefixString><number> +** eg. "Outline1", "Outline2", etc. +** +** The RunningObjectTable (ROT) is consulted to determine if a +** FileMoniker is in use. If the name is in use then the number is +** incremented and the ROT is checked again. +** +** Parameters: +** LPSTR lpszPrefixString - prefix used to build the name +** UINT FAR* lpuUnique - (IN-OUT) last used number. +** this number is used to make the +** name unique. on entry, the input +** number is incremented. on output, +** the number used is returned. this +** number should be passed again +** unchanged on the next call. +** LPSTR lpszName - (OUT) buffer used to build string. +** caller must be sure buffer is large +** enough to hold the generated string. +** LPMONIKER FAR* lplpmk - (OUT) next unused FileMoniker +** +** Returns: +** void +** +** Comments: +** This function is similar in spirit to the Windows API +** CreateTempFileName. +*/ +STDAPI_(void) OleStdCreateTempFileMoniker( + LPTSTR lpszPrefixString, + UINT FAR* lpuUnique, + LPTSTR lpszName, + LPMONIKER FAR* lplpmk +) +{ + LPRUNNINGOBJECTTABLE lpROT = NULL; + UINT i = (lpuUnique != NULL ? *lpuUnique : 1); + HRESULT hrErr; + + wsprintf(lpszName, TEXT("%s%d"), lpszPrefixString, i++); + + CreateFileMonikerA(lpszName, lplpmk); + + + OLEDBG_BEGIN2(TEXT("GetRunningObjectTable called\r\n")) + hrErr = GetRunningObjectTable(0,(LPRUNNINGOBJECTTABLE FAR*)&lpROT); + OLEDBG_END2 + + if (hrErr == NOERROR) { + + while (1) { + if (! *lplpmk) + break; // failed to create FileMoniker + + OLEDBG_BEGIN2(TEXT("IRunningObjectTable::IsRunning called\r\n")) + hrErr = lpROT->lpVtbl->IsRunning(lpROT,*lplpmk); + OLEDBG_END2 + + if (hrErr != NOERROR) + break; // the Moniker is NOT running; found unused one! + + OleStdVerifyRelease( + (LPUNKNOWN)*lplpmk, + TEXT("OleStdCreateTempFileMoniker: Moniker NOT released") + ); + + wsprintf(lpszName, TEXT("%s%d"), lpszPrefixString, i++); + CreateFileMonikerA(lpszName, lplpmk); + } + + OleStdRelease((LPUNKNOWN)lpROT); + } + + if (lpuUnique != NULL) + *lpuUnique = i; +} + + +/* OleStdGetFirstMoniker +** --------------------- +** return the first piece of a moniker. +** +** NOTE: if the given moniker is not a generic composite moniker, +** then an AddRef'ed pointer to the given moniker is returned. +*/ +STDAPI_(LPMONIKER) OleStdGetFirstMoniker(LPMONIKER lpmk) +{ + LPMONIKER lpmkFirst = NULL; + LPENUMMONIKER lpenumMoniker; + DWORD dwMksys; + HRESULT hrErr; + + if (! lpmk) + return NULL; + + if (lpmk->lpVtbl->IsSystemMoniker(lpmk, (LPDWORD)&dwMksys) == NOERROR + && dwMksys == MKSYS_GENERICCOMPOSITE) { + + /* OLE2NOTE: the moniker is a GenericCompositeMoniker. + ** enumerate the moniker to pull off the first piece. + */ + + hrErr = lpmk->lpVtbl->Enum( + lpmk, + TRUE /* fForward */, + (LPENUMMONIKER FAR*)&lpenumMoniker + ); + if (hrErr != NOERROR) + return NULL; // ERROR: give up! + + hrErr = lpenumMoniker->lpVtbl->Next( + lpenumMoniker, + 1, + (LPMONIKER FAR*)&lpmkFirst, + NULL + ); + lpenumMoniker->lpVtbl->Release(lpenumMoniker); + return lpmkFirst; + + } else { + /* OLE2NOTE: the moniker is NOT a GenericCompositeMoniker. + ** return an AddRef'ed pointer to the input moniker. + */ + lpmk->lpVtbl->AddRef(lpmk); + return lpmk; + } +} + + +/* OleStdGetLenFilePrefixOfMoniker +** ------------------------------- +** if the first piece of the Moniker is a FileMoniker, then return +** the length of the filename string. +** +** lpmk pointer to moniker +** +** Returns +** 0 if moniker does NOT start with a FileMoniker +** uLen string length of filename prefix of the display name +** retrieved from the given (lpmk) moniker. +*/ +STDAPI_(ULONG) OleStdGetLenFilePrefixOfMoniker(LPMONIKER lpmk) +{ + LPMONIKER lpmkFirst = NULL; + DWORD dwMksys; + LPTSTR lpsz = NULL; + LPBC lpbc = NULL; + ULONG uLen = 0; + HRESULT hrErr; + + if (! lpmk) + return 0; + + lpmkFirst = OleStdGetFirstMoniker(lpmk); + if (lpmkFirst) { + if ( (lpmkFirst->lpVtbl->IsSystemMoniker( + lpmkFirst, (LPDWORD)&dwMksys) == NOERROR) + && dwMksys == MKSYS_FILEMONIKER) { + +#ifdef OLE201 + hrErr = CreateBindCtx(0, (LPBC FAR*)&lpbc); +#endif + if (hrErr == NOERROR) { + hrErr = CallIMonikerGetDisplayNameA(lpmkFirst, lpbc, NULL, + &lpsz); + + if (hrErr == NOERROR && lpsz != NULL) { + uLen = lstrlen(lpsz); + OleStdFreeString(lpsz, NULL); + } + OleStdRelease((LPUNKNOWN)lpbc); + } + } + lpmkFirst->lpVtbl->Release(lpmkFirst); + } + return uLen; +} + + +/* OleStdMkParseDisplayName +** Parse a string into a Moniker by calling the OLE API +** MkParseDisplayName. if the original link source class was an OLE1 +** class, then attempt the parsing assuming the same class applies. +** +** if the class of the previous link source was an OLE1 class, +** then first attempt to parse a string that it is qualified +** with the progID associated with the OLE1 class. this more +** closely matches the semantics of OLE1 where the class of +** link sources is not expected to change. prefixing the +** string with "@<ProgID -- OLE1 class name>!" will force the +** parsing of the string to assume the file is of that +** class. +** NOTE: this trick of prepending the string with "@<ProgID> +** only works for OLE1 classes. +** +** PARAMETERS: +** REFCLSID rClsid -- original class of link source. +** CLSID_NULL if class is unknown +** ... other parameters the same as MkParseDisplayName API ... +** +** RETURNS +** NOERROR if string parsed successfully +** else error code returned by MkParseDisplayName +*/ +STDAPI OleStdMkParseDisplayName( + REFCLSID rClsid, + LPBC lpbc, + LPTSTR lpszUserName, + ULONG FAR* lpchEaten, + LPMONIKER FAR* lplpmk +) +{ + HRESULT hrErr; + + if (!IsEqualCLSID(rClsid,&CLSID_NULL) && CoIsOle1Class(rClsid) && + lpszUserName[0] != '@') { + LPTSTR lpszBuf; + LPTSTR lpszProgID; + + // Prepend "@<ProgID>!" to the input string + ProgIDFromCLSIDA(rClsid, &lpszProgID); + + if (lpszProgID == NULL) + goto Cont1; + lpszBuf = OleStdMalloc( + ((ULONG)lstrlen(lpszUserName)+ +#ifdef UNICODE + // OLE in Win32 is always UNICODE + wcslen(lpszProgID) +#else + lstrlen(lpszProgID) +#endif + +3)*sizeof(TCHAR)); + if (lpszBuf == NULL) { + if (lpszProgID) + OleStdFree(lpszProgID); + goto Cont1; + } + + wsprintf(lpszBuf, TEXT("@%s!%s"), lpszProgID, lpszUserName); + + OLEDBG_BEGIN2(TEXT("MkParseDisplayName called\r\n")) + + hrErr = MkParseDisplayNameA(lpbc, lpszBuf, lpchEaten, lplpmk); + + OLEDBG_END2 + + if (lpszProgID) + OleStdFree(lpszProgID); + if (lpszBuf) + OleStdFree(lpszBuf); + + if (hrErr == NOERROR) + return NOERROR; + } + +Cont1: + OLEDBG_BEGIN2(TEXT("MkParseDisplayName called\r\n")) + + hrErr = MkParseDisplayNameA(lpbc, lpszUserName, lpchEaten, lplpmk); + + OLEDBG_END2 + + return hrErr; +} + + +/* + * 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; + long 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 == cfEmbeddedObject + || lpPriorityList[i].fmtetc.cfFormat == cfEmbedSource + || lpPriorityList[i].fmtetc.cfFormat == 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 == 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->lpVtbl->EnumFormatEtc( + lpSrcDataObj, + 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; + _fmemset(rgfmtetc,0,sizeof(rgfmtetc[FORMATETC_MAX]) ); + if (lpEnumFmtEtc->lpVtbl->Next( + lpEnumFmtEtc, 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(&rgfmtetc[j], &lpPriorityList[i].fmtetc)) + { + lpPriorityList[i].dwScratchSpace = TRUE; + } + } + } + } // endif + + // Clean up + if (lpEnumFmtEtc) + OleStdRelease((LPUNKNOWN)lpEnumFmtEtc); +} + + +/* OleStdGetPriorityClipboardFormat +** -------------------------------- +** +** Retrieve the first clipboard format in a list for which data +** exists in the source IDataObject*. +** +** Returns -1 if no acceptable match is found. +** index of first acceptable match in the priority list. +** +*/ +STDAPI_(int) OleStdGetPriorityClipboardFormat( + LPDATAOBJECT lpSrcDataObj, + LPOLEUIPASTEENTRY lpPriorityList, + int cEntries +) +{ + int i; + int nFmtEtc = -1; + + // Mark all entries that the Source provides + OleStdMarkPasteEntryList(lpSrcDataObj, lpPriorityList, cEntries); + + // Loop over the target's priority list of formats + for (i = 0; i < cEntries; i++) + { + if (lpPriorityList[i].dwFlags != OLEUIPASTE_PASTEONLY && + !(lpPriorityList[i].dwFlags & OLEUIPASTE_PASTE)) + continue; + + // get first marked entry + if (lpPriorityList[i].dwScratchSpace) { + nFmtEtc = i; + break; // Found priority format; DONE + } + } + + return nFmtEtc; +} + + +/* OleStdIsDuplicateFormat +** ----------------------- +** Returns TRUE if the lpFmtEtc->cfFormat is found in the array of +** FormatEtc structures. +*/ +STDAPI_(BOOL) OleStdIsDuplicateFormat( + LPFORMATETC lpFmtEtc, + LPFORMATETC arrFmtEtc, + int nFmtEtc +) +{ + int i; + + for (i = 0; i < nFmtEtc; i++) { + if (IsEqualFORMATETC((*lpFmtEtc), arrFmtEtc[i])) + return TRUE; + } + + return FALSE; +} + + +/* OleStdGetItemToken + * ------------------ + * + * LPTSTR lpszSrc - Pointer to a source string + * LPTSTR lpszDst - Pointer to destination buffer + * + * Will copy one token from the lpszSrc buffer to the lpszItem buffer. + * It considers all alpha-numeric and white space characters as valid + * characters for a token. the first non-valid character delimates the + * token. + * + * returns the number of charaters eaten. + */ +STDAPI_(ULONG) OleStdGetItemToken(LPTSTR lpszSrc, LPTSTR lpszDst, int nMaxChars) +{ + ULONG chEaten = 0L; + + // skip leading delimeter characters + while (*lpszSrc && --nMaxChars > 0 + && ((*lpszSrc==TEXT('/')) || (*lpszSrc==TEXT('\\')) || + (*lpszSrc==TEXT('!')) || (*lpszSrc==TEXT(':')))) { + *lpszSrc++; + chEaten++; + } + + // Extract token string (up to first delimeter char or EOS) + while (*lpszSrc && --nMaxChars > 0 + && !((*lpszSrc==TEXT('/')) || (*lpszSrc==TEXT('\\')) || + (*lpszSrc==TEXT('!')) || (*lpszSrc==TEXT(':')))) { + *lpszDst++ = *lpszSrc++; + chEaten++; + } + *lpszDst = TEXT('\0'); + return chEaten; +} + + +/************************************************************************* +** OleStdCreateRootStorage +** create a root level Storage given a filename that is compatible +** to be used by a top-level OLE container. if the filename +** specifies an existing file, then an error is returned. +** the root storage (Docfile) that is created by this function +** is suitable to be used to create child storages for embedings. +** (CreateChildStorage can be used to create child storages.) +** NOTE: the root-level storage is opened in transacted mode. +*************************************************************************/ + +STDAPI_(LPSTORAGE) OleStdCreateRootStorage(LPTSTR lpszStgName, DWORD grfMode) +{ + HRESULT hr; + DWORD grfCreateMode = STGM_READWRITE | STGM_TRANSACTED; + DWORD reserved = 0; + LPSTORAGE lpRootStg; + TCHAR szMsg[64]; + + // if temp file is being created, enable delete-on-release + if (! lpszStgName) + grfCreateMode |= STGM_DELETEONRELEASE; + + hr = StgCreateDocfileA( + lpszStgName, + grfMode | grfCreateMode, + reserved, + (LPSTORAGE FAR*)&lpRootStg + ); + + if (hr == NOERROR) + return lpRootStg; // existing file successfully opened + + OleDbgOutHResult(TEXT("StgCreateDocfile returned"), hr); + + if (0 == LoadString(ghInst, IDS_OLESTDNOCREATEFILE, (LPTSTR)szMsg, 64)) + return NULL; + + MessageBox(NULL, (LPTSTR)szMsg, NULL,MB_ICONEXCLAMATION | MB_OK); + return NULL; +} + + +/************************************************************************* +** OleStdOpenRootStorage +** open a root level Storage given a filename that is compatible +** to be used by a top-level OLE container. if the file does not +** exist then an error is returned. +** the root storage (Docfile) that is opened by this function +** is suitable to be used to create child storages for embedings. +** (CreateChildStorage can be used to create child storages.) +** NOTE: the root-level storage is opened in transacted mode. +*************************************************************************/ + +STDAPI_(LPSTORAGE) OleStdOpenRootStorage(LPTSTR lpszStgName, DWORD grfMode) +{ + HRESULT hr; + DWORD reserved = 0; + LPSTORAGE lpRootStg; + TCHAR szMsg[64]; + + if (lpszStgName) { + hr = StgOpenStorageA( + lpszStgName, + NULL, + grfMode | STGM_TRANSACTED, + NULL, + reserved, + (LPSTORAGE FAR*)&lpRootStg + ); + + if (hr == NOERROR) + return lpRootStg; // existing file successfully opened + + OleDbgOutHResult(TEXT("StgOpenStorage returned"), hr); + } + + if (0 == LoadString(ghInst, IDS_OLESTDNOOPENFILE, szMsg, 64)) + return NULL; + + MessageBox(NULL, (LPTSTR)szMsg, NULL,MB_ICONEXCLAMATION | MB_OK); + return NULL; +} + + +/************************************************************************* +** OpenOrCreateRootStorage +** open a root level Storage given a filename that is compatible +** to be used by a top-level OLE container. if the filename +** specifies an existing file, then it is open, otherwise a new file +** with the given name is created. +** the root storage (Docfile) that is created by this function +** is suitable to be used to create child storages for embedings. +** (CreateChildStorage can be used to create child storages.) +** NOTE: the root-level storage is opened in transacted mode. +*************************************************************************/ + +STDAPI_(LPSTORAGE) OleStdOpenOrCreateRootStorage(LPTSTR lpszStgName, DWORD grfMode) +{ + HRESULT hrErr; + SCODE sc; + DWORD reserved = 0; + LPSTORAGE lpRootStg; + TCHAR szMsg[64]; + + if (lpszStgName) { + + hrErr = StgOpenStorageA( + lpszStgName, + NULL, + grfMode | STGM_READWRITE | STGM_TRANSACTED, + NULL, + reserved, + (LPSTORAGE FAR*)&lpRootStg + ); + + if (hrErr == NOERROR) + return lpRootStg; // existing file successfully opened + + OleDbgOutHResult(TEXT("StgOpenStorage returned"), hrErr); + sc = GetScode(hrErr); + + if (sc!=STG_E_FILENOTFOUND && sc!=STG_E_FILEALREADYEXISTS) { + return NULL; + } + } + + /* if file did not already exist, try to create a new one */ + hrErr = StgCreateDocfileA( + lpszStgName, + grfMode | STGM_READWRITE | STGM_TRANSACTED, + reserved, + (LPSTORAGE FAR*)&lpRootStg + ); + + if (hrErr == NOERROR) + return lpRootStg; // existing file successfully opened + + OleDbgOutHResult(TEXT("StgCreateDocfile returned"), hrErr); + + if (0 == LoadString(ghInst, IDS_OLESTDNOCREATEFILE, (LPTSTR)szMsg, 64)) + return NULL; + + MessageBox(NULL, (LPTSTR)szMsg, NULL, MB_ICONEXCLAMATION | MB_OK); + return NULL; +} + + +/* +** OleStdCreateChildStorage +** create a child Storage inside the given lpStg that is compatible +** to be used by an embedded OLE object. the return value from this +** function can be passed to OleCreateXXX functions. +** NOTE: the child storage is opened in transacted mode. +*/ +STDAPI_(LPSTORAGE) OleStdCreateChildStorage(LPSTORAGE lpStg, LPTSTR lpszStgName) +{ + if (lpStg != NULL) { + LPSTORAGE lpChildStg; + DWORD grfMode = (STGM_READWRITE | STGM_TRANSACTED | + STGM_SHARE_EXCLUSIVE); + DWORD reserved = 0; + + HRESULT hrErr = CallIStorageCreateStorageA( + lpStg, + lpszStgName, + grfMode, + reserved, + reserved, + (LPSTORAGE FAR*)&lpChildStg + ); + + if (hrErr == NOERROR) + return lpChildStg; + + OleDbgOutHResult(TEXT("lpStg->lpVtbl->CreateStorage returned"), hrErr); + } + return NULL; +} + + +/* +** OleStdOpenChildStorage +** open a child Storage inside the given lpStg that is compatible +** to be used by an embedded OLE object. the return value from this +** function can be passed to OleLoad function. +** NOTE: the child storage is opened in transacted mode. +*/ +STDAPI_(LPSTORAGE) OleStdOpenChildStorage(LPSTORAGE lpStg, LPTSTR lpszStgName, DWORD grfMode) +{ + LPSTORAGE lpChildStg; + LPSTORAGE lpstgPriority = NULL; + DWORD reserved = 0; + HRESULT hrErr; + + if (lpStg != NULL) { + + hrErr = CallIStorageOpenStorageA( + lpStg, + lpszStgName, + lpstgPriority, + grfMode | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE, + NULL, + reserved, + (LPSTORAGE FAR*)&lpChildStg + ); + + if (hrErr == NOERROR) + return lpChildStg; + + OleDbgOutHResult(TEXT("lpStg->lpVtbl->OpenStorage returned"), hrErr); + } + return NULL; +} + + +/* OleStdCommitStorage +** ------------------- +** Commit the changes to the given IStorage*. This routine can be +** called on either a root-level storage as used by an OLE-Container +** or by a child storage as used by an embedded object. +** +** This routine first attempts to perform this commit in a safe +** manner. if this fails it then attempts to do the commit in a less +** robust manner (STGC_OVERWRITE). +*/ +STDAPI_(BOOL) OleStdCommitStorage(LPSTORAGE lpStg) +{ + HRESULT hrErr; + + // make the changes permanent + hrErr = lpStg->lpVtbl->Commit(lpStg, 0); + + if (GetScode(hrErr) == STG_E_MEDIUMFULL) { + // try to commit changes in less robust manner. + OleDbgOut(TEXT("Warning: commiting with STGC_OVERWRITE specified\n")); + hrErr = lpStg->lpVtbl->Commit(lpStg, STGC_OVERWRITE); + } + + if (hrErr != NOERROR) + { + TCHAR szMsg[64]; + + if (0 == LoadString(ghInst, IDS_OLESTDDISKFULL, (LPTSTR)szMsg, 64)) + return FALSE; + + MessageBox(NULL, (LPTSTR)szMsg, NULL, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + else { + return TRUE; + } +} + + +/* OleStdDestroyAllElements +** ------------------------ +** Destroy all elements within an open storage. this is subject +** to the current transaction. +*/ +STDAPI OleStdDestroyAllElements(LPSTORAGE lpStg) +{ + IEnumSTATSTG FAR* lpEnum; + STATSTG sstg; + HRESULT hrErr; + + hrErr = lpStg->lpVtbl->EnumElements( + lpStg, 0, NULL, 0, (IEnumSTATSTG FAR* FAR*)&lpEnum); + + if (hrErr != NOERROR) + return hrErr; + + while (1) { + if (lpEnum->lpVtbl->Next(lpEnum, 1, &sstg, NULL) != NOERROR) + break; + lpStg->lpVtbl->DestroyElement(lpStg, sstg.pwcsName); + OleStdFree(sstg.pwcsName); + } + lpEnum->lpVtbl->Release(lpEnum); + return NOERROR; +} + +// 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/oleutest/letest/ole2ui/olestd.h b/private/oleutest/letest/ole2ui/olestd.h new file mode 100644 index 000000000..7ca92fcbf --- /dev/null +++ b/private/oleutest/letest/ole2ui/olestd.h @@ -0,0 +1,852 @@ +/************************************************************************* +** +** OLE 2.0 Standard Utilities +** +** 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 - 1992 All Rights Reserved +** +*************************************************************************/ + +#if !defined( _OLESTD_H_ ) +#define _OLESTD_H_ + +#ifndef RC_INVOKED +#pragma message ("INCLUDING OLESTD.H from " __FILE__) +#endif /* RC_INVOKED */ + +#if defined( __TURBOC__ ) || defined( WIN32 ) +#define _based(a) +#endif + +#ifndef RC_INVOKED +#include <dos.h> // needed for filetime +#endif /* RC_INVOKED */ + +#include <commdlg.h> // needed for LPPRINTDLG +#include <shellapi.h> // needed for HKEY + +// String table defines... +#define IDS_OLESTDNOCREATEFILE 700 +#define IDS_OLESTDNOOPENFILE 701 +#define IDS_OLESTDDISKFULL 702 + + +/* + * Some C interface declaration stuff + */ + +#if ! defined(__cplusplus) +typedef struct tagINTERFACEIMPL { + IUnknownVtbl FAR* lpVtbl; + LPVOID lpBack; + int cRef; // interface specific ref count. +} INTERFACEIMPL, FAR* LPINTERFACEIMPL; + +#define INIT_INTERFACEIMPL(lpIFace, pVtbl, pBack) \ + ((lpIFace)->lpVtbl = pVtbl, \ + ((LPINTERFACEIMPL)(lpIFace))->lpBack = (LPVOID)pBack, \ + ((LPINTERFACEIMPL)(lpIFace))->cRef = 0 \ + ) + +#if defined( _DEBUG ) +#define OleDbgQueryInterfaceMethod(lpUnk) \ + ((lpUnk) != NULL ? ((LPINTERFACEIMPL)(lpUnk))->cRef++ : 0) +#define OleDbgAddRefMethod(lpThis, iface) \ + ((LPINTERFACEIMPL)(lpThis))->cRef++ + +#if _DEBUGLEVEL >= 2 +#define OleDbgReleaseMethod(lpThis, iface) \ + (--((LPINTERFACEIMPL)(lpThis))->cRef == 0 ? \ + OleDbgOut("\t" iface "* RELEASED (cRef == 0)\r\n"),1 : \ + (((LPINTERFACEIMPL)(lpThis))->cRef < 0) ? \ + ( \ + DebugBreak(), \ + OleDbgOut( \ + "\tERROR: " iface "* RELEASED TOO MANY TIMES\r\n") \ + ),1 : \ + 1) + +#else // if _DEBUGLEVEL < 2 +#define OleDbgReleaseMethod(lpThis, iface) \ + (--((LPINTERFACEIMPL)(lpThis))->cRef == 0 ? \ + 1 : \ + (((LPINTERFACEIMPL)(lpThis))->cRef < 0) ? \ + ( \ + OleDbgOut( \ + "\tERROR: " iface "* RELEASED TOO MANY TIMES\r\n") \ + ),1 : \ + 1) + +#endif // if _DEBUGLEVEL < 2 + +#else // ! defined (_DEBUG) + +#define OleDbgQueryInterfaceMethod(lpUnk) +#define OleDbgAddRefMethod(lpThis, iface) +#define OleDbgReleaseMethod(lpThis, iface) + +#endif // if defined( _DEBUG ) + +#endif // ! defined(__cplusplus) + +/* + * Some docfiles stuff + */ + +#define STGM_DFRALL (STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE) +#define STGM_DFALL (STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE) +#define STGM_SALL (STGM_READWRITE | STGM_SHARE_EXCLUSIVE) + +/* + * Some moniker stuff + */ + +// Delimeter used to separate ItemMoniker pieces of a composite moniker +#if defined( _MAC ) +#define OLESTDDELIM ":" +#else +#define OLESTDDELIM TEXT("\\") +#endif + +/* + * Some Concurrency stuff + */ + +/* standard Delay (in msec) to wait before retrying an LRPC call. +** this value is returned from IMessageFilter::RetryRejectedCall +*/ +#define OLESTDRETRYDELAY (DWORD)5000 + +/* Cancel the pending outgoing LRPC call. +** this value is returned from IMessageFilter::RetryRejectedCall +*/ +#define OLESTDCANCELRETRY (DWORD)-1 + +/* + * Some Icon support stuff. + * + * The following API's are now OBSOLETE because equivalent API's have been + * added to the OLE2.DLL library + * GetIconOfFile superceeded by OleGetIconOfFile + * GetIconOfClass superceeded by OleGetIconOfClass + * OleUIMetafilePictFromIconAndLabel + * superceeded by OleMetafilePictFromIconAndLabel + * + * The following macros are defined for backward compatibility with previous + * versions of the OLE2UI library. It is recommended that the new Ole* API's + * should be used instead. + */ +#define GetIconOfFile(hInst, lpszFileName, fUseFileAsLabel) \ + OleGetIconOfFileA(lpszFileName, fUseFileAsLabel) + +#define GetIconOfClass(hInst, rclsid, lpszLabel, fUseTypeAsLabel) \ + OleGetIconOfClassA(rclsid, lpszLabel, fUseTypeAsLabel) + +#define OleUIMetafilePictFromIconAndLabel(hIcon,pszLabel,pszSourceFile,iIcon)\ + OleMetafilePictFromIconAndLabelA(hIcon, pszLabel, pszSourceFile, iIcon) + + +/* + * Some Clipboard Copy/Paste & Drag/Drop support stuff + */ + +//Macro to set all FormatEtc fields +#define SETFORMATETC(fe, cf, asp, td, med, li) \ + ((fe).cfFormat=cf, \ + (fe).dwAspect=asp, \ + (fe).ptd=td, \ + (fe).tymed=med, \ + (fe).lindex=li) + +//Macro to set interesting FormatEtc fields defaulting the others. +#define SETDEFAULTFORMATETC(fe, cf, med) \ + ((fe).cfFormat=cf, \ + (fe).dwAspect=DVASPECT_CONTENT, \ + (fe).ptd=NULL, \ + (fe).tymed=med, \ + (fe).lindex=-1) + +// Macro to test if two FormatEtc structures are an exact match +#define IsEqualFORMATETC(fe1, fe2) \ + (OleStdCompareFormatEtc(&(fe1), &(fe2))==0) + +// Clipboard format strings +#define CF_EMBEDSOURCE TEXT("Embed Source") +#define CF_EMBEDDEDOBJECT TEXT("Embedded Object") +#define CF_LINKSOURCE TEXT("Link Source") +#define CF_CUSTOMLINKSOURCE TEXT("Custom 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 OleStdQueryOleObjectData(lpformatetc) \ + (((lpformatetc)->tymed & TYMED_ISTORAGE) ? \ + NOERROR : ResultFromScode(DV_E_FORMATETC)) + +#define OleStdQueryLinkSourceData(lpformatetc) \ + (((lpformatetc)->tymed & TYMED_ISTREAM) ? \ + NOERROR : ResultFromScode(DV_E_FORMATETC)) + +#define OleStdQueryObjectDescriptorData(lpformatetc) \ + (((lpformatetc)->tymed & TYMED_HGLOBAL) ? \ + NOERROR : ResultFromScode(DV_E_FORMATETC)) + +#define OleStdQueryFormatMedium(lpformatetc, tymd) \ + (((lpformatetc)->tymed & tymd) ? \ + NOERROR : ResultFromScode(DV_E_FORMATETC)) + +// Make an independent copy of a MetafilePict +#define OleStdCopyMetafilePict(hpictin, phpictout) \ + (*(phpictout) = OleDuplicateData(hpictin,CF_METAFILEPICT,GHND|GMEM_SHARE)) + + +// REVIEW: these need to be added to OLE2.H +#if !defined( DD_DEFSCROLLINTERVAL ) +#define DD_DEFSCROLLINTERVAL 50 +#endif + +#if !defined( DD_DEFDRAGDELAY ) +#define DD_DEFDRAGDELAY 200 +#endif + +#if !defined( DD_DEFDRAGMINDIST ) +#define DD_DEFDRAGMINDIST 2 +#endif + + +/* OleStdGetDropEffect +** ------------------- +** +** Convert a keyboard state into a DROPEFFECT. +** +** returns the DROPEFFECT value derived from the key state. +** the following is the standard interpretation: +** no modifier -- Default Drop (NULL is returned) +** CTRL -- DROPEFFECT_COPY +** SHIFT -- DROPEFFECT_MOVE +** CTRL-SHIFT -- DROPEFFECT_LINK +** +** Default Drop: this depends on the type of the target application. +** this is re-interpretable by each target application. a typical +** interpretation is if the drag is local to the same document +** (which is source of the drag) then a MOVE operation is +** performed. if the drag is not local, then a COPY operation is +** performed. +*/ +#define OleStdGetDropEffect(grfKeyState) \ + ( (grfKeyState & MK_CONTROL) ? \ + ( (grfKeyState & MK_SHIFT) ? DROPEFFECT_LINK : DROPEFFECT_COPY ) : \ + ( (grfKeyState & MK_SHIFT) ? DROPEFFECT_MOVE : 0 ) ) + + +/* The OLEUIPASTEFLAG enumeration is used by the OLEUIPASTEENTRY structure. + * + * OLEUIPASTE_ENABLEICON If the container does not specify this flag for the entry in the + * OLEUIPASTEENTRY array passed as input to OleUIPasteSpecial, the DisplayAsIcon button will be + * unchecked and disabled when the the user selects the format that corresponds to the entry. + * + * OLEUIPASTE_PASTEONLY Indicates that the entry in the OLEUIPASTEENTRY array is valid for pasting only. + * OLEUIPASTE_PASTE Indicates that the entry in the OLEUIPASTEENTRY array is valid for pasting. It + * may also be valid for linking if any of the following linking flags are specified. + * + * If the entry in the OLEUIPASTEENTRY array is valid for linking, the following flags indicate which link + * types are acceptable by OR'ing together the appropriate OLEUIPASTE_LINKTYPE<#> values. + * These values correspond as follows to the array of link types passed to OleUIPasteSpecial: + * OLEUIPASTE_LINKTYPE1=arrLinkTypes[0] + * OLEUIPASTE_LINKTYPE2=arrLinkTypes[1] + * OLEUIPASTE_LINKTYPE3=arrLinkTypes[2] + * OLEUIPASTE_LINKTYPE4=arrLinkTypes[3] + * OLEUIPASTE_LINKTYPE5=arrLinkTypes[4] + * OLEUIPASTE_LINKTYPE6=arrLinkTypes[5] + * OLEUIPASTE_LINKTYPE7=arrLinkTypes[6] + * OLEUIPASTE_LINKTYPE8=arrLinkTypes[7] + * + * where, + * UINT arrLinkTypes[8] is an array of registered clipboard formats for linking. A maximium of 8 link + * types are allowed. + */ + +typedef enum tagOLEUIPASTEFLAG +{ + OLEUIPASTE_ENABLEICON = 2048, // enable display as icon + OLEUIPASTE_PASTEONLY = 0, + OLEUIPASTE_PASTE = 512, + OLEUIPASTE_LINKANYTYPE = 1024, + OLEUIPASTE_LINKTYPE1 = 1, + OLEUIPASTE_LINKTYPE2 = 2, + OLEUIPASTE_LINKTYPE3 = 4, + OLEUIPASTE_LINKTYPE4 = 8, + OLEUIPASTE_LINKTYPE5 = 16, + OLEUIPASTE_LINKTYPE6 = 32, + OLEUIPASTE_LINKTYPE7 = 64, + OLEUIPASTE_LINKTYPE8 = 128 +} OLEUIPASTEFLAG; + +/* + * PasteEntry structure + * -------------------- + * An array of OLEUIPASTEENTRY entries is specified for the PasteSpecial dialog + * box. Each entry includes a FORMATETC which specifies the formats that are + * acceptable, a string that is to represent the format in the dialog's list + * box, a string to customize the result text of the dialog and a set of flags + * from the OLEUIPASTEFLAG enumeration. The flags indicate if the entry is + * valid for pasting only, linking only or both pasting and linking. If the + * entry is valid for linking, the flags indicate which link types are + * acceptable by OR'ing together the appropriate OLEUIPASTE_LINKTYPE<#> values. + * These values correspond to the array of link types as follows: + * OLEUIPASTE_LINKTYPE1=arrLinkTypes[0] + * OLEUIPASTE_LINKTYPE2=arrLinkTypes[1] + * OLEUIPASTE_LINKTYPE3=arrLinkTypes[2] + * OLEUIPASTE_LINKTYPE4=arrLinkTypes[3] + * OLEUIPASTE_LINKTYPE5=arrLinkTypes[4] + * OLEUIPASTE_LINKTYPE6=arrLinkTypes[5] + * OLEUIPASTE_LINKTYPE7=arrLinkTypes[6] + * OLEUIPASTE_LINKTYPE8=arrLinkTypes[7] + * UINT arrLinkTypes[8]; is an array of registered clipboard formats + * for linking. A maximium of 8 link types are allowed. + */ + +typedef struct tagOLEUIPASTEENTRY +{ + FORMATETC fmtetc; // Format that is acceptable. The paste + // dialog checks if this format is + // offered by the object on the + // clipboard and if so offers it for + // selection to the user. + LPCTSTR lpstrFormatName; // String that represents the format to the user. Any %s + // in this string is replaced by the FullUserTypeName + // of the object on the clipboard and the resulting string + // is placed in the list box of the dialog. Atmost + // one %s is allowed. The presence or absence of %s indicates + // if the result text is to indicate that data is + // being pasted or that an object that can be activated by + // an application is being pasted. If %s is + // present, the result-text says that an object is being pasted. + // Otherwise it says that data is being pasted. + LPCTSTR lpstrResultText; // String to customize the result text of the dialog when + // the user selects the format correspoding to this + // entry. Any %s in this string is replaced by the the application + // name or FullUserTypeName of the object on + // the clipboard. Atmost one %s is allowed. + DWORD dwFlags; // Values from OLEUIPASTEFLAG enum + DWORD dwScratchSpace; // Scratch space available to be used + // by routines which loop through an + // IEnumFORMATETC* to mark if the + // PasteEntry format is available. + // this field CAN be left uninitialized. +} OLEUIPASTEENTRY, *POLEUIPASTEENTRY, FAR *LPOLEUIPASTEENTRY; + +#define OLESTDDROP_NONE 0 +#define OLESTDDROP_DEFAULT 1 +#define OLESTDDROP_NONDEFAULT 2 + + +/* + * Some misc stuff + */ + +#define EMBEDDINGFLAG "Embedding" // Cmd line switch for launching a srvr + +#define HIMETRIC_PER_INCH 2540 // number HIMETRIC units per inch +#define PTS_PER_INCH 72 // number points (font size) per inch + +#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) +#define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH) + +// Returns TRUE if all fields of the two Rect's are equal, else FALSE. +#define AreRectsEqual(lprc1, lprc2) \ + (((lprc1->top == lprc2->top) && \ + (lprc1->left == lprc2->left) && \ + (lprc1->right == lprc2->right) && \ + (lprc1->bottom == lprc2->bottom)) ? TRUE : FALSE) + +/* lstrcpyn is defined to be able to handle UNICODE string + * The third parameter here is the number of CHARACTERS that are + * to be copied. + */ +#define LSTRCPYN(lpdst, lpsrc, cch) \ +(\ + (lpdst)[(cch)-1] = '\0', \ + (cch>1 ? lstrcpyn(lpdst, lpsrc, (cch)-1) : 0)\ +) + + +/****** DEBUG Stuff *****************************************************/ + +#ifdef _DEBUG + +#if !defined( _DBGTRACE ) +#define _DEBUGLEVEL 2 +#else +#define _DEBUGLEVEL _DBGTRACE +#endif + + +#if defined( NOASSERT ) + +#define OLEDBGASSERTDATA +#define OleDbgAssert(a) +#define OleDbgAssertSz(a, b) +#define OleDbgVerify(a) +#define OleDbgVerifySz(a, b) + +#else // ! NOASSERT + +STDAPI FnAssert(LPSTR lpstrExpr, LPSTR lpstrMsg, LPSTR lpstrFileName, UINT iLine); + +#define OLEDBGASSERTDATA \ + static char _based(_segname("_CODE")) _szAssertFile[]= TEXT(__FILE__); + +#define OleDbgAssert(a) \ + (!(a) ? FnAssert(#a, NULL, _szAssertFile, __LINE__) : (HRESULT)1) + +#define OleDbgAssertSz(a, b) \ + (!(a) ? FnAssert(#a, b, _szAssertFile, __LINE__) : (HRESULT)1) + +#define OleDbgVerify(a) \ + OleDbgAssert(a) + +#define OleDbgVerifySz(a, b) \ + OleDbgAssertSz(a, b) + +#endif // ! NOASSERT + +#ifdef DLL_VER +#define OLEDBGDATA_MAIN(szPrefix) \ + TCHAR NEAR g_szDbgPrefix[] = szPrefix; \ + OLEDBGASSERTDATA +#define OLEDBGDATA \ + extern TCHAR NEAR g_szDbgPrefix[]; \ + OLEDBGASSERTDATA +#else +#define OLEDBGDATA_MAIN(szPrefix) \ + TCHAR g_szDbgPrefix[] = szPrefix; \ + OLEDBGASSERTDATA +#define OLEDBGDATA \ + extern TCHAR g_szDbgPrefix[]; \ + OLEDBGASSERTDATA +#endif + +#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.C +STDAPI_(int) SetDCToAnisotropic(HDC hDC, LPRECT lprcPhysical, LPRECT lprcLogical, LPRECT lprcWindowOld, LPRECT lprcViewportOld); +STDAPI_(int) SetDCToDrawInHimetricRect(HDC, LPRECT, LPRECT, LPRECT, LPRECT); +STDAPI_(int) ResetOrigDC(HDC, int, LPRECT, LPRECT); + +STDAPI_(int) XformWidthInHimetricToPixels(HDC, int); +STDAPI_(int) XformWidthInPixelsToHimetric(HDC, int); +STDAPI_(int) XformHeightInHimetricToPixels(HDC, int); +STDAPI_(int) XformHeightInPixelsToHimetric(HDC, int); + +STDAPI_(void) XformRectInPixelsToHimetric(HDC, LPRECT, LPRECT); +STDAPI_(void) XformRectInHimetricToPixels(HDC, LPRECT, LPRECT); +STDAPI_(void) XformSizeInPixelsToHimetric(HDC, LPSIZEL, LPSIZEL); +STDAPI_(void) XformSizeInHimetricToPixels(HDC, LPSIZEL, LPSIZEL); +STDAPI_(int) XformWidthInHimetricToPixels(HDC, int); +STDAPI_(int) XformWidthInPixelsToHimetric(HDC, int); +STDAPI_(int) XformHeightInHimetricToPixels(HDC, int); +STDAPI_(int) XformHeightInPixelsToHimetric(HDC, int); + +STDAPI_(void) ParseCmdLine(LPSTR, BOOL FAR *, LPSTR); + +STDAPI_(BOOL) OleStdIsOleLink(LPUNKNOWN lpUnk); +STDAPI_(LPUNKNOWN) OleStdQueryInterface(LPUNKNOWN lpUnk, REFIID riid); +STDAPI_(LPSTORAGE) OleStdCreateRootStorage(LPTSTR lpszStgName, DWORD grfMode); +STDAPI_(LPSTORAGE) OleStdOpenRootStorage(LPTSTR lpszStgName, DWORD grfMode); +STDAPI_(LPSTORAGE) OleStdOpenOrCreateRootStorage(LPTSTR lpszStgName, DWORD grfMode); +STDAPI_(LPSTORAGE) OleStdCreateChildStorage(LPSTORAGE lpStg, LPTSTR lpszStgName); +STDAPI_(LPSTORAGE) OleStdOpenChildStorage(LPSTORAGE lpStg, LPTSTR lpszStgName, DWORD grfMode); +STDAPI_(BOOL) OleStdCommitStorage(LPSTORAGE lpStg); +STDAPI OleStdDestroyAllElements(LPSTORAGE lpStg); + +STDAPI_(LPSTORAGE) OleStdCreateStorageOnHGlobal( + HANDLE hGlobal, + BOOL fDeleteOnRelease, + DWORD dwgrfMode +); +STDAPI_(LPSTORAGE) OleStdCreateTempStorage(BOOL fUseMemory, DWORD grfMode); +STDAPI OleStdDoConvert(LPSTORAGE lpStg, REFCLSID rClsidNew); +STDAPI_(BOOL) OleStdGetTreatAsFmtUserType( + REFCLSID rClsidApp, + LPSTORAGE lpStg, + CLSID FAR* lpclsid, + CLIPFORMAT FAR* lpcfFmt, + LPTSTR FAR* lplpszType +); +STDAPI OleStdDoTreatAsClass(LPTSTR lpszUserType, REFCLSID rclsid, REFCLSID rclsidNew); +STDAPI_(BOOL) OleStdSetupAdvises(LPOLEOBJECT lpOleObject, DWORD dwDrawAspect, + LPTSTR lpszContainerApp, LPTSTR lpszContainerObj, + LPADVISESINK lpAdviseSink, BOOL fCreate); +STDAPI OleStdSwitchDisplayAspect( + LPOLEOBJECT lpOleObj, + LPDWORD lpdwCurAspect, + DWORD dwNewAspect, + HGLOBAL hMetaPict, + BOOL fDeleteOldAspect, + BOOL fSetupViewAdvise, + LPADVISESINK lpAdviseSink, + BOOL FAR* lpfMustUpdate +); +STDAPI OleStdSetIconInCache(LPOLEOBJECT lpOleObj, HGLOBAL hMetaPict); +STDAPI_(HGLOBAL) OleStdGetData( + LPDATAOBJECT lpDataObj, + CLIPFORMAT cfFormat, + DVTARGETDEVICE FAR* lpTargetDevice, + DWORD dwAspect, + LPSTGMEDIUM lpMedium +); +STDAPI_(void) OleStdMarkPasteEntryList( + LPDATAOBJECT lpSrcDataObj, + LPOLEUIPASTEENTRY lpPriorityList, + int cEntries +); +STDAPI_(int) OleStdGetPriorityClipboardFormat( + LPDATAOBJECT lpSrcDataObj, + LPOLEUIPASTEENTRY lpPriorityList, + int cEntries +); +STDAPI_(BOOL) OleStdIsDuplicateFormat( + LPFORMATETC lpFmtEtc, + LPFORMATETC arrFmtEtc, + int nFmtEtc +); +STDAPI_(void) OleStdRegisterAsRunning(LPUNKNOWN lpUnk, LPMONIKER lpmkFull, DWORD FAR* lpdwRegister); +STDAPI_(void) OleStdRevokeAsRunning(DWORD FAR* lpdwRegister); +STDAPI_(void) OleStdNoteFileChangeTime(LPTSTR lpszFileName, DWORD dwRegister); +STDAPI_(void) OleStdNoteObjectChangeTime(DWORD dwRegister); +STDAPI OleStdGetOleObjectData( + LPPERSISTSTORAGE lpPStg, + LPFORMATETC lpformatetc, + LPSTGMEDIUM lpMedium, + BOOL fUseMemory +); +STDAPI OleStdGetLinkSourceData( + LPMONIKER lpmk, + LPCLSID lpClsID, + LPFORMATETC lpformatetc, + LPSTGMEDIUM lpMedium +); +STDAPI_(HGLOBAL) OleStdGetObjectDescriptorData( + CLSID clsid, + DWORD dwAspect, + SIZEL sizel, + POINTL pointl, + DWORD dwStatus, + LPTSTR lpszFullUserTypeName, + LPTSTR lpszSrcOfCopy +); +STDAPI_(HGLOBAL) OleStdGetObjectDescriptorDataFromOleObject( + LPOLEOBJECT lpOleObj, + LPTSTR lpszSrcOfCopy, + DWORD dwAspect, + POINTL pointl, + LPSIZEL lpSizelHim +); +STDAPI_(HGLOBAL) OleStdFillObjectDescriptorFromData( + LPDATAOBJECT lpDataObject, + LPSTGMEDIUM lpmedium, + CLIPFORMAT FAR* lpcfFmt +); +STDAPI_(HANDLE) OleStdGetMetafilePictFromOleObject( + LPOLEOBJECT lpOleObj, + DWORD dwDrawAspect, + LPSIZEL lpSizelHim, + DVTARGETDEVICE FAR* ptd +); + +STDAPI_(void) OleStdCreateTempFileMoniker(LPTSTR lpszPrefixString, UINT FAR* lpuUnique, LPTSTR lpszName, LPMONIKER FAR* lplpmk); +STDAPI_(LPMONIKER) OleStdGetFirstMoniker(LPMONIKER lpmk); +STDAPI_(ULONG) OleStdGetLenFilePrefixOfMoniker(LPMONIKER lpmk); +STDAPI OleStdMkParseDisplayName( + REFCLSID rClsid, + LPBC lpbc, + LPTSTR lpszUserName, + ULONG FAR* lpchEaten, + LPMONIKER FAR* lplpmk +); +STDAPI_(LPVOID) OleStdMalloc(ULONG ulSize); +STDAPI_(LPVOID) OleStdRealloc(LPVOID pmem, ULONG ulSize); +STDAPI_(void) OleStdFree(LPVOID pmem); +STDAPI_(ULONG) OleStdGetSize(LPVOID pmem); +STDAPI_(void) OleStdFreeString(LPTSTR lpsz, LPMALLOC lpMalloc); +STDAPI_(LPTSTR) OleStdCopyString(LPTSTR lpszSrc, LPMALLOC lpMalloc); +STDAPI_(ULONG) OleStdGetItemToken(LPTSTR lpszSrc, LPTSTR lpszDst,int nMaxChars); + +STDAPI_(UINT) OleStdIconLabelTextOut(HDC hDC, + HFONT hFont, + int nXStart, + int nYStart, + UINT fuOptions, + RECT FAR * lpRect, + LPTSTR lpszString, + UINT cchString, + int FAR * lpDX); + +// registration database query functions +STDAPI_(UINT) OleStdGetAuxUserType(REFCLSID rclsid, + WORD wAuxUserType, + LPTSTR lpszAuxUserType, + int cch, + HKEY hKey); + +STDAPI_(UINT) OleStdGetUserTypeOfClass(REFCLSID rclsid, + LPTSTR lpszUserType, + UINT cch, + HKEY hKey); + +STDAPI_(BOOL) OleStdGetMiscStatusOfClass(REFCLSID, HKEY, DWORD FAR *); +STDAPI_(CLIPFORMAT) OleStdGetDefaultFileFormatOfClass( + REFCLSID rclsid, + HKEY hKey +); + +STDAPI_(void) OleStdInitVtbl(LPVOID lpVtbl, UINT nSizeOfVtbl); +STDMETHODIMP OleStdNullMethod(LPUNKNOWN lpThis); +STDAPI_(BOOL) OleStdCheckVtbl(LPVOID lpVtbl, UINT nSizeOfVtbl, LPTSTR lpszIface); +STDAPI_(ULONG) OleStdVerifyRelease(LPUNKNOWN lpUnk, LPTSTR lpszMsg); +STDAPI_(ULONG) OleStdRelease(LPUNKNOWN lpUnk); + +STDAPI_(HDC) OleStdCreateDC(DVTARGETDEVICE FAR* ptd); +STDAPI_(HDC) OleStdCreateIC(DVTARGETDEVICE FAR* ptd); +STDAPI_(DVTARGETDEVICE FAR*) OleStdCreateTargetDevice(LPPRINTDLG lpPrintDlg); +STDAPI_(BOOL) OleStdDeleteTargetDevice(DVTARGETDEVICE FAR* ptd); +STDAPI_(DVTARGETDEVICE FAR*) OleStdCopyTargetDevice(DVTARGETDEVICE FAR* ptdSrc); +STDAPI_(BOOL) OleStdCopyFormatEtc(LPFORMATETC petcDest, LPFORMATETC petcSrc); +STDAPI_(int) OleStdCompareFormatEtc(FORMATETC FAR* pFetcLeft, FORMATETC FAR* pFetcRight); +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); + +// debug implementation of the IMalloc interface. +STDAPI OleStdCreateDbAlloc(ULONG reserved, IMalloc FAR* FAR* ppmalloc); + + +STDAPI_(LPENUMFORMATETC) + OleStdEnumFmtEtc_Create(ULONG nCount, LPFORMATETC lpEtc); + +STDAPI_(LPENUMSTATDATA) + OleStdEnumStatData_Create(ULONG nCount, LPSTATDATA lpStat); + +STDAPI_(BOOL) + OleStdCopyStatData(LPSTATDATA pDest, LPSTATDATA pSrc); + +STDAPI_(HPALETTE) + OleStdCreateStandardPalette(void); + +#if defined( OBSOLETE ) + +/************************************************************************* +** The following API's have been converted into macros: +** OleStdQueryOleObjectData +** OleStdQueryLinkSourceData +** OleStdQueryObjectDescriptorData +** OleStdQueryFormatMedium +** OleStdCopyMetafilePict +** AreRectsEqual +** OleStdGetDropEffect +** +** These macros are defined above +*************************************************************************/ +STDAPI_(BOOL) AreRectsEqual(LPRECT lprc1, LPRECT lprc2); +STDAPI_(BOOL) OleStdCopyMetafilePict(HANDLE hpictin, HANDLE FAR* phpictout); +STDAPI OleStdQueryOleObjectData(LPFORMATETC lpformatetc); +STDAPI OleStdQueryLinkSourceData(LPFORMATETC lpformatetc); +STDAPI OleStdQueryObjectDescriptorData(LPFORMATETC lpformatetc); +STDAPI OleStdQueryFormatMedium(LPFORMATETC lpformatetc, TYMED tymed); +STDAPI_(DWORD) OleStdGetDropEffect ( DWORD grfKeyState ); +#endif // OBSOLETE + + +#endif // _OLESTD_H_ + diff --git a/private/oleutest/letest/ole2ui/olestr.c b/private/oleutest/letest/ole2ui/olestr.c new file mode 100644 index 000000000..e7e8e93fa --- /dev/null +++ b/private/oleutest/letest/ole2ui/olestr.c @@ -0,0 +1,32 @@ +void CopyAndFreeOLESTR(LPOLESTR polestr, char **ppszOut) +{ + // See if there is any work + if (polestr == NULL) + { + if (ppszOut != NULL) + { + // Output string requested so set it to NULL. + *ppszOut = NULL; + } + + return; + } + + // Get the public memory allocator + + if (pszOut) + { + // Copy of string converted to ANSI is requested + } + + // Free the original string +} + +LPOLESTR CreateOLESTR(char *pszIn) +{ + // Get the public memory allocator + + // Allocate the string + + // Convert the string +} diff --git a/private/oleutest/letest/ole2ui/olestr.h b/private/oleutest/letest/ole2ui/olestr.h new file mode 100644 index 000000000..a9c282930 --- /dev/null +++ b/private/oleutest/letest/ole2ui/olestr.h @@ -0,0 +1,21 @@ +#ifndef _OLESTR_H_ +#define _OLESTR_H_ + +void CopyAndFreeOLESTR(LPOLESTR polestr, char **pszOut); + +void CopyAndFreeSTR(LPSTR polestr, LPOLESTR *pszOut); + +LPOLESTR CreateOLESTR(const char *pszIn); +LPSTR CreateSTR(LPCOLESTR pszIn); + +#define CREATEOLESTR(x, y) LPOLESTR x = CreateOLESTR(y); + +#define CREATESTR(x, y) LPSTR x = CreateSTR(y); + +#define FREEOLESTR(x) CopyAndFreeOLESTR(x, NULL); + +#define FREESTR(x) CopyAndFreeSTR(x, NULL); + + + +#endif // _OLESTR_H_ diff --git a/private/oleutest/letest/ole2ui/olethunk.c b/private/oleutest/letest/ole2ui/olethunk.c new file mode 100644 index 000000000..a69c3102d --- /dev/null +++ b/private/oleutest/letest/ole2ui/olethunk.c @@ -0,0 +1,649 @@ +#include <windows.h> +#include <ole2.h> +#include "olethunk.h" + +STDAPI_(LPVOID) OleStdMalloc(ULONG ulSize); + +STDAPI_(void) OleStdFree(LPVOID pmem); + + +STDAPI_(void) CopyAndFreeOLESTR(LPOLESTR polestr, LPSTR *ppszOut) +{ + // See if there is any work + if (polestr == NULL) + { + if (ppszOut != NULL) + { + // Output string requested so set it to NULL. + *ppszOut = NULL; + } + + return; + } + + if (ppszOut) + { + // Copy of string converted to ANSI is requested + int len = wcslen(polestr) + 1; + *ppszOut = OleStdMalloc(len); + + if (*ppszOut) + { + wcstombs(*ppszOut, polestr, len); + } + } + + // Free the original string + OleStdFree(polestr); +} + + + + +STDAPI_(void) CopyAndFreeSTR(LPSTR pstr, LPOLESTR *ppolestrOut) +{ + // See if there is any work + if (pstr == NULL) + { + if (ppolestrOut != NULL) + { + // Output string requested so set it to NULL. + *ppolestrOut = NULL; + } + + return; + } + + if (ppolestrOut) + { + // Copy of string converted to ANSI is requested + int len = strlen(pstr) + 1; + *ppolestrOut = OleStdMalloc(len * sizeof(WCHAR)); + + if (*ppolestrOut) + { + mbstowcs(*ppolestrOut, pstr, len); + } + } + + // Free the original string + OleStdFree(pstr); +} + + + +STDAPI_(LPOLESTR) CreateOLESTR(LPCSTR pszIn) +{ + // Return NULL if there was no string input + LPOLESTR polestr = NULL; + + if (pszIn != NULL) + { + // Calculate size of string to allocate + int len = strlen(pszIn) + 1; + + // Allocate the string + polestr = (LPOLESTR) OleStdMalloc(len * sizeof(OLECHAR)); + + // Convert the string + if (polestr) + { + mbstowcs(polestr, pszIn, len); + } + } + + return polestr; +} + + + +STDAPI_(LPSTR) CreateSTR(LPCOLESTR polestrIn) +{ + // Return NULL if there was no string input + LPSTR pstr = NULL; + + if (polestrIn != NULL) + { + // Calculate size of string to allocate + int len = wcslen(polestrIn) + 1; + + // Allocate the string + pstr = (PSTR) OleStdMalloc(len); + + // Convert the string + if (pstr) + { + wcstombs(pstr, polestrIn, len); + } + } + + return pstr; +} + + + + +STDAPI_(void) CLSIDFromStringA(LPSTR pszClass, LPCLSID pclsid) +{ + CREATEOLESTR(polestr, pszClass) + + CLSIDFromString(polestr, pclsid); + + FREEOLESTR(polestr) +} + + + +STDAPI CreateFileMonikerA(LPSTR lpszPathName, LPMONIKER FAR* ppmk) +{ + CREATEOLESTR(polestr, lpszPathName) + + HRESULT hr = CreateFileMoniker(polestr, ppmk); + + FREEOLESTR(polestr) + + return hr; +} + + + +STDAPI CreateItemMonikerA( + LPSTR lpszDelim, + LPSTR lpszItem, + LPMONIKER FAR* ppmk) +{ + CREATEOLESTR(polestrDelim, lpszDelim) + CREATEOLESTR(polestrItem, lpszItem) + + HRESULT hr = CreateItemMoniker(polestrDelim, polestrItem, ppmk); + + FREEOLESTR(polestrDelim) + FREEOLESTR(polestrItem) + + return hr; +} + + + +STDAPI_(HGLOBAL) OleGetIconOfClassA( + REFCLSID rclsid, + LPSTR lpszLabel, + BOOL fUseTypeAsLabel) +{ + CREATEOLESTR(polestr, lpszLabel) + + HGLOBAL hglobal = OleGetIconOfClass(rclsid, polestr, fUseTypeAsLabel); + + FREEOLESTR(polestr) + + return hglobal; +} + + + +STDAPI_(HGLOBAL) OleGetIconOfFileA(LPSTR lpszPath, BOOL fUseFileAsLabel) +{ + CREATEOLESTR(polestr, lpszPath) + + HGLOBAL hMetaPict = OleGetIconOfFile(polestr, fUseFileAsLabel); + + FREEOLESTR(polestr) + + return hMetaPict; +} + + + + +STDAPI_(HGLOBAL) OleMetafilePictFromIconAndLabelA( + HICON hIcon, + LPSTR lpszLabel, + LPSTR lpszSourceFile, + UINT iIconIndex) +{ + CREATEOLESTR(polestrLabel, lpszLabel) + CREATEOLESTR(polestrSourceFile, lpszSourceFile) + + HGLOBAL hglobal = OleMetafilePictFromIconAndLabel(hIcon, polestrLabel, + polestrSourceFile, iIconIndex); + + FREEOLESTR(polestrLabel) + FREEOLESTR(polestrSourceFile) + + return hglobal; +} + + + + +STDAPI GetClassFileA(LPCSTR szFilename, CLSID FAR* pclsid) +{ + CREATEOLESTR(polestr, szFilename) + + HRESULT hr = GetClassFile(polestr, pclsid); + + FREEOLESTR(polestr) + + return hr; +} + + + +STDAPI CLSIDFromProgIDA(LPCSTR lpszProgID, LPCLSID lpclsid) +{ + CREATEOLESTR(polestr, lpszProgID) + + HRESULT hr = CLSIDFromProgID(polestr, lpclsid); + + FREEOLESTR(polestr) + + return hr; +} + +STDAPI MkParseDisplayNameA( + LPBC pbc, + LPSTR szUserName, + ULONG FAR * pchEaten, + LPMONIKER FAR * ppmk) +{ + CREATEOLESTR(polestr, szUserName) + + HRESULT hr = MkParseDisplayName(pbc, polestr, pchEaten, ppmk); + + FREEOLESTR(polestr) + + return hr; +} + + + + +STDAPI OleCreateLinkToFileA( + LPCSTR lpszFileName, + REFIID riid, + DWORD renderopt, + LPFORMATETC lpFormatEtc, + LPOLECLIENTSITE pClientSite, + LPSTORAGE pStg, + LPVOID FAR* ppvObj) +{ + CREATEOLESTR(polestr, lpszFileName) + + HRESULT hr = OleCreateLinkToFile(polestr, riid, renderopt, lpFormatEtc, + pClientSite, pStg, ppvObj); + + FREEOLESTR(polestr) + + return hr; +} + + +STDAPI OleCreateFromFileA( + REFCLSID rclsid, + LPCSTR lpszFileName, + REFIID riid, + DWORD renderopt, + LPFORMATETC lpFormatEtc, + LPOLECLIENTSITE pClientSite, + LPSTORAGE pStg, + LPVOID FAR* ppvObj) +{ + CREATEOLESTR(polestr, lpszFileName) + + HRESULT hr = OleCreateFromFile(rclsid, polestr, riid, renderopt, + lpFormatEtc, pClientSite, pStg, ppvObj); + + FREEOLESTR(polestr) + + return hr; +} + + + +STDAPI OleRegGetUserTypeA( + REFCLSID clsid, + DWORD dwFormOfType, + LPSTR FAR* ppszUserType) +{ + LPOLESTR polestr; + + HRESULT hr = OleRegGetUserType(clsid, dwFormOfType, &polestr); + + CopyAndFreeOLESTR(polestr, ppszUserType); + + return hr; +} + + + +STDAPI ProgIDFromCLSIDA(REFCLSID clsid, LPSTR FAR* lplpszProgID) +{ + LPOLESTR polestr; + + HRESULT hr = ProgIDFromCLSID(clsid, &polestr); + + CopyAndFreeOLESTR(polestr, lplpszProgID); + + return hr; +} + + + +STDAPI ReadFmtUserTypeStgA( + LPSTORAGE pstg, + CLIPFORMAT FAR* pcf, + LPSTR FAR* lplpszUserType) +{ + LPOLESTR polestr; + + HRESULT hr = ReadFmtUserTypeStg(pstg, pcf, &polestr); + + CopyAndFreeOLESTR(polestr, lplpszUserType); + + return hr; +} + + + + + + +STDAPI StgCreateDocfileA( + LPCSTR lpszName, + DWORD grfMode, + DWORD reserved, + IStorage FAR * FAR *ppstgOpen) +{ + HRESULT hr; + LPOLESTR polestr = NULL; + + if (lpszName != NULL) + { + polestr = CreateOLESTR(lpszName); + } + + hr = StgCreateDocfile(polestr, grfMode, reserved, ppstgOpen); + + FREEOLESTR(polestr) + + return hr; +} + + + + +STDAPI StgOpenStorageA( + LPCSTR lpszName, + IStorage FAR *pstgPriority, + DWORD grfMode, + SNB snbExclude, + DWORD reserved, + IStorage FAR * FAR *ppstgOpen) +{ + CREATEOLESTR(polestr, lpszName) + + HRESULT hr = StgOpenStorage(polestr, pstgPriority, grfMode, snbExclude, + reserved, ppstgOpen); + + FREEOLESTR(polestr) + + return hr; +} + + + +STDAPI StgSetTimesA( + LPSTR lpszName, + FILETIME const FAR* pctime, + FILETIME const FAR* patime, + FILETIME const FAR* pmtime) +{ + CREATEOLESTR(polestr, lpszName) + + HRESULT hr = StgSetTimes(polestr, pctime, patime, pmtime); + + FREEOLESTR(polestr) + + return hr; +} + + + + +STDAPI_(void) StringFromCLSIDA(REFCLSID rclsid, LPSTR *lplpszCLSID) +{ + LPOLESTR polestr; + + StringFromCLSID(rclsid, &polestr); + + CopyAndFreeOLESTR(polestr, lplpszCLSID); +} + + +STDAPI WriteFmtUserTypeStgA( + LPSTORAGE lpStg, + CLIPFORMAT cf, + LPSTR lpszUserType) +{ + CREATEOLESTR(polestr, lpszUserType) + + HRESULT hr = WriteFmtUserTypeStg(lpStg, cf, polestr); + + FREEOLESTR(polestr) + + return hr; +} + + + + + + + +STDAPI CallIMonikerGetDisplayNameA( + LPMONIKER lpmk, + IBindCtx *pbc, + IMoniker *pmkToLeft, + LPSTR *ppszDisplayName) +{ + LPOLESTR polestr; + + HRESULT hr = lpmk->lpVtbl->GetDisplayName(lpmk, pbc, NULL, + &polestr); + + CopyAndFreeOLESTR(polestr, ppszDisplayName); + + return hr; +} + + + +STDAPI CallIOleInPlaceUIWindowSetActiveObjectA( + IOleInPlaceUIWindow FAR *lpthis, + IOleInPlaceActiveObject *pActiveObject, + LPCSTR pszObjName) +{ + CREATEOLESTR(polestr, pszObjName) + + HRESULT hr = lpthis->lpVtbl->SetActiveObject(lpthis, pActiveObject, + polestr); + + FREEOLESTR(polestr) + + return hr; +} + + + +STDAPI CallIOleInPlaceFrameSetStatusTextA( + IOleInPlaceFrame *poleinplc, + LPCSTR pszStatusText) +{ + CREATEOLESTR(polestr, pszStatusText) + + HRESULT hr = poleinplc->lpVtbl->SetStatusText(poleinplc, polestr); + + FREEOLESTR(polestr) + + return hr; +} + + + + +STDAPI CallIOleLinkGetSourceDisplayNameA( + IOleLink FAR *polelink, + LPSTR *ppszDisplayName) +{ + LPOLESTR polestr; + + HRESULT hr = polelink->lpVtbl->GetSourceDisplayName(polelink, &polestr); + + CopyAndFreeOLESTR(polestr, ppszDisplayName); + + return hr; +} + + + +STDAPI CallIOleLinkSetSourceDisplayNameA( + IOleLink FAR *polelink, + LPCSTR pszStatusText) +{ + CREATEOLESTR(polestr, pszStatusText) + + HRESULT hr = polelink->lpVtbl->SetSourceDisplayName(polelink, polestr); + + FREEOLESTR(polestr) + + return hr; +} + + + + + +STDAPI CallIOleObjectGetUserTypeA( + LPOLEOBJECT lpOleObject, + DWORD dwFormOfType, + LPSTR *ppszUserType) +{ + LPOLESTR polestr; + + HRESULT hr = lpOleObject->lpVtbl->GetUserType(lpOleObject, + dwFormOfType, &polestr); + + CopyAndFreeOLESTR(polestr, ppszUserType); + + return hr; +} + + + +STDAPI CallIOleObjectSetHostNamesA( + LPOLEOBJECT lpOleObject, + LPCSTR szContainerApp, + LPCSTR szContainerObj) +{ + CREATEOLESTR(polestrApp, szContainerApp) + CREATEOLESTR(polestrObj, szContainerObj) + + HRESULT hr = lpOleObject->lpVtbl->SetHostNames(lpOleObject, polestrApp, + polestrObj); + + FREEOLESTR(polestrApp) + FREEOLESTR(polestrObj) + + return hr; +} + +STDAPI CallIStorageDestroyElementA( + LPSTORAGE lpStg, + LPSTR pszName) +{ + CREATEOLESTR(polestr, pszName) + + HRESULT hr = lpStg->lpVtbl->DestroyElement(lpStg, polestr); + + FREEOLESTR(polestr) + + return hr; +} + + + +STDAPI CallIStorageCreateStorageA( + LPSTORAGE lpStg, + const char *pszName, + DWORD grfMode, + DWORD dwStgFmt, + DWORD reserved2, + IStorage **ppstg) +{ + CREATEOLESTR(polestr, pszName) + + HRESULT hr = lpStg->lpVtbl->CreateStorage(lpStg, polestr, grfMode, + dwStgFmt, reserved2, ppstg); + + FREEOLESTR(polestr) + + return hr; +} + + + +STDAPI CallIStorageOpenStorageA( + LPSTORAGE lpStg, + const char *pszName, + IStorage *pstgPriority, + DWORD grfMode, + SNB snbExclude, + DWORD reserved, + IStorage **ppstg) +{ + CREATEOLESTR(polestr, pszName) + + HRESULT hr = lpStg->lpVtbl->OpenStorage(lpStg, polestr, pstgPriority, + grfMode, snbExclude, reserved, ppstg); + + FREEOLESTR(polestr) + + return hr; +} + + +STDAPI CallIStorageCreateStreamA( + LPSTORAGE lpStg, + LPSTR pszName, + DWORD grfMode, + DWORD reserved1, + DWORD reserved2, + IStream **ppstm) +{ + CREATEOLESTR(polestr, pszName) + + HRESULT hr = lpStg->lpVtbl->CreateStream(lpStg, polestr, + grfMode, reserved1, reserved2, ppstm); + + FREEOLESTR(polestr) + + return hr; +} + +STDAPI CallIStorageOpenStreamA( + LPSTORAGE lpStg, + LPSTR pszName, + void *reserved1, + DWORD grfMode, + DWORD reserved2, + IStream **ppstm) +{ + CREATEOLESTR(polestr, pszName) + + HRESULT hr = lpStg->lpVtbl->OpenStream(lpStg, polestr, reserved1, + grfMode, reserved2, ppstm); + + FREEOLESTR(polestr) + + return hr; +} diff --git a/private/oleutest/letest/ole2ui/olethunk.h b/private/oleutest/letest/ole2ui/olethunk.h new file mode 100644 index 000000000..ed47a62da --- /dev/null +++ b/private/oleutest/letest/ole2ui/olethunk.h @@ -0,0 +1,193 @@ +#ifndef _OLETHUNK_H_ +#define _OLETHUNK_H_ + +// +// String Conversion Helpers +// +STDAPI_(void) CopyAndFreeOLESTR(LPOLESTR polestr, char **pszOut); + +STDAPI_(void) CopyAndFreeSTR(LPSTR polestr, LPOLESTR *pszOut); + +STDAPI_(LPOLESTR) CreateOLESTR(const char *pszIn); + +STDAPI_(LPSTR) CreateSTR(LPCOLESTR pszIn); + +#define CREATEOLESTR(x, y) LPOLESTR x = CreateOLESTR(y); + +#define CREATESTR(x, y) LPSTR x = CreateSTR(y); + +#define FREEOLESTR(x) CopyAndFreeOLESTR(x, NULL); + +#define FREESTR(x) CopyAndFreeSTR(x, NULL); + +// +// OLE API Thunks +// +STDAPI_(void) CLSIDFromStringA(LPSTR pszClass, LPCLSID pclsid); + +STDAPI CLSIDFromProgIDA(LPCSTR lpszProgID, LPCLSID lpclsid); + +STDAPI CreateFileMonikerA(LPSTR lpszPathName, LPMONIKER FAR* ppmk); + +STDAPI CreateItemMonikerA( + LPSTR lpszDelim, + LPSTR lpszItem, + LPMONIKER FAR* ppmk); + +STDAPI GetClassFileA(LPCSTR szFilename, CLSID FAR* pclsid); + +STDAPI MkParseDisplayNameA( + LPBC pbc, + LPSTR szUserName, + ULONG FAR * pchEaten, + LPMONIKER FAR * ppmk); + +STDAPI OleCreateFromFileA( + REFCLSID rclsid, + LPCSTR lpszFileName, + REFIID riid, + DWORD renderopt, + LPFORMATETC lpFormatEtc, + LPOLECLIENTSITE pClientSite, + LPSTORAGE pStg, + LPVOID FAR* ppvObj); + +STDAPI OleCreateLinkToFileA( + LPCSTR lpszFileName, + REFIID riid, + DWORD renderopt, + LPFORMATETC lpFormatEtc, + LPOLECLIENTSITE pClientSite, + LPSTORAGE pStg, + LPVOID FAR* ppvObj); + +STDAPI_(HGLOBAL) OleGetIconOfClassA( + REFCLSID rclsid, + LPSTR lpszLabel, + BOOL fUseTypeAsLabel); + +STDAPI_(HGLOBAL) OleGetIconOfFileA(LPSTR lpszPath, BOOL fUseFileAsLabel); + +STDAPI_(HGLOBAL) OleMetafilePictFromIconAndLabelA( + HICON hIcon, + LPSTR lpszLabel, + LPSTR lpszSourceFile, + UINT iIconIndex); + +STDAPI OleRegGetUserTypeA( + REFCLSID clsid, + DWORD dwFormOfType, + LPSTR FAR* pszUserType); + +STDAPI ProgIDFromCLSIDA(REFCLSID clsid, LPSTR FAR* lplpszProgID); + +STDAPI ReadFmtUserTypeStgA( + LPSTORAGE pstg, + CLIPFORMAT FAR* pcf, + LPSTR FAR* lplpszUserType); + +STDAPI StgCreateDocfileA( + LPCSTR pwcsName, + DWORD grfMode, + DWORD reserved, + IStorage FAR * FAR *ppstgOpen); + +STDAPI StgOpenStorageA( + LPCSTR pwcsName, + IStorage FAR *pstgPriority, + DWORD grfMode, + SNB snbExclude, + DWORD reserved, + IStorage FAR * FAR *ppstgOpen); + +STDAPI StgSetTimesA( + LPSTR lpszName, + FILETIME const FAR* pctime, + FILETIME const FAR* patime, + FILETIME const FAR* pmtime); + + +STDAPI_(void) StringFromCLSIDA(REFCLSID rclsid, LPSTR *lplpszCLSID); + +STDAPI WriteFmtUserTypeStgA( + LPSTORAGE pstg, + CLIPFORMAT cf, + LPSTR lpszUserType); + + + +// +// Method Thunks +// +STDAPI CallIMonikerGetDisplayNameA( + LPMONIKER lpmk, + IBindCtx *pbc, + IMoniker *pmkToLeft, + LPSTR *ppszDisplayName); + +STDAPI CallIOleLinkGetSourceDisplayNameA( + IOleLink FAR *polelink, + LPSTR *ppszDisplayName); + +STDAPI CallIOleLinkSetSourceDisplayNameA( + IOleLink FAR *polelink, + LPCSTR pszStatusText); + +STDAPI CallIOleInPlaceFrameSetStatusTextA( + IOleInPlaceFrame *poleinplc, + LPCSTR pszStatusText); + +STDAPI CallIOleInPlaceUIWindowSetActiveObjectA( + IOleInPlaceUIWindow FAR *lpthis, + IOleInPlaceActiveObject *pActiveObject, + LPCSTR pszObjName); + +STDAPI CallIOleObjectGetUserTypeA( + LPOLEOBJECT lpOleObject, + DWORD dwFormOfType, + LPSTR *pszUserType); + +STDAPI CallIOleObjectSetHostNamesA( + LPOLEOBJECT lpOleObject, + LPCSTR szContainerApp, + LPCSTR szContainerObj); + +STDAPI CallIStorageCreateStorageA( + LPSTORAGE lpStg, + const char *pwcsName, + DWORD grfMode, + DWORD dwStgFmt, + DWORD reserved2, + IStorage **ppstg); + +STDAPI CallIStorageDestroyElementA( + LPSTORAGE lpStg, + LPSTR pszName); + +STDAPI CallIStorageOpenStorageA( + LPSTORAGE lpStg, + const char *pszName, + IStorage *pstgPriority, + DWORD grfMode, + SNB snbExclude, + DWORD reserved, + IStorage **ppstg); + +STDAPI CallIStorageCreateStreamA( + LPSTORAGE lpStg, + LPSTR pszName, + DWORD grfMode, + DWORD reserved1, + DWORD reserved2, + IStream **ppstm); + +STDAPI CallIStorageOpenStreamA( + LPSTORAGE lpStg, + LPSTR pszName, + void *reserved1, + DWORD grfMode, + DWORD reserved2, + IStream **ppstm); + + +#endif // _OLETHUNK_H_ diff --git a/private/oleutest/letest/ole2ui/oleutl.c b/private/oleutest/letest/ole2ui/oleutl.c new file mode 100644 index 000000000..9c968cefd --- /dev/null +++ b/private/oleutest/letest/ole2ui/oleutl.c @@ -0,0 +1,660 @@ +/* + * OLEUTL.C + * + * Miscellaneous utility functions for OLE 2.0 Applications: + * + * Function Purpose + * ------------------------------------------------------------------- + * SetDCToDrawInHimetricRect Sets up an HIMETRIC mapping mode in a DC. + * ResetOrigDC Performs the opposite of + * SetDCToDrawInHimetricRect + * XformWidthInPixelsToHimetric Converts an int width into HiMetric units + * XformWidthInHimetricToPixels Converts an int width from HiMetric units + * XformHeightInPixelsToHimetric Converts an int height into HiMetric units + * XformHeightInHimetricToPixels Converts an int height from HiMetric units + * XformRectInPixelsToHimetric Converts a rect into HiMetric units + * XformRectInHimetricToPixels Converts a rect from HiMetric units + * XformSizeInPixelsToHimetric Converts a SIZEL into HiMetric units + * XformSizeInHimetricToPixels Converts a SIZEL from HiMetric units + * AreRectsEqual Compares to Rect's + * + * ParseCmdLine Determines if -Embedding exists + * OpenOrCreateRootStorage Creates a root docfile for OLE storage + * 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 + */ + + +#define STRICT 1 +#include "ole2ui.h" +#include <stdlib.h> +#include <ctype.h> + +//Internal function to this module. No need for UNICODE in this function +static LPSTR GetWord(LPSTR lpszSrc, LPSTR lpszDst); + + +/* + * SetDCToAnisotropic + * + * Purpose: + * Setup the correspondence between the rect in device unit (Viewport) and + * the rect in logical unit (Window) so that the proper scaling of + * coordinate systems will be calculated. set up both the Viewport and + * the window as follows: + * + * 1) ------------------ ( 2 + * | | + * | | + * | | + * | | + * | | + * 3) ------------------ ( 4 + * + * Origin = P3 + * X extent = P2x - P3x + * Y extent = P2y - P3y + * + * Parameters: + * hDC HDC to affect + * lprcPhysical LPRECT containing the physical (device) extents of DC + * lprcLogical LPRECT containing the logical extents + * lprcWindowOld LPRECT in which to preserve the window for ResetOrigDC + * lprcViewportOld LPRECT in which to preserver the viewport for ResetOrigDC + * + * Return Value: + * int The original mapping mode of the DC. + */ + +STDAPI_(int) SetDCToAnisotropic( + HDC hDC, + LPRECT lprcPhysical, LPRECT lprcLogical, + LPRECT lprcWindowOld, LPRECT lprcViewportOld) +{ + int nMapModeOld=SetMapMode(hDC, MM_ANISOTROPIC); + + SetWindowOrgEx(hDC, lprcLogical->left, lprcLogical->bottom, (LPPOINT)&lprcWindowOld->left); + SetWindowExtEx(hDC, (lprcLogical->right-lprcLogical->left), (lprcLogical->top-lprcLogical->bottom), (LPSIZE)&lprcWindowOld->right); + SetViewportOrgEx(hDC, lprcPhysical->left, lprcPhysical->bottom, (LPPOINT)&lprcViewportOld->left); + SetViewportExtEx(hDC, (lprcPhysical->right-lprcPhysical->left), (lprcPhysical->top-lprcPhysical->bottom), (LPSIZE)&lprcViewportOld->right); + + return nMapModeOld; +} + + +/* + * SetDCToDrawInHimetricRect + * + * Purpose: + * Setup the correspondence between the rect in pixels (Viewport) and + * the rect in HIMETRIC (Window) so that the proper scaling of + * coordinate systems will be calculated. set up both the Viewport and + * the window as follows: + * + * 1) ------------------ ( 2 + * | | + * | | + * | | + * | | + * | | + * 3) ------------------ ( 4 + * + * Origin = P3 + * X extent = P2x - P3x + * Y extent = P2y - P3y + * + * Parameters: + * hDC HDC to affect + * lprcPix LPRECT containing the pixel extents of DC + * lprcHiMetric LPRECT to receive the himetric extents + * lprcWindowOld LPRECT in which to preserve the window for ResetOrigDC + * lprcViewportOld LPRECT in which to preserver the viewport for ResetOrigDC + * + * Return Value: + * int The original mapping mode of the DC. + */ +STDAPI_(int) SetDCToDrawInHimetricRect( + HDC hDC, + LPRECT lprcPix, LPRECT lprcHiMetric, + LPRECT lprcWindowOld, LPRECT lprcViewportOld) + { + int nMapModeOld=SetMapMode(hDC, MM_ANISOTROPIC); + BOOL fSystemDC =FALSE; + + if (NULL==hDC) + { + hDC=GetDC(NULL); + fSystemDC=TRUE; + } + + XformRectInPixelsToHimetric(hDC, lprcPix, lprcHiMetric); + + SetWindowOrgEx(hDC, lprcHiMetric->left, lprcHiMetric->bottom, (LPPOINT)&lprcWindowOld->left); + SetWindowExtEx(hDC, (lprcHiMetric->right-lprcHiMetric->left), (lprcHiMetric->top-lprcHiMetric->bottom), (LPSIZE)&lprcWindowOld->right); + SetViewportOrgEx(hDC, lprcPix->left, lprcPix->bottom, (LPPOINT)&lprcViewportOld->left); + SetViewportExtEx(hDC, (lprcPix->right-lprcPix->left), (lprcPix->top-lprcPix->bottom), (LPSIZE)&lprcViewportOld->right); + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return nMapModeOld; + } + + + +/* + * ResetOrigDC + * + * Purpose: + * Restores a DC set to draw in himetric from SetDCToDrawInHimetricRect. + * + * Parameters: + * hDC HDC to restore + * nMapModeOld int original mapping mode of hDC + * lprcWindowOld LPRECT filled in SetDCToDrawInHimetricRect + * lprcViewportOld LPRECT filled in SetDCToDrawInHimetricRect + * + * Return Value: + * int Same as nMapModeOld. + */ + +STDAPI_(int) ResetOrigDC( + HDC hDC, int nMapModeOld, + LPRECT lprcWindowOld, LPRECT lprcViewportOld) + { + POINT pOld; + + SetMapMode(hDC, nMapModeOld); + + SetWindowOrgEx(hDC, lprcWindowOld->left, lprcWindowOld->top, (LPPOINT)&pOld); + SetWindowExtEx(hDC, lprcWindowOld->right, lprcWindowOld->bottom, (LPSIZE)&pOld); + SetViewportOrgEx(hDC, lprcViewportOld->left, lprcViewportOld->top, (LPPOINT)&pOld); + SetViewportExtEx(hDC, lprcViewportOld->right, lprcViewportOld->bottom, (LPSIZE)&pOld); + + return nMapModeOld; + } + + + +/* + * XformWidthInPixelsToHimetric + * XformWidthInHimetricToPixels + * XformHeightInPixelsToHimetric + * 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. This + * contains pixels in XformSizeInPixelsToHimetric and + * logical HiMetric units in the complement function. + * lpSizeDst LPSIZEL providing the structure to receive converted + * units. This contains pixels in + * XformSizeInPixelsToHimetric and logical HiMetric + * units in the complement function. + * + * 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) XformWidthInPixelsToHimetric(HDC hDC, int iWidthInPix) + { + int iXppli; //Pixels per logical inch along width + int iWidthInHiMetric; + BOOL fSystemDC=FALSE; + + if (NULL==hDC) + { + hDC=GetDC(NULL); + fSystemDC=TRUE; + } + + iXppli = GetDeviceCaps (hDC, LOGPIXELSX); + + //We got pixel units, convert them to logical HIMETRIC along the display + iWidthInHiMetric = MAP_PIX_TO_LOGHIM(iWidthInPix, iXppli); + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return iWidthInHiMetric; + } + + +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) XformHeightInPixelsToHimetric(HDC hDC, int iHeightInPix) + { + int iYppli; //Pixels per logical inch along height + int iHeightInHiMetric; + BOOL fSystemDC=FALSE; + + if (NULL==hDC) + { + hDC=GetDC(NULL); + fSystemDC=TRUE; + } + + iYppli = GetDeviceCaps (hDC, LOGPIXELSY); + + //* We got pixel units, convert them to logical HIMETRIC along the display + iHeightInHiMetric = MAP_PIX_TO_LOGHIM(iHeightInPix, iYppli); + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return iHeightInHiMetric; + } + + +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; + } + + + +/* + * XformRectInPixelsToHimetric + * XformRectInHimetricToPixels + * + * Purpose: + * Convert a rectangle between pixels of a given hDC and HIMETRIC units + * as manipulated in OLE. If the hDC is NULL, then a screen DC is used + * and assumes the MM_TEXT mapping mode. + * + * Parameters: + * hDC HDC providing reference to the pixel mapping. If + * NULL, a screen DC is used. + * lprcSrc LPRECT providing the rectangle to convert. This + * contains pixels in XformRectInPixelsToHimetric and + * logical HiMetric units in the complement function. + * lprcDst LPRECT providing the rectangle to receive converted units. + * This contains pixels in XformRectInPixelsToHimetric and + * logical HiMetric units in the complement function. + * + * Return Value: + * None + * + * 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 + * + * Rect in Pixels (MM_TEXT): + * + * 0---------- X + * | + * | 1) ------------------ ( 2 P1 = (rc.left, rc.top) + * | | | P2 = (rc.right, rc.top) + * | | | P3 = (rc.left, rc.bottom) + * | | | P4 = (rc.right, rc.bottom) + * | | + * Y | | + * 3) ------------------ ( 4 + * + * NOTE: Origin = (P1x, P1y) + * X extent = P4x - P1x + * Y extent = P4y - P1y + * + * + * Rect in Himetric (MM_HIMETRIC): + * + * + * 1) ------------------ ( 2 P1 = (rc.left, rc.top) + * Y | | P2 = (rc.right, rc.top) + * | | P3 = (rc.left, rc.bottom) + * | | | P4 = (rc.right, rc.bottom) + * | | | + * | | | + * | 3) ------------------ ( 4 + * | + * 0---------- X + * + * NOTE: Origin = (P3x, P3y) + * X extent = P2x - P3x + * Y extent = P2y - P3y + * + * + */ + +STDAPI_(void) XformRectInPixelsToHimetric( + HDC hDC, LPRECT lprcPix, LPRECT lprcHiMetric) + { + int iXppli; //Pixels per logical inch along width + int iYppli; //Pixels per logical inch along height + int iXextInPix=(lprcPix->right-lprcPix->left); + int iYextInPix=(lprcPix->bottom-lprcPix->top); + BOOL fSystemDC=FALSE; + + if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0) + { + hDC=GetDC(NULL); + fSystemDC=TRUE; + } + + iXppli = GetDeviceCaps (hDC, LOGPIXELSX); + iYppli = GetDeviceCaps (hDC, LOGPIXELSY); + + //We got pixel units, convert them to logical HIMETRIC along the display + lprcHiMetric->right = MAP_PIX_TO_LOGHIM(iXextInPix, iXppli); + lprcHiMetric->top = MAP_PIX_TO_LOGHIM(iYextInPix, iYppli); + + lprcHiMetric->left = 0; + lprcHiMetric->bottom = 0; + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return; + } + + + +STDAPI_(void) XformRectInHimetricToPixels( + HDC hDC, LPRECT lprcHiMetric, LPRECT lprcPix) + { + int iXppli; //Pixels per logical inch along width + int iYppli; //Pixels per logical inch along height + int iXextInHiMetric=(lprcHiMetric->right-lprcHiMetric->left); + int iYextInHiMetric=(lprcHiMetric->bottom-lprcHiMetric->top); + BOOL fSystemDC=FALSE; + + if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0) + { + hDC=GetDC(NULL); + fSystemDC=TRUE; + } + + iXppli = GetDeviceCaps (hDC, LOGPIXELSX); + iYppli = GetDeviceCaps (hDC, LOGPIXELSY); + + //We got pixel units, convert them to logical HIMETRIC along the display + lprcPix->right = MAP_LOGHIM_TO_PIX(iXextInHiMetric, iXppli); + lprcPix->top = MAP_LOGHIM_TO_PIX(iYextInHiMetric, iYppli); + + lprcPix->left = 0; + lprcPix->bottom= 0; + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return; + } + + + + +/* + * XformSizeInPixelsToHimetric + * XformSizeInHimetricToPixels + * + * Functions to convert a SIZEL structure (Size functions) or + * an int (Width functions) 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. This + * contains pixels in XformSizeInPixelsToHimetric and + * logical HiMetric units in the complement function. + * lpSizeDst LPSIZEL providing the structure to receive converted + * units. This contains pixels in + * XformSizeInPixelsToHimetric and logical HiMetric + * units in the complement function. + * + * 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_(void) XformSizeInPixelsToHimetric( + HDC hDC, LPSIZEL lpSizeInPix, LPSIZEL lpSizeInHiMetric) + { + int iXppli; //Pixels per logical inch along width + int iYppli; //Pixels per logical inch along height + BOOL fSystemDC=FALSE; + + if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0) + { + hDC=GetDC(NULL); + fSystemDC=TRUE; + } + + iXppli = GetDeviceCaps (hDC, LOGPIXELSX); + iYppli = GetDeviceCaps (hDC, LOGPIXELSY); + + //We got pixel units, convert them to logical HIMETRIC along the display + lpSizeInHiMetric->cx = (long)MAP_PIX_TO_LOGHIM((int)lpSizeInPix->cx, iXppli); + lpSizeInHiMetric->cy = (long)MAP_PIX_TO_LOGHIM((int)lpSizeInPix->cy, iYppli); + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return; + } + + +STDAPI_(void) XformSizeInHimetricToPixels( + HDC hDC, LPSIZEL lpSizeInHiMetric, LPSIZEL lpSizeInPix) + { + int iXppli; //Pixels per logical inch along width + int iYppli; //Pixels per logical inch along height + BOOL fSystemDC=FALSE; + + if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0) + { + hDC=GetDC(NULL); + fSystemDC=TRUE; + } + + iXppli = GetDeviceCaps (hDC, LOGPIXELSX); + iYppli = GetDeviceCaps (hDC, LOGPIXELSY); + + //We got logical HIMETRIC along the display, convert them to pixel units + lpSizeInPix->cx = (long)MAP_LOGHIM_TO_PIX((int)lpSizeInHiMetric->cx, iXppli); + lpSizeInPix->cy = (long)MAP_LOGHIM_TO_PIX((int)lpSizeInHiMetric->cy, iYppli); + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return; + } + + +#if defined( OBSOLETE ) +// This function has been converted to a macro + +/* AreRectsEqual +** ------------- +*/ +STDAPI_(BOOL) AreRectsEqual(LPRECT lprc1, LPRECT lprc2) +{ + if ((lprc1->top == lprc2->top) && + (lprc1->left == lprc2->left) && + (lprc1->right == lprc2->right) && + (lprc1->bottom == lprc2->bottom)) + return TRUE; + + return FALSE; +} +#endif // OBSOLETE + + +/* + * ParseCmdLine + * + * Parses the Windows command line which was passed to WinMain. + * This function determines if the -Embedding switch has been given. + * + */ + +STDAPI_(void) ParseCmdLine( + LPSTR lpszLine, + BOOL FAR* lpfEmbedFlag, + LPSTR szFileName) +{ + int i=0; + CHAR szBuf[256]; + + if(lpfEmbedFlag) + *lpfEmbedFlag = FALSE; + szFileName[0]='\0'; // NULL string + + // skip blanks + while(isspace(*lpszLine)) lpszLine++; + + if(!*lpszLine) // No filename or options, so start a fresh document. + return; + + // Check for "-Embedding" or "/Embedding" and set fEmbedding. + if(lpfEmbedFlag && (*lpszLine == '-' || *lpszLine == '/')) { + lpszLine++; + lpszLine = GetWord(lpszLine, szBuf); + *lpfEmbedFlag = (BOOL) !strcmp(szBuf, EMBEDDINGFLAG); + } + + // skip blanks + while(isspace(*lpszLine)) lpszLine++; + + // set szFileName to argument + while(lpszLine[i]) { + szFileName[i]=lpszLine[i]; + i++; + } + szFileName[i]='\0'; +} + + +/* 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 && !isspace(*lpszSrc)) + *lpszDst++ = *lpszSrc++; + + *lpszDst = '\0'; + return lpszSrc; +} + + + + + diff --git a/private/oleutest/letest/ole2ui/outlui.d32 b/private/oleutest/letest/ole2ui/outlui.d32 new file mode 100644 index 000000000..502d0b598 --- /dev/null +++ b/private/oleutest/letest/ole2ui/outlui.d32 @@ -0,0 +1,138 @@ +;; +;; ole2ui.def +;; +;; Definition file for ole2ui.dll +;; +;; (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved +;; +;; + +CODE MOVEABLE DISCARDABLE +DATA MOVEABLE SINGLE + +HEAPSIZE 16392 + +EXPORTS WEP @1 RESIDENTNAME +;; +;; NOTE: DO NOT PLACE ANY EXPORTS HERE -- USE THE +;; __export KEYWORD INSTEAD. + +SetDCToAnisotropic +SetDCToDrawInHimetricRect +ResetOrigDC +XformRectInPixelsToHimetric +XformRectInHimetricToPixels +XformSizeInPixelsToHimetric +XformSizeInHimetricToPixels +XformWidthInHimetricToPixels +XformWidthInPixelsToHimetric +XformHeightInHimetricToPixels +XformHeightInPixelsToHimetric +AreRectsEqual +ParseCmdLine +OleStdIsOleLink +OleStdQueryInterface +OleStdCreateRootStorage +OleStdOpenRootStorage +OleStdOpenOrCreateRootStorage +OleStdCreateChildStorage +OleStdOpenChildStorage +OleStdCommitStorage +OleStdCreateStorageOnHGlobal +OleStdCreateTempStorage +OleStdDoConvert +OleStdGetTreatAsFmtUserType +OleStdDoTreatAsClass +OleStdSetupAdvises +OleStdSwitchDisplayAspect +OleStdSetIconInCache +OleStdGetData +OleStdMarkPasteEntryList +OleStdGetPriorityClipboardFormat +OleStdIsDuplicateFormat +OleStdRegisterAsRunning +OleStdRevokeAsRunning +OleStdNoteFileChangeTime +OleStdNoteObjectChangeTime +OleStdGetOleObjectData +OleStdGetLinkSourceData +OleStdGetObjectDescriptorData +OleStdGetObjectDescriptorDataFromOleObject +OleStdFillObjectDescriptorFromData +OleStdCopyMetafilePict +OleStdGetMetafilePictFromOleObject +OleStdQueryOleObjectData +OleStdQueryLinkSourceData +OleStdQueryObjectDescriptorData +OleStdQueryFormatMedium +OleStdGetDropEffect +OleStdCreateTempFileMoniker +OleStdGetFirstMoniker +OleStdGetLenFilePrefixOfMoniker +OleStdMalloc +OleStdRealloc +OleStdFree +OleStdGetSize +OleStdFreeString +OleStdCopyString +OleStdGetItemToken +OleStdInitVtbl +OleStdCheckVtbl +OleStdVerifyRelease +OleStdRelease +OleStdCreateDC +OleStdCreateIC +OleStdCreateTargetDevice +OleStdDeleteTargetDevice +OleStdCopyTargetDevice +OleStdCopyFormatEtc +OleDbgPrint +OleDbgPrintAlways +OleDbgSetDbgLevel +OleDbgGetDbgLevel +OleDbgIndent +OleDbgPrintRefCnt +OleDbgPrintRefCntAlways +OleDbgPrintRect +OleDbgPrintRectAlways +OleDbgPrintScodeAlways +OleUIInitialize +OleUIUnInitialize +OleUIAddVerbMenu +OleUIMetafilePictFromIconAndLabel +OleUIMetafilePictIconFree +OleUIMetafilePictIconDraw +OleUIMetafilePictExtractLabel +OleUIMetafilePictExtractIcon +OleUIMetafilePictExtractIconSource +OleUIInsertObject +OleUIPasteSpecial +OleUIEditLinks +OleUIChangeIcon +OleUIConvert +OleUIBusy +OleUIUpdateLinks +OleUIDrawHandles +OleUIDrawShading +OleUIShowObject +RegisterHatchWindowClass +CreateHatchWindow +GetHatchWidth +GetHatchRect +SetHatchRect +SetHatchWindowSize +OleUIPromptUser +OleStdEnumFmtEtc_Create +GetIconOfFile +GetIconOfClass +OleStdGetAuxUserType +OleStdGetUserTypeOfClass +OleStdIconLabelTextOut +OleStdMsgFilter_Create +OleStdMsgFilter_SetInComingCallStatus +OleStdMsgFilter_GetInComingCallStatus +OleStdMsgFilter_EnableBusyDialog +OleStdMsgFilter_EnableNotRespondingDialog +OleStdMsgFilter_SetParentWindow +OleStdGetMiscStatusOfClass +OleStdGetDefaultFileFormatOfClass diff --git a/private/oleutest/letest/ole2ui/pastespl.c b/private/oleutest/letest/ole2ui/pastespl.c new file mode 100644 index 000000000..0cf086cf1 --- /dev/null +++ b/private/oleutest/letest/ole2ui/pastespl.c @@ -0,0 +1,1713 @@ +/* + * PASTESPL.C + * + * Implements the OleUIPasteSpecial function which invokes the complete + * Paste Special dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Rights Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "pastespl.h" +#include "common.h" +#include "utility.h" +#include "resimage.h" +#include "iconbox.h" +#include "geticon.h" +#include "icon.h" +#include "regdb.h" +#include <stdlib.h> + +OLEDBGDATA + +/* + * 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 OLE2UI.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, sizeof(OLEUIPASTEENTRY))) + uRet = OLEUI_IOERR_ARRPASTEENTRIESINVALID; + if (NULL != lpPS->arrLinkTypes && IsBadReadPtr(lpPS->arrLinkTypes, sizeof(UINT))) + uRet = OLEUI_IOERR_ARRLINKTYPESINVALID; + + if (0!=lpPS->cClsidExclude) + { + if (NULL!=lpPS->lpClsidExclude && IsBadReadPtr(lpPS->lpClsidExclude + , lpPS->cClsidExclude*sizeof(CLSID))) + uRet=OLEUI_IOERR_LPCLSIDEXCLUDEINVALID; + } + + if (uRet >= OLEUI_ERR_STANDARDMIN) + { + if (NULL != hMemDlg) + FreeResource(hMemDlg); + return uRet; + } + + //Now that we've validated everything, we can invoke the dialog. + uRet = UStandardInvocation(PasteSpecialDialogProc, (LPOLEUISTANDARD)lpPS + , hMemDlg, MAKEINTRESOURCE(IDD_PASTESPECIAL)); + + /* + * IF YOU ARE CREATING ANYTHING BASED ON THE RESULTS, DO IT HERE. + */ + + return uRet; +} + + +/* + * PasteSpecialDialogProc + * + * Purpose: + * Implements the OLE Paste Special dialog as invoked through the + * OleUIPasteSpecial function. + * + * Parameters: + * Standard + * + * Return Value: + * Standard + */ + +BOOL CALLBACK EXPORT PasteSpecialDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + LPOLEUIPASTESPECIAL lpOPS; + LPPASTESPECIAL lpPS; + BOOL fHook=FALSE; + HCURSOR hCursorOld; + + //Declare Win16/Win32 compatible WM_COMMAND parameters. + COMMANDPARAMS(wID, wCode, hWndMsg); + + //This will fail under WM_INITDIALOG, where we allocate it. + lpPS=(LPPASTESPECIAL)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &fHook); + + //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) + { + 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, ID_PS_PASTELIST)); + FreeListData(GetDlgItem(hDlg, ID_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); + + // Change the clipboard notification chain + hwndNextViewer = GetProp(hDlg, NEXTCBVIEWER); + if (hwndNextViewer != HWND_BROADCAST) + { + SetProp(hDlg, NEXTCBVIEWER, HWND_BROADCAST); + ChangeClipboardChain(hDlg, hwndNextViewer); + } + RemoveProp(hDlg, NEXTCBVIEWER); + + StandardCleanup(lpPS, hDlg); + EndDialog(hDlg, wParam); + return TRUE; + } + + switch (iMsg) + { + case WM_INITDIALOG: + hCursorOld = HourGlassOn(); + FPasteSpecialInit(hDlg, wParam, lParam); + HourGlassOff(hCursorOld); + return FALSE; + + case WM_DRAWCLIPBOARD: + { + HWND hwndNextViewer = 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 = GetProp(hDlg, NEXTCBVIEWER); + } + 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, ID_PS_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0L); + + SendMessage( + hDlg, uMsgEndDialog, OLEUI_PSERR_CLIPBOARDCHANGED,0L); + } + break; + } + + case WM_CHANGECBCHAIN: + { + HWND hwndNextViewer = GetProp(hDlg, NEXTCBVIEWER); + + if (wParam == (WORD)hwndNextViewer) + SetProp(hDlg, NEXTCBVIEWER, (hwndNextViewer = (HWND)LOWORD(lParam))); + else if (hwndNextViewer && hwndNextViewer != HWND_BROADCAST) + SendMessage(hwndNextViewer, iMsg, wParam, lParam); + break; + } + + case WM_COMMAND: + switch (wID) + { + case ID_PS_PASTE: + FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTE); + break; + + case ID_PS_PASTELINK: + FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTELINK); + break; + + case ID_PS_DISPLAYLIST: + switch (wCode) + { + case LBN_SELCHANGE: + ChangeListSelection(hDlg, lpPS, hWndMsg); + break; + + case LBN_DBLCLK: + // Same as pressing OK + SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg); + break; + } + break; + + case ID_PS_DISPLAYASICON: + ToggleDisplayAsIcon(hDlg, lpPS); + break; + + case ID_PS_CHANGEICON: + ChangeIcon(hDlg, lpPS); + if (lpPS->fClipboardChanged) { + // Free icon and icon title metafile + SendDlgItemMessage( + hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGEFREE,0,0L); + SendMessage( + hDlg, uMsgEndDialog, + OLEUI_PSERR_CLIPBOARDCHANGED, 0L); + } + break; + + case IDOK: + { + BOOL fDestAspectIcon = + ((lpPS->dwFlags & PSF_CHECKDISPLAYASICON) ? + TRUE : FALSE); + lpOPS = lpPS->lpOPS; + // 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, ID_PS_ICONDISPLAY, + IBXM_IMAGEGET, 0, 0L); + SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L); + break; + } + case IDCANCEL: + // Free icon and icon title metafile + SendDlgItemMessage( + hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0L); + SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L); + break; + + case ID_OLEUIHELP: + PostMessage(lpPS->lpOPS->hWndOwner, uMsgHelp, + (WPARAM)hDlg, MAKELPARAM(IDD_PASTESPECIAL, 0)); + break; + } + break; + } + return FALSE; +} + + +/* + * 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) +{ + LPPASTESPECIAL lpPS; + LPOLEUIPASTESPECIAL lpOPS; + HFONT hFont; + BOOL fPasteAvailable, fPasteLinkAvailable; + STGMEDIUM medium; + LPOBJECTDESCRIPTOR lpOD; + LPLINKSRCDESCRIPTOR lpLSD; + int n; + CLIPFORMAT cfFormat; + + // Copy the structure at lParam into our instance memory. + lpPS = (LPPASTESPECIAL)LpvStandardInit(hDlg, sizeof(PASTESPECIAL), TRUE, &hFont); + + // PvStandardInit sent a termination to us already. + if (NULL == lpPS) + return FALSE; + + lpOPS=(LPOLEUIPASTESPECIAL)lParam; + + // Copy other information from lpOPS that we might modify. + lpPS->lpOPS = lpOPS; + lpPS->dwFlags = lpOPS->dwFlags; + + // Initialize user selections in the Paste and PasteLink listboxes + lpPS->nPasteListCurSel = 0; + lpPS->nPasteLinkListCurSel = 0; + + // If we got a font, send it to the necessary controls. + if (NULL!=hFont) + { + SendDlgItemMessage(hDlg, ID_PS_SOURCETEXT, WM_SETFONT, (WPARAM)hFont, 0L); + SendDlgItemMessage(hDlg, ID_PS_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L); + } + + // Hide the help button if required + if (!(lpPS->lpOPS->dwFlags & PSF_SHOWHELP)) + StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE); + + // Hide all DisplayAsIcon related controls if it should be disabled + if ( lpPS->dwFlags & PSF_DISABLEDISPLAYASICON ) { + StandardShowDlgItem(hDlg, ID_PS_DISPLAYASICON, SW_HIDE); + StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_HIDE); + StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); + } + + // PSF_CHECKDISPLAYASICON is an OUT flag. Clear it if has been set on the way in. + lpPS->dwFlags = lpPS->dwFlags & ~PSF_CHECKDISPLAYASICON; + + // Change the caption if required + if (NULL != lpOPS->lpszCaption) + SetWindowText(hDlg, lpOPS->lpszCaption); + + // Load 'Unknown Source' and 'Unknown Type' strings + n = LoadString(ghInst, IDS_PSUNKNOWNTYPE, lpPS->szUnknownType, PS_UNKNOWNSTRLEN); + if (n) + n = LoadString(ghInst, IDS_PSUNKNOWNSRC, lpPS->szUnknownSource, PS_UNKNOWNSTRLEN); + if (!n) + { + PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L); + return FALSE; + } + lpPS->szAppName[0]=TEXT('\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. + + if (lpPS->hObjDesc = OleStdFillObjectDescriptorFromData(lpOPS->lpSrcDataObj, &medium, &cfFormat)) + { + lpOD = GlobalLock(lpPS->hObjDesc); + + // Get FullUserTypeName, SourceOfCopy and CLSID + if (lpOD->dwFullUserTypeName) + lpPS->szFullUserTypeNameOD = (LPTSTR)lpOD+lpOD->dwFullUserTypeName; + else lpPS->szFullUserTypeNameOD = lpPS->szUnknownType; + + if (lpOD->dwSrcOfCopy) + { + lpPS->szSourceOfDataOD = (LPTSTR)lpOD+lpOD->dwSrcOfCopy; + // 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 == cfFileName) + lpPS->szSourceOfDataOD = ChopText(GetDlgItem(hDlg, ID_PS_SOURCETEXT), 0, lpPS->szSourceOfDataOD); + } + else lpPS->szSourceOfDataOD = lpPS->szUnknownSource; + + 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 + if (0==OleStdGetAuxUserType(&lpPS->clsidOD, 3, lpPS->szAppName, OLEUI_CCHKEYMAX_SIZE, NULL)) + { + // Use "the application which created it" as the name of the application + if (0==LoadString(ghInst, 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) + { +#ifdef OLE201 + lpPS->hMetaPictOD = GetIconOfClass( + ghInst, + &lpPS->clsidOD, + NULL, + TRUE); // Use the short user type name (auxusertype3) +#endif + lpPS->hMetaPictOD = NULL; + + + } + } + + // Does object offer CF_LINKSRCDESCRIPTOR? + if (lpPS->hLinkSrcDesc = OleStdGetData( + lpOPS->lpSrcDataObj, + (CLIPFORMAT) cfLinkSrcDescriptor, + NULL, + DVASPECT_CONTENT, + &medium)) + { + // Get FullUserTypeName, SourceOfCopy and CLSID + lpLSD = GlobalLock(lpPS->hLinkSrcDesc); + if (lpLSD->dwFullUserTypeName) + lpPS->szFullUserTypeNameLSD = (LPTSTR)lpLSD+lpLSD->dwFullUserTypeName; + else lpPS->szFullUserTypeNameLSD = lpPS->szUnknownType; + + if (lpLSD->dwSrcOfCopy) + lpPS->szSourceOfDataLSD = (LPTSTR)lpLSD+lpLSD->dwSrcOfCopy; + else lpPS->szSourceOfDataLSD = lpPS->szUnknownSource; + + // if no ObjectDescriptor, then use LinkSourceDescriptor source string + if (!lpPS->hObjDesc) + lpPS->szSourceOfDataOD = lpPS->szSourceOfDataLSD; + + 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) + { + TCHAR szLabel[OLEUI_CCHLABELMAX]; + HWND hIconWnd; + RECT IconRect; + int nWidth; + LPTSTR lpszLabel; + + hIconWnd = GetDlgItem(hDlg, ID_PS_ICONDISPLAY); + + GetClientRect(hIconWnd, &IconRect); + + nWidth = ((IconRect.right-IconRect.left) * 3) / 2; // width is 1.5 times width of iconbox + + LSTRCPYN(szLabel, lpPS->szSourceOfDataLSD, OLEUI_CCHLABELMAX); + szLabel[OLEUI_CCHLABELMAX-1] = TEXT('\0'); + + lpszLabel = ChopText(hIconWnd, nWidth, (LPTSTR)szLabel); + +#ifdef OLE201 + lpPS->hMetaPictLSD = GetIconOfClass( + ghInst, + &lpPS->clsidLSD, + lpszLabel, /* use chopped source string as label */ + FALSE /* not applicable */ + ); +#endif + lpPS->hMetaPictLSD = NULL; + + } + } + else if (lpPS->hObjDesc) // Does not offer CF_LINKSRCDESCRIPTOR but offers CF_OBJECTDESCRIPTOR + { + // Copy the values of OBJECTDESCRIPTOR + lpPS->szFullUserTypeNameLSD = lpPS->szFullUserTypeNameOD; + lpPS->szSourceOfDataLSD = lpPS->szSourceOfDataOD; + 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) + { + TCHAR szLabel[OLEUI_CCHLABELMAX]; + HWND hIconWnd; + RECT IconRect; + int nWidth; + LPTSTR lpszLabel; + + hIconWnd = GetDlgItem(hDlg, ID_PS_ICONDISPLAY); + + GetClientRect(hIconWnd, &IconRect); + + nWidth = ((IconRect.right-IconRect.left) * 3) / 2; // width is 1.5 times width of iconbox + + LSTRCPYN(szLabel, lpPS->szSourceOfDataLSD, OLEUI_CCHLABELMAX); + szLabel[OLEUI_CCHLABELMAX-1] = TEXT('\0'); + + lpszLabel = ChopText(hIconWnd, nWidth, (LPTSTR)szLabel); + +#ifdef OLE201 + lpPS->hMetaPictLSD = GetIconOfClass( + ghInst, + &lpPS->clsidLSD, + lpszLabel, /* Use chopped source string as label */ + FALSE /* Not applicable */ + ); +#endif + lpPS->hMetaPictLSD = NULL; + + } + } + + // Not an OLE object + if (lpPS->hObjDesc == NULL && lpPS->hLinkSrcDesc == NULL) + { + lpPS->szFullUserTypeNameLSD = lpPS->szFullUserTypeNameOD = lpPS->szUnknownType; + lpPS->szSourceOfDataLSD = lpPS->szSourceOfDataOD = lpPS->szUnknownSource; + lpPS->hMetaPictLSD = lpPS->hMetaPictOD = NULL; + } + + // Allocate scratch memory to construct item names in the paste and pastelink listboxes + 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 + fPasteAvailable = FFillPasteList(hDlg, lpPS); + if (!fPasteAvailable) + { + lpPS->dwFlags &= ~PSF_SELECTPASTE; + EnableWindow(GetDlgItem(hDlg, ID_PS_PASTE), FALSE); + } + + // Check if items are available to be paste-linked + fPasteLinkAvailable = FFillPasteLinkList(hDlg, lpPS); + if (!fPasteLinkAvailable) + { + lpPS->dwFlags &= ~PSF_SELECTPASTELINK; + EnableWindow(GetDlgItem(hDlg, ID_PS_PASTELINK), FALSE); + } + + // 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; + + if (lpPS->dwFlags & PSF_SELECTPASTE) + { + // FTogglePaste will set the PSF_SELECTPASTE flag, so clear it. + lpPS->dwFlags &= ~PSF_SELECTPASTE; + CheckRadioButton(hDlg, ID_PS_PASTE, ID_PS_PASTELINK, ID_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, ID_PS_PASTE, ID_PS_PASTELINK, ID_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); + } + + // Give initial focus to the list box + SetFocus(GetDlgItem(hDlg, ID_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, ID_PS_ICONDISPLAY, SW_HIDE); + + hListDisplay = GetDlgItem(hDlg, ID_PS_DISPLAYLIST); + + // If Paste was selected + if (lpPS->dwFlags & PSF_SELECTPASTE) + { + // Set the Source of the object in the clipboard + SetDlgItemText(hDlg, ID_PS_SOURCETEXT, lpPS->szSourceOfDataOD); + + // If an icon is available + if (lpPS->hMetaPictOD) + // Set the icon display + SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGESET, + (WPARAM)lpPS->hMetaPictOD, 0L); + + + hList = GetDlgItem(hDlg, ID_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, ID_PS_SOURCETEXT, lpPS->szSourceOfDataLSD); + + // If an icon is available + if (lpPS->hMetaPictLSD) + // Set the icon display + SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGESET, + (WPARAM)lpPS->hMetaPictLSD, 0L); + + + hList = GetDlgItem(hDlg, ID_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 + 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, ID_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, ID_PS_DISPLAYASICON, FALSE); + EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), FALSE); + + // Hide IconDisplay and ChangeIcon button + StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); + StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_HIDE); + } + else if (fSrcOnlyIconic) // Does SOURCE specify OLEMISC_ONLYICONIC? + { + // Check & Disable DisplayAsIcon + lpPS->dwFlags |= PSF_CHECKDISPLAYASICON; + CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, TRUE); + EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), FALSE); + + // Show IconDisplay and ChangeIcon button + StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_SHOWNORMAL); + StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_SHOWNORMAL); + } + else if (fSrcAspectIcon) // Does SOURCE specify DVASPECT_ICON? + { + // Check & Enable DisplayAsIcon + lpPS->dwFlags |= PSF_CHECKDISPLAYASICON; + CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, TRUE); + EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), TRUE); + + // Show IconDisplay and ChangeIcon button + StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_SHOWNORMAL); + StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_SHOWNORMAL); + } + else + { + //Uncheck and Enable DisplayAsIcon + lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON; + CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, FALSE); + EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), TRUE); + + // Hide IconDisplay and ChangeIcon button + StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); + StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_HIDE); + + } + } + else // No icon available + { + // Unchecked & Disabled + lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON; + CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, FALSE); + EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), FALSE); + + // Hide IconDisplay and ChangeIcon button + StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); + StandardShowDlgItem(hDlg, ID_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, ID_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, ID_PS_ICONDISPLAY, i); + StandardShowDlgItem(hDlg, ID_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 + _fmemset((LPOLEUICHANGEICON)&ci, 0, sizeof(ci)); + + ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, ID_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, (LONG)(LPSTR)&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, ID_PS_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)ci.hMetaPict, 0L); + // 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, ID_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)/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(ghInst, iString, psz1, cch)) + { + // 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, ID_PS_RESULTTEXT, psz1); + + // Change the result bitmap + SendDlgItemMessage(hDlg, ID_PS_RESULTIMAGE, RIM_IMAGESET, iImage, 0L); + + GlobalUnlock(lpPS->hBuff); +} + +/* + * 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 + * pIMalloc LPMALLOC Memory Allocator + * 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, + LPMALLOC pIMalloc, LPTSTR lpszBuf, LPTSTR lpszFullUserTypeName) +{ + LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS; + LPPASTELISTITEMDATA lpItemData; + int nIndex; + + // Allocate memory for each list box item + lpItemData = (LPPASTELISTITEMDATA)pIMalloc->lpVtbl->Alloc( + pIMalloc, (DWORD)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( + (LPTSTR)lpszBuf, + lpOPS->arrPasteEntries[nPasteEntriesIndex].lpstrFormatName, + (LPTSTR)lpszFullUserTypeName + ); + + // only add to listbox if not a duplicate + if (LB_ERR!=SendMessage(hList,LB_FINDSTRING, 0, (LPARAM)(LPTSTR)lpszBuf)) { + // item is already in list; SKIP this one + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)lpItemData); + return TRUE; // this is NOT an error + } + + nIndex = (int)SendMessage( + hList, + (fInsertFirst ? LB_INSERTSTRING : LB_ADDSTRING), + 0, + (LPARAM)(LPTSTR)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; + LPMALLOC pIMalloc = NULL; + LPTSTR lpszBuf = (LPTSTR)GlobalLock(lpPS->hBuff); + HWND hList; + int i, j; + int nItems = 0; + int nDefFormat = -1; + BOOL fTryObjFmt = FALSE; + BOOL fInsertFirst; + BOOL fExclude; + HRESULT hrErr; + + hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); + if (hrErr != NOERROR) + goto error; + + hList = GetDlgItem(hDlg, ID_PS_PASTELIST); + + // 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==cfFileName + || lpOPS->arrPasteEntries[i].fmtetc.cfFormat==cfEmbeddedObject + || lpOPS->arrPasteEntries[i].fmtetc.cfFormat==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, + (LPCLSID)(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 + + if (!FAddPasteListItem(hList, fInsertFirst, i, lpPS, pIMalloc, + lpszBuf, lpPS->szFullUserTypeNameOD)) + goto error; + nItems++; + } + } + + // initialize selection to first format matched in list + if (nDefFormat >= 0) + lpPS->nPasteListCurSel = nDefFormat; + + // Clean up + if (pIMalloc) + pIMalloc->lpVtbl->Release(pIMalloc); + if (lpszBuf) + GlobalUnlock(lpPS->hBuff); + + // 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: + if (pIMalloc) + pIMalloc->lpVtbl->Release(pIMalloc); + if (lpszBuf) + GlobalUnlock(lpPS->hBuff); + 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; + LPMALLOC pIMalloc = NULL; + LPTSTR lpszBuf = (LPTSTR)GlobalLock(lpPS->hBuff); + 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; + + hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); + if (hrErr != NOERROR) + goto error; + + // Remember which link type formats are offered by lpSrcDataObj. + _fmemset(&fmtetc, 0, sizeof(FORMATETC)); + for (i = 0; i < lpOPS->cLinkTypes; i++) + { + if (lpOPS->arrLinkTypes[i] = 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->lpVtbl->QueryGetData(lpSrcDataObj,&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, ID_PS_PASTELINKLIST); + + // 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; + pasteFlag*=2, j++) + { + if ((lpOPS->arrPasteEntries[i].dwFlags & pasteFlag) && + arrLinkTypesSupported[j]) + { + fLinkTypeSupported = TRUE; + break; + } + } + } + + fInsertFirst = FALSE; + + if (lpOPS->arrPasteEntries[i].fmtetc.cfFormat==cfFileName + || lpOPS->arrPasteEntries[i].fmtetc.cfFormat==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 + + if (!FAddPasteListItem(hList, fInsertFirst, i, lpPS, pIMalloc, + lpszBuf, lpPS->szFullUserTypeNameLSD)) + goto error; + 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 (pIMalloc) + pIMalloc->lpVtbl->Release(pIMalloc); + if (lpszBuf) + GlobalUnlock(lpPS->hBuff); + + // 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: + if (pIMalloc) + pIMalloc->lpVtbl->Release(pIMalloc); + if (lpszBuf) + GlobalUnlock(lpPS->hBuff); + 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; + LPMALLOC pIMalloc; + HRESULT hrErr; + + hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); + if (hrErr != NOERROR) + return; + + 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) + pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)lpItemData); + } + pIMalloc->lpVtbl->Release(pIMalloc); +} + +/* + * 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 == TEXT('%')) + { +#ifdef WIN32 + // AnsiNext is obsolete in Win32 + lpszTmp = CharNext(lpszTmp); +#else + lpszTmp = AnsiNext(lpszTmp); +#endif + if (*lpszTmp == TEXT('s')) // If %s, return + { + GlobalUnlock(lpPS->hBuff); + return TRUE; + } + else if (*lpszTmp == TEXT('%')) // if %%, skip to next character +#ifdef WIN32 + // AnsiNext is obsolete in Win32 + lpszTmp = CharNext(lpszTmp); +#else + lpszTmp = AnsiNext(lpszTmp); +#endif + } + else +#ifdef WIN32 + lpszTmp = CharNext(lpszTmp); +#else + lpszTmp = AnsiNext(lpszTmp); +#endif + } + + 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+nAlloc)); +} + diff --git a/private/oleutest/letest/ole2ui/pastespl.dlg b/private/oleutest/letest/ole2ui/pastespl.dlg new file mode 100644 index 000000000..d64f5e45c --- /dev/null +++ b/private/oleutest/letest/ole2ui/pastespl.dlg @@ -0,0 +1,40 @@ +// DLGINCLUDE RCDATA DISCARDABLE +// BEGIN +// "PASTESPL.H\0" +// END + +IDD_PASTESPECIAL DIALOG 3, 15, 293, 140 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Paste Special" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Source:", ID_PS_STXSOURCE, 6, 9, 30, 8 + LTEXT "", ID_PS_SOURCETEXT, 37, 9, 180, 8, SS_NOPREFIX | NOT + WS_GROUP + CONTROL "&Paste", ID_PS_PASTE, "Button", BS_AUTORADIOBUTTON | + WS_GROUP | WS_TABSTOP, 6, 38, 55, 10 + CONTROL "Paste &Link", ID_PS_PASTELINK, "Button", + BS_AUTORADIOBUTTON, 6, 63, 55, 10 + LTEXT "&As:", ID_PS_STXAS, 65, 25, 16, 8 + LISTBOX ID_PS_PASTELIST, 65, 36, 153, 57, LBS_USETABSTOPS | + WS_VSCROLL | WS_GROUP | WS_TABSTOP | NOT WS_VISIBLE + LISTBOX ID_PS_PASTELINKLIST, 65, 36, 153, 57, LBS_USETABSTOPS | + WS_VSCROLL | WS_GROUP | WS_TABSTOP | NOT WS_VISIBLE + LISTBOX ID_PS_DISPLAYLIST, 65, 36, 153, 57, LBS_USETABSTOPS | + WS_VSCROLL | WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "OK", IDOK, 224, 6, 66, 14, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, 224, 23, 66, 14 + PUSHBUTTON "&Help", ID_OLEUIHELP, 224, 42, 66, 14 + CONTROL "&Display As Icon", ID_PS_DISPLAYASICON, "Button", + BS_AUTOCHECKBOX | WS_TABSTOP, 224, 59, 66, 14 +// CONTROL "", ID_PS_ICONDISPLAY, SZCLASSICONBOX, 0, 224, 75, 66, 44 + PUSHBUTTON "Change &Icon...", ID_PS_CHANGEICON, 224, 123, 66, 14 +// CONTROL "", ID_PS_RESULTIMAGE, SZCLASSRESULTIMAGE, 0, 8, 101, +// 42, 34 + LTEXT "Result", ID_PS_RESULTTEXT, 54, 100, 159, 35, + SS_NOPREFIX | NOT WS_GROUP + GROUPBOX "Result", ID_PS_RESULTGROUP, 6, 90, 212, 48, WS_GROUP +END + + + diff --git a/private/oleutest/letest/ole2ui/pastespl.h b/private/oleutest/letest/ole2ui/pastespl.h new file mode 100644 index 000000000..526462f36 --- /dev/null +++ b/private/oleutest/letest/ole2ui/pastespl.h @@ -0,0 +1,110 @@ +/* + * PASTESPL.H + * + * Internal definitions, structures, and function prototypes for the + * OLE 2.0 UI Paste Special dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#ifndef _PASTESPL_H_ +#define _PASTESPL_H_ + +#ifndef RC_INVOKED +#pragma message ("INCLUDING PASTESPL.H from " __FILE__) +#endif /* RC_INVOKED */ + + +// Length of buffers to hold the strings 'Unknown Type', Unknown Source' +// and 'the application which created it' +#define PS_UNKNOWNSTRLEN 100 + +//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. + + /* + * 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 + LPTSTR szFullUserTypeNameOD; // Full User Type Name + LPTSTR szSourceOfDataOD; // 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 + LPTSTR szFullUserTypeNameLSD;// Full User Type Name + LPTSTR szSourceOfDataLSD; // 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.C +BOOL CALLBACK EXPORT 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, LPMALLOC, LPTSTR, LPTSTR); +BOOL FFillPasteList(HWND, LPPASTESPECIAL); +BOOL FFillPasteLinkList(HWND, LPPASTESPECIAL); +BOOL FHasPercentS(LPCTSTR, LPPASTESPECIAL); +HGLOBAL AllocateScratchMem(LPPASTESPECIAL); +void FreeListData(HWND); + +#endif //_PASTESPL_H_ + diff --git a/private/oleutest/letest/ole2ui/precomp.c b/private/oleutest/letest/ole2ui/precomp.c new file mode 100644 index 000000000..1385d8a41 --- /dev/null +++ b/private/oleutest/letest/ole2ui/precomp.c @@ -0,0 +1,23 @@ +/* + * PRECOMP.C + * + * This file is used to precompile the OLE2UI.H header file + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" + +// This dummy function is needed in order for the static link version +// of this library to work correctly. When we include PRECOMP.OBJ +// in our library (.LIB file), it will only get linked into our +// application IFF at least one function in precomp.c is called from +// either our EXE or LIB. Therefore, we will use a function +// here called OleUIStaticLibDummy(). You need to call it from +// your application. + +void FAR PASCAL OleUIStaticLibDummy(void) +{ + +} diff --git a/private/oleutest/letest/ole2ui/prompt.dlg b/private/oleutest/letest/ole2ui/prompt.dlg new file mode 100644 index 000000000..fc8474315 --- /dev/null +++ b/private/oleutest/letest/ole2ui/prompt.dlg @@ -0,0 +1,80 @@ +Exclamation ICON bang.ico + + +IDD_LINKSOURCEUNAVAILABLE DIALOG 21, 34, 175, 78 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "Exclamation", ID_DUMMY, 8, 8, 0, 0, SS_ICON + LTEXT "This action cannot be completed because the selected link's source is presently unavailable.", ID_PU_TEXT, 48, 8, 117, 32 + DEFPUSHBUTTON "OK", IDOK, 39, 58, 40, 14 + PUSHBUTTON "Links...", ID_PU_LINKS, 95, 58, 40, 14 +END + + +IDD_CANNOTUPDATELINK DIALOG 21, 34, 175, 78 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "Exclamation", ID_DUMMY, 8, 8, 0, 0, SS_ICON + LTEXT "Some links could not be updated because their sources are presently unavailable.", ID_PU_TEXT, 48, 8, 117, 32 + DEFPUSHBUTTON "OK", IDOK, 39, 58, 40, 14 + PUSHBUTTON "Links...", ID_PU_LINKS, 95, 58, 40, 14 +END + + +IDD_SERVERNOTREG DIALOG 39, 30, 198, 78 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +BEGIN + ICON "Exclamation", ID_DUMMY, 8, 8, 0, 0, SS_ICON + LTEXT "The application necessary to activate this %s is unavailable. You may convert it to or activate it as another type of object using Convert...", ID_PU_TEXT, 39, 8, 152, 36 + DEFPUSHBUTTON "Convert...", ID_PU_CONVERT, 23, 58, 40, 14 + PUSHBUTTON "Cancel", IDCANCEL, 79, 58, 40, 14 + PUSHBUTTON "Help", ID_OLEUIHELP, 135, 58, 40, 14 +END + + +IDD_LINKTYPECHANGED DIALOG 39, 30, 198, 78 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +BEGIN + ICON "Exclamation", ID_DUMMY, 8, 8, 0, 0, SS_ICON + LTEXT "The link is no longer a %s. Please choose a different command offered by the new type.", + ID_PU_TEXT, 39, 8, 152, 36 + PUSHBUTTON "OK", IDOK, 79, 58, 40, 14 +END + + +IDD_SERVERNOTFOUND DIALOG 36, 39, 183, 90 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +BEGIN + ICON "Exclamation", ID_DUMMY, 8, 8, 0, 0, SS_ICON + LTEXT "The server application cannot be found.\n\nMake sure the application is properly installed, or exists in your DOS path, and that is has not been deleted, moved, or renamed.", + ID_PU_TEXT, 38, 8, 136, 52 + DEFPUSHBUTTON "OK", IDOK, 71, 70, 40, 14 +END + + +IDD_UPDATELINKS DIALOG 50, 57, 179, 55 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", ID_PU_METER, "Static", SS_BLACKFRAME, 5, 40, 122, 9 + DEFPUSHBUTTON "Stop", ID_PU_STOP, 134, 37, 40, 14 + LTEXT "Update links...", ID_DUMMY, 5, 7, 56, 8 + LTEXT "", ID_PU_PERCENT, 56, 26, 20, 8 +END + + +IDD_OUTOFMEMORY DIALOG 36, 39, 107, 73 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg" +BEGIN + ICON "Exclamation", ID_DUMMY, 8, 8, 0, 0, SS_ICON + LTEXT "Out of memory!", ID_PU_TEXT, 41, 13, 57, 12 + DEFPUSHBUTTON "OK", IDOK, 33, 53, 40, 14 +END diff --git a/private/oleutest/letest/ole2ui/regdb.c b/private/oleutest/letest/ole2ui/regdb.c new file mode 100644 index 000000000..b6922b260 --- /dev/null +++ b/private/oleutest/letest/ole2ui/regdb.c @@ -0,0 +1,401 @@ +/* + * REGDB.C + * + * Functions to query the registration database + * + * OleStdGetMiscStatusOfClass + * OleStdGetDefaultFileFormatOfClass + * OleStdGetAuxUserType + * OleStdGetUserTypeOfClass + * + * (c) Copyright Microsoft Corp. 1992-1993 All Rights Reserved + * + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "common.h" +#include <ctype.h> + +OLEDBGDATA + +// Replacement for stdlib atol, +// which didn't work and doesn't take far pointers. +// Must be tolerant of leading spaces. +// +// +static LONG Atol(LPTSTR lpsz) +{ + signed int sign = +1; + UINT base = 10; + LONG l = 0; + + if (NULL==lpsz) + { + OleDbgAssert (0); + return 0; + } + while (isspace(*lpsz)) + lpsz++; + + if (*lpsz=='-') + { + lpsz++; + sign = -1; + } + if (lpsz[0]==TEXT('0') && lpsz[1]==TEXT('x')) + { + base = 16; + lpsz+=2; + } + + if (base==10) + { + while (isdigit(*lpsz)) + { + l = l * base + *lpsz - '0'; + lpsz++; + } + } + else + { + OleDbgAssert (base==16); + while (isxdigit(*lpsz)) + { + l = l * base + isdigit(*lpsz) ? *lpsz - '0' : toupper(*lpsz) - 'A' + 10; + lpsz++; + } + } + return l * sign; +} + + + +/* + * OleStdGetUserTypeOfClass(REFCLSID, LPSTR, UINT, HKEY) + * + * Purpose: + * Returns the user type (human readable class name) of the specified class. + * + * Parameters: + * rclsid pointer to the clsid to retrieve user type of. + * lpszUserType pointer to buffer to return user type in. + * cch length of buffer pointed to by lpszUserType + * hKey hKey for reg db - if this is NULL, then we + * open and close the reg db within this function. If it + * is non-NULL, then we assume it's a valid key to the + * \ root and use it without closing it. (useful + * if you're doing lots of reg db stuff). + * + * Return Value: + * UINT Number of characters in returned string. 0 on error. + * + */ +STDAPI_(UINT) OleStdGetUserTypeOfClass(REFCLSID rclsid, LPTSTR lpszUserType, UINT cch, HKEY hKey) +{ + + LONG dw; + LONG lRet; + LPSTR lpszCLSID, lpszProgID; + BOOL fFreeProgID = FALSE; + BOOL bCloseRegDB = FALSE; + TCHAR szKey[128]; + LPMALLOC lpIMalloc; + + if (!lpszUserType) + return 0; + + *lpszUserType = TEXT('\0'); + if (hKey == NULL) + { + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return (UINT)FALSE; + + bCloseRegDB = TRUE; + } + + // Get a string containing the class name + StringFromCLSIDA(rclsid, &lpszCLSID); + + wsprintf(szKey, TEXT("CLSID\\%s"), lpszCLSID); + + dw=cch; + lRet = RegQueryValue(hKey, szKey, lpszUserType, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) { + // Load 'Unknown Source' and 'Unknown Type' strings + dw = (LONG)LoadString(ghInst, IDS_PSUNKNOWNTYPE, lpszUserType, cch); + } + + if ( ((LONG)ERROR_SUCCESS!=lRet) && (CoIsOle1Class(rclsid)) ) + { + // We've got an OLE 1.0 class, so let's try to get the user type + // name from the ProgID entry. + + ProgIDFromCLSIDA(rclsid, &lpszProgID); + fFreeProgID = TRUE; + + dw = cch; + lRet = RegQueryValue(hKey, lpszProgID, lpszUserType, &dw); + + if ((LONG)ERROR_SUCCESS != lRet) + dw = 0; + } + + + if (NOERROR == CoGetMalloc(MEMCTX_TASK, &lpIMalloc)) + { + if (fFreeProgID) + lpIMalloc->lpVtbl->Free(lpIMalloc, (LPVOID)lpszProgID); + + lpIMalloc->lpVtbl->Free(lpIMalloc, (LPVOID)lpszCLSID); + lpIMalloc->lpVtbl->Release(lpIMalloc); + } + + if (bCloseRegDB) + RegCloseKey(hKey); + + return (UINT)dw; + +} + + + +/* + * OleStdGetAuxUserType(RCLSID, WORD, LPSTR, int, HKEY) + * + * Purpose: + * Returns the specified AuxUserType from the reg db. + * + * Parameters: + * rclsid pointer to the clsid to retrieve aux user type of. + * hKey hKey for reg db - if this is NULL, then we + * open and close the reg db within this function. If it + * is non-NULL, then we assume it's a valid key to the + * \ root and use it without closing it. (useful + * if you're doing lots of reg db stuff). + * wAuxUserType which aux user type field to look for. In 4/93 release + * 2 is short name and 3 is exe name. + * lpszUserType pointer to buffer to return user type in. + * cch length of buffer pointed to by lpszUserType + * + * Return Value: + * UINT Number of characters in returned string. 0 on error. + * + */ +STDAPI_(UINT) OleStdGetAuxUserType(REFCLSID rclsid, + WORD wAuxUserType, + LPTSTR lpszAuxUserType, + int cch, + HKEY hKey) +{ + HKEY hThisKey; + BOOL fCloseRegDB = FALSE; + LONG dw; + LRESULT lRet; + LPTSTR lpszCLSID; + LPMALLOC lpIMalloc; + TCHAR szKey[OLEUI_CCHKEYMAX]; + TCHAR szTemp[32]; + + lpszAuxUserType[0] = TEXT('\0'); + + if (NULL == hKey) + { + lRet = RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hThisKey); + + if (ERROR_SUCCESS != lRet) + return 0; + } + else + hThisKey = hKey; + + StringFromCLSIDA(rclsid, &lpszCLSID); + + lstrcpy(szKey, TEXT("CLSID\\")); + lstrcat(szKey, lpszCLSID); + wsprintf(szTemp, TEXT("\\AuxUserType\\%d"), wAuxUserType); + lstrcat(szKey, szTemp); + + dw = cch; + + lRet = RegQueryValue(hThisKey, szKey, lpszAuxUserType, &dw); + + if (ERROR_SUCCESS != lRet) { + dw = 0; + lpszAuxUserType[0] = TEXT('\0'); + } + + + if (fCloseRegDB) + RegCloseKey(hThisKey); + + if (NOERROR == CoGetMalloc(MEMCTX_TASK, &lpIMalloc)) + { + lpIMalloc->lpVtbl->Free(lpIMalloc, (LPVOID)lpszCLSID); + lpIMalloc->lpVtbl->Release(lpIMalloc); + } + + return (UINT)dw; +} + + + +/* + * OleStdGetMiscStatusOfClass(REFCLSID, HKEY) + * + * Purpose: + * Returns the value of the misc status for the given clsid. + * + * Parameters: + * rclsid pointer to the clsid to retrieve user type of. + * hKey hKey for reg db - if this is NULL, then we + * open and close the reg db within this function. If it + * is non-NULL, then we assume it's a valid key to the + * \\CLSID root and use it without closing it. (useful + * if you're doing lots of reg db stuff). + * + * Return Value: + * BOOL TRUE on success, FALSE on failure. + * + */ +STDAPI_(BOOL) OleStdGetMiscStatusOfClass(REFCLSID rclsid, HKEY hKey, DWORD FAR * lpdwValue) +{ + DWORD dw; + LONG lRet; + LPTSTR lpszCLSID; + TCHAR szKey[64]; + TCHAR szMiscStatus[OLEUI_CCHKEYMAX]; + BOOL bCloseRegDB = FALSE; + + if (hKey == NULL) + { + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return FALSE; + + bCloseRegDB = TRUE; + } + + // Get a string containing the class name + StringFromCLSIDA(rclsid, &lpszCLSID); + + // Construct key + lstrcpy(szKey, lpszCLSID); + + lstrcat(szKey, TEXT("\\MiscStatus")); + + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet = RegQueryValue(hKey, szKey, (LPTSTR)szMiscStatus, &dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + { + OleStdFreeString(lpszCLSID, NULL); + + if (bCloseRegDB) + RegCloseKey(hKey); + + return FALSE; + + } + + *lpdwValue = Atol((LPTSTR)szMiscStatus); + + OleStdFreeString(lpszCLSID, NULL); + + if (bCloseRegDB) + RegCloseKey(hKey); + + return TRUE; + + +} + + +/* + * CLIPFORMAT OleStdGetDefaultFileFormatOfClass(REFCLSID, HKEY) + * + * Purpose: + * Returns the default file format of the specified class. + * this is entered in REGDB as follows: + * CLSID\{...}\DataFormats\DefaultFile = <cfFmt> + * + * Parameters: + * rclsid pointer to the clsid to retrieve user type of. + * hKey hKey for reg db- if this is NULL, then we + * open and close the reg db within this function. If it + * is non-NULL, then we assume it's a valid key to the + * \ root and use it without closing it. (useful + * if you're doing lots of reg db stuff). + * + * Return Value: + * cfFmt -- DefaultFile format + * NULL -- failed to get default file format + * + */ +STDAPI_(CLIPFORMAT) OleStdGetDefaultFileFormatOfClass( + REFCLSID rclsid, + HKEY hKey +) +{ + CLIPFORMAT cfFmt = 0; + DWORD dw; + LONG lRet; + LPTSTR lpszCLSID; + BOOL bCloseRegDB = FALSE; + TCHAR szKey[128]; + TCHAR szDefaultFile[OLEUI_CCHKEYMAX]; + BOOL bStatus = TRUE; + + + if (hKey == NULL) + { + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return 0; + + bCloseRegDB = TRUE; + } + + + // Get a string containing the class name + StringFromCLSIDA(rclsid, &lpszCLSID); + + // Construct key + wsprintf(szKey, TEXT("CLSID\\%s\\DataFormats\\DefaultFile"), lpszCLSID); + + OleStdFreeString(lpszCLSID, NULL); + + dw=OLEUI_CCHKEYMAX_SIZE; + lRet = RegQueryValue(hKey, szKey, (LPTSTR)szDefaultFile, (LONG FAR *)&dw); + + if ((LONG)ERROR_SUCCESS!=lRet) + bStatus = FALSE; + else { + /* if the format is a number, then it should refer to one of the + ** standard Windows formats. + */ + if (isdigit(szDefaultFile[0])) + cfFmt = (CLIPFORMAT)Atol(szDefaultFile); + else + cfFmt = RegisterClipboardFormat(szDefaultFile); + } + + if (bCloseRegDB) + RegCloseKey(hKey); + + return cfFmt; +} + + diff --git a/private/oleutest/letest/ole2ui/regdb.h b/private/oleutest/letest/ole2ui/regdb.h new file mode 100644 index 000000000..d05bc93b2 --- /dev/null +++ b/private/oleutest/letest/ole2ui/regdb.h @@ -0,0 +1,8 @@ +// This file is now OBSOLETE (include olestd.h instead) +/* + * Regdb.h + * + * (c) Copyright Microsoft Corp. 1992 All Rights Reserved + */ + +// Function prototypes moved to olestd.h diff --git a/private/oleutest/letest/ole2ui/resimage.c b/private/oleutest/letest/ole2ui/resimage.c new file mode 100644 index 000000000..8a95f4c71 --- /dev/null +++ b/private/oleutest/letest/ole2ui/resimage.c @@ -0,0 +1,363 @@ +/* + * RESIMAGE.C + * + * 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 + */ + + +#define STRICT 1 +#include "ole2ui.h" +#include "resimage.h" + +OLEDBGDATA + +//Flag indicating if we've registered the class +static BOOL fRegistered=FALSE; + +//Bitmap and image dimensions for result images. +static HBITMAP hBmpResults=NULL; +static UINT cxBmpResult=0; +static UINT cyBmpResult=0; + +/* + * 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. + * + * lpszClassName LPSTR containing the class name to register the + * ResultImage control class with. + * + * Return Value: + * BOOL TRUE if all initialization succeeded, FALSE otherwise. + */ + +BOOL FResultImageInitialize(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpszClassName) + { + 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; + + 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; + cyBmpResult=bm.bmHeight/CIMAGESY; + + + // 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 in the same instance + + if (!fRegistered) + { + 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.lpszClassName =lpszClassName; + wc.style =CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW; + + fRegistered = RegisterClass(&wc); + } + } + + return fRegistered; +} + + + + + +/* + * ResultImageUninitialize + * + * Purpose: + * Cleans up anything done in FResultImageInitialize, such as freeing + * the bitmaps. Call from WEP. + * + * Parameters: + * None + * + * Return Value: + * None + */ + +void ResultImageUninitialize(void) + { + if (NULL!=hBmpResults) + { + DeleteObject(hBmpResults); + } + + return; + } + + + + + + +/* + * 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 EXPORT 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); + + if (RESULTIMAGE_NONE!=iBmp) + { + 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); +#if defined( WIN32 ) + hBr = (HBRUSH)SendMessage(hDlg, + WM_CTLCOLORDLG, + (WPARAM)hDCDlg, + (LPARAM)hDlg); +#else + hBr = (HBRUSH)SendMessage(hDlg, + WM_CTLCOLOR, + (WPARAM)hDCDlg, + MAKELPARAM(hDlg, CTLCOLOR_DLG)); +#endif + ReleaseDC(hDlg, hDCDlg); + + GetObject(hBr, sizeof(LOGBRUSH), &lb); + SetBkColor(hDC, lb.lbColor); + + TransparentBlt(hDC, x, y, hBmpResults, 0, iBmp*cyBmpResult + , cxBmpResult, cyBmpResult, RGBTRANSPARENT); + } + + 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=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); + + return; + } diff --git a/private/oleutest/letest/ole2ui/resimage.h b/private/oleutest/letest/ole2ui/resimage.h new file mode 100644 index 000000000..31640be91 --- /dev/null +++ b/private/oleutest/letest/ole2ui/resimage.h @@ -0,0 +1,61 @@ +/* + * 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_MIN 0 +#define RESULTIMAGE_MAX 6 + + +//Total number of images in each bitmap. +#define CIMAGESY (RESULTIMAGE_MAX+1) + +//The color to use for transparancy (cyan) +#define RGBTRANSPARENT RGB(0, 255, 255) + + +//Function prototypes +BOOL FResultImageInitialize(HINSTANCE, HINSTANCE, LPTSTR); +void ResultImageUninitialize(void); +LONG CALLBACK EXPORT ResultImageWndProc(HWND, UINT, WPARAM, LPARAM); +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/oleutest/letest/ole2ui/stdpal.c b/private/oleutest/letest/ole2ui/stdpal.c new file mode 100644 index 000000000..abe3e82ac --- /dev/null +++ b/private/oleutest/letest/ole2ui/stdpal.c @@ -0,0 +1,94 @@ +/*----------------------------------------------------------------------- +| stdpal.c +| +| Standard App Palette useful for OLE applications. v 1.01 +| +| NOTE: Palette MUST be created with OleStdCreateStandardPalette +| +| Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved. +| +-----------------------------------------------------------------------*/ + +#ifndef PC_RESERVED +#ifndef INC_OLE2 + #define INC_OLE2 +#endif + +#undef UNICODE +#include <windows.h> +#include <ole2.h> +#endif + +#include "stdpal.h" + +#define cpeAppPal 256 // number of colors in our apps palette +typedef struct + { + WORD wVersion; + WORD cpe; + PALETTEENTRY rgpe[cpeAppPal]; + } LOGPAL; + + +/*----------------------------------------------------------------------- +| OleStdCreateStandardPalette +| +| Creates the standard Apps palette. Create one of these for your +| app, and select/realize it into each DC. +| +| Arguments: +| void: +| +| Returns: +| +| Keywords: +-----------------------------------------------------------------------*/ +STDAPI_(HPALETTE) OleStdCreateStandardPalette(void) + { + HDC hdc; + HPALETTE hpal; + + hpal = (HPALETTE) NULL; + hdc = GetDC(NULL); + if (hdc != NULL && GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) + { + int cpeSysPal; + int cpeReserved; + + cpeSysPal = GetDeviceCaps(hdc, SIZEPALETTE); + cpeReserved = GetDeviceCaps(hdc, NUMRESERVED); + if (cpeSysPal > cpeReserved) + { + int cpeReserved2; + unsigned char FAR* lpb; + PALETTEENTRY FAR* ppe; + PALETTEENTRY FAR* ppeMac; + LOGPAL logpal; + + cpeReserved2 = cpeReserved/2; + + // Get the system palette entries at the beginning and end. + GetSystemPaletteEntries(hdc, 0, cpeReserved2, logpal.rgpe); + GetSystemPaletteEntries(hdc, cpeSysPal - cpeReserved2, cpeReserved2, + &logpal.rgpe[cpeAppPal-cpeReserved2]); + + logpal.cpe = cpeAppPal; + logpal.wVersion = 0x300; + + lpb = (BYTE FAR *) &palSVGA[10]; + ppe = (PALETTEENTRY FAR*)&logpal.rgpe[cpeReserved2]; + ppeMac = (PALETTEENTRY FAR*)&logpal.rgpe[cpeAppPal-cpeReserved2]; + while (ppe < ppeMac) + { + ppe->peFlags = PC_NOCOLLAPSE; + ppe->peRed = *lpb++; + ppe->peGreen = *lpb++; + ppe->peBlue = *lpb++; + ppe++; + } + hpal = CreatePalette((LOGPALETTE FAR *)&logpal); + } + } + ReleaseDC(NULL, hdc); + return hpal; + } diff --git a/private/oleutest/letest/ole2ui/stdpal.h b/private/oleutest/letest/ole2ui/stdpal.h new file mode 100644 index 000000000..59162ed78 --- /dev/null +++ b/private/oleutest/letest/ole2ui/stdpal.h @@ -0,0 +1,292 @@ +/*----------------------------------------------------------------------- +| stdpal.h +| +| Standard App Palette useful for OLE applications. v 1.01 +| +| #include this file in the same file as HpalCreateAppPalette +| +| NOTE: Palette MUST be created with HpalCreateAppPalette +| +| Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved. +| +-----------------------------------------------------------------------*/ + +#include <commdlg.h> // needed for LPPRINTDLG +#include <shellapi.h> // needed for HKEY + +#ifdef WIN32 +#define _based(A) +#define _segname(A) +#endif + +#ifndef CSCONST +#ifdef FLAT +#define CSCONST(type) type const +#else +#define CSCONST(type) type _based(_segname("_CODE")) const +#endif +#endif + +CSCONST(unsigned char) palSVGA[256][3] = + { + // R G B + {0x00, 0x00, 0x00}, // 0 Sys Black gray 0 + {0x80, 0x00, 0x00}, // 1 Sys Dk Red + {0x00, 0x80, 0x00}, // 2 Sys Dk Green + {0x80, 0x80, 0x00}, // 3 Sys Dk Yellow + {0x00, 0x00, 0x80}, // 4 Sys Dk Blue + {0x80, 0x00, 0x80}, // 5 Sys Dk Violet + {0x00, 0x80, 0x80}, // 6 Sys Dk Cyan + {0xc0, 0xc0, 0xc0}, // 7 Sys Lt Grey gray 192 + {0xc0, 0xdc, 0xc0}, // 8 Sys 8 + {0xa6, 0xca, 0xf0}, // 9 Sys 9 (the first 10 are fixed by Windows) + + {0x80, 0x00, 0x00}, // 10 Sys Dk Red repeat + {0x00, 0x80, 0x00}, // 11 Sys Dk Green repeat + {0x80, 0x80, 0x00}, // 12 Sys Dk Yellow repeat + {0x00, 0x00, 0x80}, // 13 Sys Dk Blue repeat + {0x80, 0x00, 0x80}, // 14 Sys Dk Violet repeat + {0x00, 0x80, 0x80}, // 15 Sys Dk Cyan repeat + {0x80, 0x80, 0x80}, // 16 Sys Dk Grey repeat gray 128 + {0x80, 0x80, 0xff}, // 17 Excel Chart Fill 1 + {0x80, 0x20, 0x60}, // 18 Excel Chart Fill 2 + {0xff, 0xff, 0xc0}, // 19 Excel Chart Fill 3 + {0xa0, 0xe0, 0xe0}, // 20 Excel Chart Fill 4 + {0x60, 0x00, 0x80}, // 21 Excel Chart Fill 4 + {0xff, 0x80, 0x80}, // 22 Excel Chart Fill 6 + {0x00, 0x80, 0xc0}, // 23 Excel Chart Fill 7 + {0xc0, 0xc0, 0xff}, // 24 Excel Chart Fill 8 + {0x00, 0xcf, 0xff}, // 25 Excel clrt entry + {0x69, 0xff, 0xff}, // 26 Excel clrt entry + {0xe0, 0xff, 0xe0}, // 27 Excel clrt entry + {0xdd, 0x9c, 0xb3}, // 28 Excel clrt entry + {0xb3, 0x8f, 0xee}, // 29 Excel clrt entry + {0x2a, 0x6f, 0xf9}, // 30 Excel clrt entry + {0x3f, 0xb8, 0xcd}, // 31 Excel clrt entry + {0x48, 0x84, 0x36}, // 32 Excel clrt entry + {0x95, 0x8c, 0x41}, // 33 Excel clrt entry + {0x8e, 0x5e, 0x42}, // 34 Excel clrt entry + {0xa0, 0x62, 0x7a}, // 35 Excel clrt entry + {0x62, 0x4f, 0xac}, // 36 Excel clrt entry + {0x1d, 0x2f, 0xbe}, // 37 Excel clrt entry + {0x28, 0x66, 0x76}, // 38 Excel clrt entry + {0x00, 0x45, 0x00}, // 39 Excel clrt entry + {0x45, 0x3e, 0x01}, // 40 Excel clrt entry + {0x6a, 0x28, 0x13}, // 41 Excel clrt entry + {0x85, 0x39, 0x6a}, // 42 Excel clrt entry + {0x4a, 0x32, 0x85}, // 43 Excel clrt entry + {0x04, 0x04, 0x04}, // 44 gray 4 + {0x08, 0x08, 0x08}, // 45 gray 8 + {0x0c, 0x0c, 0x0c}, // 46 gray 12 + {0x11, 0x11, 0x11}, // 47 gray 17 + {0x16, 0x16, 0x16}, // 48 gray 22 + {0x1c, 0x1c, 0x1c}, // 49 gray 28 + {0x22, 0x22, 0x22}, // 50 gray 34 + {0x29, 0x29, 0x29}, // 51 gray 41 + {0x30, 0x30, 0x30}, // 52 gray 48 + {0x5f, 0x5f, 0x5f}, // 53 swapped so inversions look good gray 95 + {0x55, 0x55, 0x55}, // 54 swapped so inversions look good gray 85 + {0x4d, 0x4d, 0x4d}, // 55 swapped so inversions look good gray 77 + {0x42, 0x42, 0x42}, // 56 swapped so inversions look good gray 66 + {0x39, 0x39, 0x39}, // 57 swapped so inversions look good gray 57 + {0x00, 0x07, 0x00}, // 58 + {0x0d, 0x00, 0x00}, // 59 + {0xb7, 0x99, 0x81}, // 60 + {0x84, 0x99, 0xb4}, // 61 + {0xbd, 0xbd, 0x90}, // 62 + {0x7f, 0x7f, 0x60}, // 63 + {0x60, 0x60, 0x7f}, // 64 + {0x00, 0x0e, 0x00}, // 65 + {0x1b, 0x00, 0x00}, // 66 + {0x28, 0x00, 0x00}, // 67 + {0x08, 0x09, 0x2b}, // 68 + {0x00, 0x1d, 0x00}, // 69 + {0x39, 0x00, 0x00}, // 70 + {0x00, 0x00, 0x9b}, // 71 + {0x00, 0x25, 0x00}, // 72 + {0x49, 0x00, 0x00}, // 73 + {0x11, 0x11, 0x3b}, // 74 + {0x00, 0x2f, 0x00}, // 75 + {0x5d, 0x00, 0x00}, // 76 + {0x17, 0x17, 0x45}, // 77 + {0x00, 0x3a, 0x00}, // 78 + {0x49, 0x11, 0x11}, // 79 + {0x1c, 0x1c, 0x53}, // 80 + {0x00, 0x16, 0xff}, // 81 + {0x2b, 0x00, 0xff}, // 82 + {0x21, 0x21, 0x6c}, // 83 + {0x59, 0x14, 0x14}, // 84 + {0x00, 0x51, 0x00}, // 85 + {0x47, 0x1a, 0x6a}, // 86 + {0x19, 0x32, 0x67}, // 87 + {0x00, 0x61, 0x00}, // 88 + {0x00, 0x31, 0xff}, // 89 + {0x61, 0x00, 0xff}, // 90 + {0x53, 0x20, 0x7b}, // 91 + {0x16, 0x43, 0x67}, // 92 + {0x2e, 0x2e, 0xe2}, // 93 + {0x26, 0x59, 0x16}, // 94 + {0x51, 0x46, 0x04}, // 95 + {0x68, 0x2e, 0x49}, // 96 + {0x07, 0x52, 0x8f}, // 97 + {0x6a, 0x18, 0xb8}, // 98 + {0x90, 0x23, 0x15}, // 99 + {0x00, 0x53, 0xff}, // 100 + {0xa3, 0x00, 0xff}, // 101 + {0x6a, 0x4a, 0x12}, // 102 + {0x75, 0x33, 0x6c}, // 103 + {0x4a, 0x41, 0x9a}, // 104 + {0x37, 0x65, 0x0b}, // 105 + {0xa4, 0x2c, 0x15}, // 106 + {0x83, 0x1f, 0xb1}, // 107 + {0x4e, 0x2c, 0xff}, // 108 + {0x20, 0x51, 0xb6}, // 109 + {0x08, 0x64, 0x92}, // 110 + {0x6f, 0x56, 0x0b}, // 111 + {0x59, 0x43, 0xad}, // 112 + {0x36, 0x72, 0x12}, // 113 + {0xb0, 0x33, 0x17}, // 114 + {0x00, 0xa1, 0x00}, // 115 + {0x77, 0x5f, 0x1f}, // 116 + {0x89, 0x47, 0x71}, // 117 + {0xb0, 0x43, 0x1c}, // 118 + {0xb7, 0x2d, 0x7d}, // 119 + {0x00, 0x86, 0x95}, // 120 + {0x7a, 0x6e, 0x23}, // 121 + {0x26, 0x9f, 0x00}, // 122 + {0x73, 0xa9, 0x01}, // 123 + {0x00, 0x00, 0x00}, // 124 free 0 gray 0 + {0x00, 0x00, 0x00}, // 125 free 2 gray 0 + {0x00, 0x00, 0x00}, // 126 free 4 gray 0 + {0x00, 0x00, 0x00}, // 127 free 6 gray 0 + {0x00, 0x00, 0x00}, // 128 free 7 gray 0 + {0x00, 0x00, 0x00}, // 129 free 5 gray 0 + {0x00, 0x00, 0x00}, // 130 free 3 gray 0 + {0x00, 0x00, 0x00}, // 131 free 1 gray 0 + {0x00, 0xca, 0x00}, // 132 + {0xac, 0x5b, 0x01}, // 133 + {0x20, 0x1d, 0xc2}, // 134 + {0x94, 0x52, 0x70}, // 135 + {0x24, 0xaa, 0x4c}, // 136 + {0x0a, 0x94, 0x89}, // 137 + {0x36, 0x6e, 0x7b}, // 138 + {0x44, 0x75, 0x90}, // 139 + {0xff, 0x00, 0xa8}, // 140 + {0x00, 0x71, 0xff}, // 141 + {0xdf, 0x00, 0xff}, // 142 + {0x56, 0x91, 0x4a}, // 143 + {0x34, 0x48, 0xf8}, // 144 + {0xcc, 0x32, 0x82}, // 145 + {0xe4, 0x41, 0x70}, // 146 + {0x68, 0xca, 0x01}, // 147 + {0x36, 0xbc, 0x42}, // 148 + {0x00, 0x9a, 0xff}, // 149 + {0x96, 0x22, 0xb7}, // 150 + {0x85, 0x7d, 0x33}, // 151 + {0x25, 0xb7, 0x8c}, // 152 + {0x36, 0x5a, 0xed}, // 153 + {0x5c, 0xff, 0x00}, // 154 + {0xff, 0x48, 0x00}, // 155 + {0x22, 0x9b, 0xa2}, // 156 + {0x42, 0xcf, 0x4d}, // 157 + {0xc2, 0x58, 0x52}, // 158 + {0x20, 0xd3, 0x95}, // 159 + {0xa5, 0x24, 0xe0}, // 160 + {0x73, 0x56, 0xb5}, // 161 + {0xa9, 0xa9, 0x00}, // 162 + {0xd0, 0x6f, 0x3c}, // 163 + {0x67, 0x9f, 0x58}, // 164 + {0x89, 0xcf, 0x0b}, // 165 + {0xff, 0xac, 0x00}, // 166 + {0xa7, 0x2e, 0xfe}, // 167 + {0xe2, 0x59, 0x7f}, // 168 + {0x4c, 0xdc, 0x67}, // 169 + {0xff, 0x18, 0xff}, // 170 + {0x3a, 0x7d, 0xff}, // 171 + {0xb1, 0xd0, 0x18}, // 172 + {0xc7, 0xff, 0x00}, // 173 + {0xff, 0xe2, 0x00}, // 174 + {0xdf, 0x9a, 0x3d}, // 175 + {0x56, 0x81, 0x9f}, // 176 + {0xc6, 0x43, 0xba}, // 177 + {0xaf, 0x71, 0x8b}, // 178 + {0x38, 0xa2, 0xc9}, // 179 + {0xd1, 0x53, 0xce}, // 180 + {0xff, 0x9a, 0x65}, // 181 + {0x46, 0xca, 0xdb}, // 182 + {0xff, 0x4d, 0xff}, // 183 + {0xc8, 0xe9, 0x6a}, // 184 + {0x4c, 0xde, 0xe0}, // 185 + {0xff, 0x98, 0xff}, // 186 + {0xdf, 0xc0, 0x82}, // 187 + {0xe9, 0xec, 0xa5}, // 188 + {0xf5, 0xf6, 0xcd}, // 189 + {0xff, 0xd0, 0xff}, // 190 + {0xb1, 0xac, 0x5a}, // 191 + {0x63, 0x91, 0xae}, // 192 + {0x22, 0x4c, 0x65}, // 193 + {0x8d, 0x4e, 0x3f}, // 194 + {0x50, 0x70, 0x70}, // 195 + {0xd0, 0xff, 0xff}, // 196 + {0xff, 0xe7, 0xff}, // 197 + {0x69, 0x69, 0x69}, // 198 gray 105 + {0x77, 0x77, 0x77}, // 199 gray 119 + {0x86, 0x86, 0x86}, // 200 gray 134 + {0x96, 0x96, 0x96}, // 201 gray 150 + {0x9d, 0x9d, 0x9d}, // 202 gray 157 + {0xa4, 0xa4, 0xa4}, // 203 gray 164 + {0xb2, 0xb2, 0xb2}, // 204 gray 178 + {0xcb, 0xcb, 0xcb}, // 205 gray 203 + {0xd7, 0xd7, 0xd7}, // 206 gray 215 + {0xdd, 0xdd, 0xdd}, // 207 gray 221 + {0xe3, 0xe3, 0xe3}, // 208 gray 227 + {0xea, 0xea, 0xea}, // 209 gray 234 + {0xf1, 0xf1, 0xf1}, // 210 gray 241 + {0xf8, 0xf8, 0xf8}, // 211 gray 248 + {0xb2, 0xc1, 0x66}, // 212 + {0x80, 0xbf, 0x78}, // 213 + {0xc6, 0xf0, 0xf0}, // 214 + {0xb2, 0xa4, 0xff}, // 215 + {0xff, 0xb3, 0xff}, // 216 + {0xd1, 0x8e, 0xa3}, // 217 + {0xc3, 0xdc, 0x37}, // 218 + {0xa0, 0x9e, 0x54}, // 219 + {0x76, 0xae, 0x70}, // 220 + {0x78, 0x9e, 0xc1}, // 221 + {0x83, 0x64, 0xbf}, // 222 + {0xa4, 0x83, 0xd3}, // 223 + {0xd1, 0x3f, 0x32}, // 224 + {0xff, 0x7d, 0x00}, // 225 + {0x44, 0x78, 0x23}, // 226 + {0x24, 0x5f, 0x60}, // 227 + {0x0e, 0x0e, 0x2c}, // 228 + {0xbe, 0x00, 0x00}, // 229 + {0xff, 0x1f, 0x00}, // 230 + {0x31, 0x39, 0x00}, // 231 + {0xd9, 0x85, 0x3e}, // 232 + {0x02, 0x77, 0x85}, // 233 + {0xb0, 0xd8, 0x81}, // 234 + {0x56, 0x21, 0x1d}, // 235 + {0x00, 0x00, 0x30}, // 236 + {0x88, 0xc8, 0xb3}, // 237 + {0xa0, 0x79, 0x00}, // 238 + {0xc0, 0xc0, 0xc0}, // 239 Sys Dk Grey repeat inversion gray 192 + {0xea, 0x70, 0x81}, // 240 + {0x51, 0xf1, 0x69}, // 241 + {0xff, 0xff, 0x80}, // 242 + {0x91, 0x74, 0xcd}, // 243 + {0xff, 0x7c, 0xff}, // 244 + {0xa2, 0xff, 0xff}, // 245 + + {0xff, 0xfb, 0xf0}, // 246 Sys Reserved + {0xa0, 0xa0, 0xa4}, // 247 Sys Reserved + {0x80, 0x80, 0x80}, // 248 Sys Lt Gray gray 128 + {0xff, 0x00, 0x00}, // 249 Sys Red + {0x00, 0xff, 0x00}, // 250 Sys Green + {0xff, 0xff, 0x00}, // 251 Sys Yellow + {0x00, 0x00, 0xff}, // 252 Sys Blue + {0xff, 0x00, 0xff}, // 253 Sys Violet + {0x00, 0xff, 0xff}, // 254 Sys Cyan + {0xff, 0xff, 0xff} // 255 Sys White gray 255 + }; + diff --git a/private/oleutest/letest/ole2ui/strings.rc b/private/oleutest/letest/ole2ui/strings.rc new file mode 100644 index 000000000..f3f8c415a --- /dev/null +++ b/private/oleutest/letest/ole2ui/strings.rc @@ -0,0 +1,124 @@ +/* + * STRINGS.RC + * + * strings for the OLE 2.0 UI Support Library. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + + +#include "ole2ui.h" + + +//Stringtable common for all dialogs. +STRINGTABLE + BEGIN + IDS_FILTERS, "All Files (*.*)|*.*|" + IDS_ICONFILTERS, "Icon Files|*.exe;*.dll;*.ico|Programs (*.exe)|*.exe|Libraries (*.dll)|Icons (*.ico)|All Files (*.*)|*.*|" + END + +// browse dialog +STRINGTABLE + BEGIN + IDS_BROWSE "Browse" + END + + +//Insert Object stringtable. +STRINGTABLE + 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, "application which created it." + IDS_IORESULTFROMFILEICON2, "application 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 an icon into your document which represents the file. The icon will be linked to " + IDS_IORESULTLINKFILEICON2, "the file so that changes to the file will be reflected in your document." + END + +//Change Icon stringtable +STRINGTABLE + 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." + END + +// Convert stringtable. +STRINGTABLE + BEGIN + IDS_CVRESULTCONVERTLINK, "A linked object must be converted at the source." + IDS_CVRESULTCONVERTTO, "Permanently changes the selected %s object to a %s object." + IDS_CVRESULTNOCHANGE, "The selected %s object will not be converted." + IDS_CVRESULTDISPLAYASICON, " It will be displayed as an icon." + IDS_CVRESULTACTIVATEAS, "Every %s object will be activated as a %s object" + IDS_CVRESULTACTIVATEDIFF, ", but it will not be converted." + END + +//Paste Special stringtable +STRINGTABLE + 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. Paste Link creates a link to the source file so that changes to the source file will be reflected in your document." + IDS_PSPASTELINKOBJECT, "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." + IDS_PSPASTELINKOBJECTASICON, "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." + IDS_PSNONOLE, "Inserts the contents of the Clipboard into your document." + IDS_PSUNKNOWNTYPE, "Unknown Type" + IDS_PSUNKNOWNSRC, "Unknown Source" + IDS_PSUNKNOWNAPP, "the application which created it" + END + +// Busy/Blocked dialog stringtable +STRINGTABLE + BEGIN + IDS_BZRESULTTEXTBUSY "This action cannot be completed because the %s application (%s) is busy. Choose ""Switch To"" to activate %s and correct the problem." + IDS_BZRESULTTEXTNOTRESPONDING "This action cannot be completed because the %s application (%s) is not responding. Choose ""Switch To"" to activate %s and correct the problem." + END + +// OLESTD stringtable +STRINGTABLE + BEGIN + IDS_OLESTDNOCREATEFILE, "Could not create file!" + IDS_OLESTDNOOPENFILE, "Could not open file!" + IDS_OLESTDDISKFULL, "Disk full--unable to complete save operation" + END + +// OLE2UI stringtable +STRINGTABLE + BEGIN + IDS_OLE2UIEDITNOOBJCMD, "&Object" + IDS_OLE2UIEDITLINKCMD_1VERB, "0%s Linked %s &Object" + IDS_OLE2UIEDITOBJECTCMD_1VERB, "0%s %s &Object" + IDS_OLE2UIEDITLINKCMD_NVERB, "Linked %s &Object" + IDS_OLE2UIEDITOBJECTCMD_NVERB, "%s &Object" + IDS_OLE2UIUNKNOWN, "Unknown" + IDS_OLE2UILINK, "Link" + IDS_OLE2UIOBJECT, "Object" + IDS_OLE2UIEDIT, "&Edit" + IDS_OLE2UICONVERT, "&Convert..." + IDS_DEFICONLABEL, "Document" + IDS_OLE2UIPASTELINKEDTYPE, "Linked %s" + END + +// LINKS stringtable +STRINGTABLE + 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_CHANGEADDITIONALLINKS "The selected link has been changed.\nThis document contains additional links to\n%s.\n\nChange additional links?" + 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_CLOSE "Close" + END diff --git a/private/oleutest/letest/ole2ui/suminfo.cpp b/private/oleutest/letest/ole2ui/suminfo.cpp new file mode 100644 index 000000000..528fe2540 --- /dev/null +++ b/private/oleutest/letest/ole2ui/suminfo.cpp @@ -0,0 +1,1371 @@ +/************************************************************************* +** +** OLE 2.0 Property Set Utilities +** +** suminfo.cpp +** +** This file contains functions that are useful for the manipulation +** of OLE 2.0 Property Sets particularly to manage the Summary Info +** property set. +** +** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved +** +*************************************************************************/ + +// Note: this file is designed to be stand-alone; it includes a +// carefully chosen, minimal set of headers. +// +// For conditional compilation we use the ole2 conventions, +// _MAC = mac +// WIN32 = Win32 (NT really) +// <nothing> = defaults to Win16 + +// REVIEW: the following needs to modified to handle _MAC +#define STRICT +#ifndef INC_OLE2 + #define INC_OLE2 +#endif + +#include <windows.h> +#include <string.h> +#include <ole2.h> +#include "ole2ui.h" + +OLEDBGDATA + +/* A LPSUMINFO variable is a pointer to an instance of an abstract data +** type. There can be an arbitrary number of SummaryInfo streams open +** simultaneously (subject to available memory); each must have its +** own LPSUMINFO instance. Each LPSUMINFO instance must +** be initialized prior to use by calling Init and freed after its +** last use by calling Free. The param argument to Init is reserved +** for future expansion and should be zero initially. Once a LPSUMINFO +** instance is allocated (by Init), the user can call the Set +** procedures to initialize fields. A copy of the arguments is made +** in every case except SetThumbnail where control of the storage +** occupied by the METAFILEPICT is merely transferred. When the +** Free routine is called, all storage will be deallocated including +** that of the thumbnail. The arguments to SetThumbNail and the +** return values from GetThumbNail correspond to the OLE2.0 spec. +** Note that on input, the thumbnail is read on demand but all the +** other properties are pre-loaded. The thumbnail is manipulated as +** a windows handle to a METAFILEPICT structure, which in turn +** contains a handle to the METAFILE. The transferClip argument on +** GetThumbNail, when set to true, transfers responsibility for +** storage management of the thumbnail to the caller; that is, after +** Free has been called, the handle is still valid. Clear can be +** used to free storage for all the properties but then you must +** call Read to load them again. All the code is based on FAR +** pointers. +** CoInitialize MUST be called PRIOR to calling OleStdInitSummaryInfo. +** Memory is allocated using the currently active IMalloc* +** allocator (as is returned by call CoGetMalloc(MEMCTX_TASK) ). +** +** Common scenarios: +** Read SummaryInfo +** ---------------- +** OleStdInitSummaryInfo() +** OleStdReadSummaryInfo() +** . . . . . +** call different Get routines +** . . . . . +** OleStdFreeSummaryInfo() +** +** Create SummaryInfo +** ------------------ +** OleStdInitSummaryInfo() +** call different Set routines +** OleStdWriteSummaryInfo() +** OleStdFreeSummaryInfo() +** +** Update SummaryInfo +** ------------------ +** OleStdInitSummaryInfo() +** OleStdReadSummaryInfo() +** OleStdGetThumbNailProperty(necessary only if no SetThumb) +** call different Set routines +** OleStdWriteSummaryInfo() +** OleStdFreeSummaryInfo() +*/ + +#ifdef WIN32 +#define CHAR TCHAR +#else +#define CHAR unsigned char +#endif +#define fTrue 1 +#define fFalse 0 +#define BYTE unsigned char +#define WORD unsigned short +#define DWORD unsigned long +#define LPVOID void FAR * +#define uchar unsigned char +#define ulong unsigned long +#define BOOL unsigned char +#define BF unsigned int + +#include "suminfo.h" +#include "wn_dos.h" + +#if defined( _DEBUG ) + #ifndef NOASSERT + // following is from compobj.dll (ole2) + #ifdef UNICODE + #define ASSERT(x) (!(x) ? FnAssert(TEXT(#x), NULL, \ + TEXT(__FILE__), __LINE__) : 0) + #else + #define ASSERT(x) (!(x) ? \ + { \ + WCHAR wsz[255]; \ + wcscpy(wsz, (#x)); \ + FnAssert(wsz, NULL, TEXT(__FILE__), __LINE__) \ + } \ + : 0) + #endif + #else + #define ASSERT(x) + #endif +#else +#define ASSERT(x) +#endif + + +typedef struct _RSUMINFO + { + WORD byteOrder; + WORD formatVersion; + WORD getOSVersion; + WORD osVersion; + CLSID classId; //from compobj.h + DWORD cSections; + PROPSETLIST rgPropSet[1/*cSections*/]; //one section in standard summary info + STANDARDSECINMEM section; + ULONG fileOffset; //offset for thumbnail to support demand read + } RSUMINFO; + +typedef RSUMINFO FAR * LPRSI; + + typedef union _foo{ + ULARGE_INTEGER uli; + struct { + DWORD dw; + DWORD dwh; + }; + struct { + WORD w0; + WORD w1; + WORD w2; + WORD w3; + }; + } Foo; + + + +/* MemAlloc +** --------- +** allocate memory using the currently active IMalloc* allocator +*/ +static LPVOID MemAlloc(ULONG ulSize) +{ + LPVOID pout; + LPMALLOC pmalloc; + + if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR) { + OleDbgAssert(pmalloc); + return NULL; + } + + pout = (LPVOID)pmalloc->Alloc(ulSize); + + if (pmalloc != NULL) { + ULONG refs = pmalloc->Release(); + } + + return pout; +} + + +/* MemFree +** ------- +** free memory using the currently active IMalloc* allocator +*/ +static void MemFree(LPVOID pmem) +{ + LPMALLOC pmalloc; + + if (pmem == NULL) + return; + + if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR) { + OleDbgAssert(pmalloc); + return; + } + + pmalloc->Free(pmem); + + if (pmalloc != NULL) { + ULONG refs = pmalloc->Release(); + } +} + +// Replace the first argument with the product of itself and the multiplier +static void ulargeMultiply(ULARGE_INTEGER FAR *ul, USHORT m) +{ + Foo out, in; + in.uli = *ul; + out.dw = (ULONG)m * in.w0; in.w0 = out.w0; + out.dw = (ULONG)m * in.w1 + out.w1; in.w1 = out.w0; + out.dw = (ULONG)m * in.w2 + out.w1; in.w2 = out.w0; + out.dw = (ULONG)m * in.w3 + out.w1; in.w3 = out.w0; + *ul = in.uli; +} + +// Replace the first argument with the product of itself and the multiplier +static void ulargeDivide(ULARGE_INTEGER FAR *ul, USHORT m) +{ + Foo out, in; + DWORD i; + in.uli = *ul; + out.dwh = in.dwh/(ULONG)m; + i = in.dwh%(ULONG)m; + in.w2 = in.w1; + in.w3 = (WORD)i; + out.w1 = (WORD)(in.dwh/(ULONG)m); + in.w1 = (WORD)(in.dwh%(ULONG)m); + out.w0 = (WORD)(in.dw/(ULONG)m); + *ul = out.uli; +} + + +static void setStandard(LPRSI lprsi) +{ + int i; + lprsi->cSections = 1; + SetSumInfFMTID(&lprsi->rgPropSet[0].formatID); + _fmemcpy(&lprsi->classId, &lprsi->rgPropSet[0].formatID, sizeof(FMTID)); + lprsi->rgPropSet[0].byteOffset = cbNewSummaryInfo(1); + for (i=0; i<cPID_STANDARD; i++) + lprsi->section.rgPropId[i].propertyID = PID_TITLE+i; + lprsi->section.cProperties = cPID_STANDARD; //always; do null test to check validity +} + +extern "C" { + +/************************************************************************* +** +** OleStdInitSummaryInfo +** +** Purpose: +** Initialize a Summary Info structure. +** +** Parameters: +** int reserved - reserverd for future use. must be 0. +** +** Return Value: +** LPSUMINFO +** +** Comments: +** CoInitialize MUST be called PRIOR to calling OleStdInitSummaryInfo. +** Memory is allocated using the currently active IMalloc* +** allocator (as is returned by call CoGetMalloc(MEMCTX_TASK) ). +** Each LPSUMINFO instance must be initialized prior to use by +** calling OleStdInitSummaryInfo. Once a LPSUMINFO instance is allocated +** (by OleStdInitSummaryInfo), the user can call the Set procedures to +** initialize fields. +*************************************************************************/ + +STDAPI_(LPSUMINFO) OleStdInitSummaryInfo(int reserved) +{ + LPRSI lprsi; + + if ((lprsi = (LPRSI)MemAlloc(sizeof(RSUMINFO))) != NULL) + { + ClearSumInf(lprsi, sizeof(RSUMINFO)); + } else return NULL; + + setStandard(lprsi); + return (LPSUMINFO)lprsi; +} + + +/************************************************************************* +** +** OleStdFreeSummaryInfo +** +** Purpose: +** Free a Summary Info structure. +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** +** Return Value: +** void +** +** Comments: +** Memory is freed using the currently active IMalloc* +** allocator (as is returned by call CoGetMalloc(MEMCTX_TASK) ). +** Every LPSUMINFO struct must be freed after its last use. +** When the OleStdFreeSummaryInfo routine is called, all storage will be +** deallocated including that of the thumbnail (unless ownership of +** the thumbnail has been transfered to the caller -- see +** description of transferClip in GetThumbnail API). +** +*************************************************************************/ + +STDAPI_(void) OleStdFreeSummaryInfo(LPSUMINFO FAR *lplp) +{ + if (lplp==NULL||*lplp==NULL) return; + OleStdClearSummaryInfo(*lplp); + MemFree(*lplp); + *lplp = NULL; +} + + +/************************************************************************* +** +** OleStdClearSummaryInfo +** +** Purpose: +** Free storage (memory) for all the properties of the LPSUMINFO. +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** +** Return Value: +** void +** +** Comments: +** After calling OleStdClearSummaryInfo you must call OleStdReadSummaryInfo to +** load them again. +** +*************************************************************************/ + +STDAPI_(void) OleStdClearSummaryInfo(LPSUMINFO lp) +{ + OleStdSetStringProperty(lp, PID_TITLE, NULL); + OleStdSetStringProperty(lp, PID_SUBJECT, NULL); + OleStdSetStringProperty(lp, PID_AUTHOR, NULL); + OleStdSetStringProperty(lp, PID_KEYWORDS, NULL); + OleStdSetStringProperty(lp, PID_COMMENTS, NULL); + OleStdSetStringProperty(lp, PID_TEMPLATE, NULL); + OleStdSetStringProperty(lp, PID_REVNUMBER, NULL); + OleStdSetStringProperty(lp, PID_APPNAME, NULL); + OleStdSetThumbNailProperty(NULL, lp, VT_CF_EMPTY, 0, NULL, NULL, 0); + ClearSumInf((LPRSI)lp, sizeof(RSUMINFO)); +} + + +/************************************************************************* +** +** OleStdReadSummaryInfo +** +** Purpose: +** Read all Summary Info properties into memory (except thumbnail +** which is demand loaded). +** +** Parameters: +** LPSTREAM lps - open SummaryInfo IStream* +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** +** Return Value: +** int - 1 for success +** - 0 if error occurs +** Comments: +** +*************************************************************************/ + +STDAPI_(int) OleStdReadSummaryInfo(LPSTREAM lpStream, LPSUMINFO lp) +{ + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + LPRSI lpSumInfo = (LPRSI)lp; + SCODE sc; + ULONG cbRead,i,sectionOffset; + LARGE_INTEGER a; + ULARGE_INTEGER b; + int j,k,l; + union { + RSUMINFO rsi; + STDZ stdz; + }; + OleStdClearSummaryInfo(lp); + LISet32(a, 0); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) goto fail; + sectionOffset = cbNewSummaryInfo(1); + sc = GetScode(lpStream->Read(&rsi, sectionOffset, &cbRead)); + if (FAILED(sc)||cbRead<sectionOffset) goto fail; + if (!FIntelOrder(&rsi)||rsi.formatVersion!=0) goto fail; + j = (int)rsi.cSections; + while (j-->0) { + if (FEqSumInfFMTID(&rsi.rgPropSet[0].formatID)) { + sectionOffset = rsi.rgPropSet[0].byteOffset; + break; + } else { + sc = GetScode(lpStream->Read(&rsi.rgPropSet[0].formatID, sizeof(PROPSETLIST), &cbRead)); + if (FAILED(sc)||cbRead!=sizeof(PROPSETLIST)) goto fail; + } + if (j<=0) goto fail; + } + + LISet32(a, sectionOffset); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) goto fail; + sc = GetScode(lpStream->Read(&rsi.section, cbNewSection(1), &cbRead)); + if (FAILED(sc)||cbRead!=cbNewSection(1)) goto fail; + i = rsi.section.cBytes+sectionOffset; + j = (int)rsi.section.cProperties; + if (j>cPID_STANDARD) goto fail; + k = 0; + while (j-->0) { + k++; + switch (l=(int)rsi.section.rgPropId[0].propertyID) { + case PID_PAGECOUNT: + case PID_WORDCOUNT: + case PID_CHARCOUNT: + case PID_SECURITY: + if (l==PID_SECURITY) l=3; else l-=PID_PAGECOUNT; + cbRead = sectionOffset+rsi.section.rgPropId[0].byteOffset; + if (cbRead>=i) goto fail; + LISet32(a, cbRead); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) goto fail; + sc = GetScode(lpStream->Read(&lpSSIM->rgInts[l], sizeof(INTS), &cbRead)); + if (FAILED(sc)||cbRead!=sizeof(INTS)) goto fail; + if (lpSSIM->rgInts[l].vtType==VT_EMPTY) break; + if (lpSSIM->rgInts[l].vtType!=VT_I4) goto fail; + break; + case PID_EDITTIME: + case PID_LASTPRINTED: + case PID_CREATE_DTM_RO: + case PID_LASTSAVE_DTM: + l-=PID_EDITTIME; + cbRead = sectionOffset+rsi.section.rgPropId[0].byteOffset; + if (cbRead>=i) goto fail; + LISet32(a, cbRead); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) goto fail; + sc = GetScode(lpStream->Read(&lpSSIM->rgTime[l], sizeof(TIME), &cbRead)); + if (FAILED(sc)||cbRead!=sizeof(TIME)) goto fail; + if (lpSSIM->rgTime[l].vtType==VT_EMPTY) break; + if (lpSSIM->rgTime[l].vtType!=VT_FILETIME) goto fail; + break; + case PID_TITLE: + case PID_SUBJECT: + case PID_AUTHOR: + case PID_KEYWORDS: + case PID_COMMENTS: + case PID_TEMPLATE: + case PID_LASTAUTHOR: + case PID_REVNUMBER: + case PID_APPNAME: + cbRead = sectionOffset+rsi.section.rgPropId[0].byteOffset; + if (cbRead>=i) goto fail; + LISet32(a, cbRead); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) goto fail; + sc = GetScode(lpStream->Read(&stdz, sizeof(STDZ), &cbRead)); + if (FAILED(sc)||cbRead<sizeof(DWORD)*2) goto fail; + if (stdz.vtType==VT_EMPTY||stdz.vtByteCount<=1) break; + if (stdz.vtType!=VT_LPSTR||stdz.vtByteCount>WORDMAX) goto fail; + stdz.rgchars[(int)stdz.vtByteCount-1] = TEXT('\0'); + OleStdSetStringProperty(lp, (DWORD)l, (LPTSTR)&stdz.rgchars[0]); + break; + case PID_THUMBNAIL: + cbRead = sectionOffset+rsi.section.rgPropId[0].byteOffset; + if (cbRead>=i) goto fail; + LISet32(a, cbRead); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) goto fail; + lpSumInfo->fileOffset = cbRead+sizeof(DWORD)*3; + sc = GetScode(lpStream->Read(&lpSSIM->thumb, sizeof(DWORD)*4, &cbRead)); + if (FAILED(sc)||cbRead!=sizeof(DWORD)*4) { + lpSSIM->thumb.vtType = VT_EMPTY; + goto fail; + } + if (lpSSIM->thumb.vtType == VT_EMPTY) { + lpSSIM->thumb.cBytes = 0; + break; + } + if (lpSSIM->thumb.vtType != VT_CF) { + lpSSIM->thumb.vtType = VT_EMPTY; + goto fail; + } + lpSSIM->thumb.cBytes -= sizeof(DWORD); //for selector + if (lpSSIM->thumb.selector==VT_CF_WIN||lpSSIM->thumb.selector==VT_CF_MAC) { + lpSumInfo->fileOffset += sizeof(DWORD); + lpSSIM->thumb.cBytes -= sizeof(DWORD); //for format val + } + break; + default: ; + } + if (j<=0) + { + // We should fail if the document is password-protected. + if(OleStdGetSecurityProperty(lp)==fSecurityPassworded) + goto fail; + return 1; + } + LISet32(a, sectionOffset+sizeof(DWORD)*2+k*sizeof(PROPIDLIST)); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) goto fail; + sc = GetScode(lpStream->Read(&rsi.section.rgPropId[0], sizeof(PROPIDLIST), &cbRead)); + if (FAILED(sc)||cbRead!=sizeof(PROPIDLIST)) goto fail; + } + +fail: + OleStdClearSummaryInfo(lpSumInfo); + + return 0; +} + + +/************************************************************************* +** +** OleStdWriteSummaryInfo +** +** Purpose: +** Write all Summary Info properties to a IStream* +** +** Parameters: +** LPSTREAM lps - open SummaryInfo IStream* +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** +** Return Value: +** int - 1 for success +** - 0 if error occurs +** Comments: +** +*************************************************************************/ + +STDAPI_(int) OleStdWriteSummaryInfo(LPSTREAM lpStream, LPSUMINFO lp) +{ + + + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + // REVIEW: localization issues for propert sets + // do we need to include a code page and dictionary? + + LPRSI lpSumInfo = (LPRSI)lp; + SCODE sc; + ULONG cbWritten; + ULONG cBytes, oBytes, k,l,m,n; + LARGE_INTEGER a; + ULARGE_INTEGER b; + CHAR FAR *lps; + LPMETAFILEPICT lpmfp; + int i,j,s; + + setStandard(lpSumInfo); + oBytes = cbNewSection(cPID_STANDARD); //offsets are relative to the section + cBytes = cbNewSection(cPID_STANDARD)+(sizeof(TIME)*MAXTIME)+(sizeof(INTS)*MAXINTS); + + lpSSIM->rgPropId[PID_EDITTIME-2].byteOffset = oBytes; + lpSSIM->rgPropId[PID_LASTPRINTED-2].byteOffset = oBytes+sizeof(TIME); + lpSSIM->rgPropId[PID_CREATE_DTM_RO-2].byteOffset = oBytes+sizeof(TIME)*2; + lpSSIM->rgPropId[PID_LASTSAVE_DTM-2].byteOffset = oBytes+sizeof(TIME)*3; + + lpSSIM->rgPropId[PID_PAGECOUNT-2].byteOffset = oBytes+(sizeof(TIME)*MAXTIME); + lpSSIM->rgPropId[PID_WORDCOUNT-2].byteOffset = oBytes+(sizeof(TIME)*MAXTIME+sizeof(INTS)); + lpSSIM->rgPropId[PID_CHARCOUNT-2].byteOffset = oBytes+(sizeof(TIME)*MAXTIME+sizeof(INTS)*2); + lpSSIM->rgPropId[PID_SECURITY-2].byteOffset = oBytes+(sizeof(TIME)*MAXTIME+sizeof(INTS)*3); + oBytes += sizeof(TIME)*MAXTIME + sizeof(INTS)*MAXINTS; + + lpSSIM->rgPropId[PID_THUMBNAIL-2].byteOffset = oBytes; + l = 0; + if (lpSSIM->thumb.vtType==VT_EMPTY) k = sizeof(DWORD); + else { + l = ((lpSSIM->thumb.cBytes+4-1)>>2)<<2; + if (lpSSIM->thumb.selector==VT_CF_BYTES) k = sizeof(DWORD)*3; + else if (lpSSIM->thumb.selector==VT_CF_FMTID) {k = sizeof(DWORD)*3; l += sizeof(FMTID); } + else if (lpSSIM->thumb.selector==VT_CF_NAME) {k = sizeof(DWORD)*3; l += (((*lpSSIM->thumb.lpstzName+1+3)>>2)<<2);} + else k = sizeof(DWORD)*4; + } + cBytes += k+l; + oBytes += k+l; + + for (i=0; i<MAXSTDZ; i++) { + j = 0; + if (lpSSIM->rglpsz[i]!=NULL) { + j = lpSSIM->rglpsz[i]->VTCB+1/*null*/; + lpSSIM->rglpsz[i]->vtByteCount = j; + j = (((j+4-1)>>2)<<2)+sizeof(DWORD); + cBytes += j; + } + if (i!=MAXSTDZ-1) lpSSIM->rgPropId[i].byteOffset = oBytes; + else lpSSIM->rgPropId[PID_APPNAME-2].byteOffset = oBytes; + oBytes += j+sizeof(DWORD); + cBytes += sizeof(DWORD); //type + } + lpSSIM->cBytes = cBytes; + + + LISet32(a, 0); + sc = GetScode(lpStream->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) return 0; + sc = GetScode(lpStream->Write(lpSumInfo, cbNewSummaryInfo(1), &cbWritten)); + if (FAILED(sc)||cbWritten!=cbNewSummaryInfo(1)) return 0; + sc = GetScode(lpStream->Write(lpSSIM, cbNewSection(cPID_STANDARD)+sizeof(TIME)*MAXTIME+sizeof(INTS)*MAXINTS, &cbWritten)); + if (FAILED(sc)||cbWritten!=cbNewSection(cPID_STANDARD)+sizeof(TIME)*MAXTIME+sizeof(INTS)*MAXINTS) return 0; + + m = lpSSIM->thumb.cBytes; + if (lpSSIM->thumb.lpstzName!=NULL) s = *lpSSIM->thumb.lpstzName; + else s = 0; + if (m!=0) { + lpSSIM->thumb.cBytes = (k-sizeof(DWORD)*2)+ + (((lpSSIM->thumb.cBytes+4-1)>>2)<<2)+(((s+4-1)>>2)<<2); + n = lpSSIM->thumb.selector; + lps = lpSSIM->thumb.lpByte; + OleDbgAssert(lps!=NULL); //maybe a GetThumbNail here + OleDbgAssert(n!=VT_CF_NAME); + if (n==VT_CF_WIN) { //bytes are in global memory + lpmfp = (LPMETAFILEPICT)GlobalLock((HANDLE)(DWORD)lps); + if (lpmfp==NULL) goto fail; + lps = (CHAR FAR*)GlobalLock(lpmfp->hMF); + } + if (n==VT_CF_NAME) lpSSIM->thumb.selector = *lpSSIM->thumb.lpstzName+1/*null*/; + } + sc = GetScode(lpStream->Write(&lpSSIM->thumb, k, &cbWritten)); + if (FAILED(sc)||cbWritten!=k) goto fail; + if (s!=0) { + k = ((s+1+4-1)>>2)<<2; + sc = GetScode(lpStream->Write(lpSSIM->thumb.lpstzName+1, k, &cbWritten)); + if (FAILED(sc)||cbWritten!=k) goto fail; + } + if (m!=0) { + k = ((m+3)>>2)<<2; + if (n==VT_CF_WIN||VT_CF_NAME) { //bytes are in global memory + sc = GetScode(lpStream->Write(lpmfp, sizeof(METAFILEPICT), &cbWritten)); + k -= sizeof(METAFILEPICT); + } + sc = GetScode(lpStream->Write(lps, k, &cbWritten)); + if (FAILED(sc)||cbWritten!=k) goto fail; + if (n==VT_CF_WIN||VT_CF_NAME) { //bytes are in global memory + GlobalUnlock(lpmfp->hMF); + GlobalUnlock((HANDLE)(DWORD)lpSSIM->thumb.lpByte); + } + } + lpSSIM->thumb.cBytes = m; //restore in mem value + lpSSIM->thumb.selector = n; + + k = VT_EMPTY; + for (i=0; i<MAXSTDZ; i++) { + if (lpSSIM->rglpsz[i]!=NULL) { + l = lpSSIM->rglpsz[i]->vtByteCount; + j = ((((int)l+4-1)/4)*4)+sizeof(DWORD)*2; + sc = GetScode(lpStream->Write(lpSSIM->rglpsz[i], j, &cbWritten)); + if (FAILED(sc)||cbWritten!=(ULONG)j) return 0; + lpSSIM->rglpsz[i]->vtByteCount = 0; //restore stz count convention + lpSSIM->rglpsz[i]->VTCB = (int)l; + } else { + sc = GetScode(lpStream->Write(&k, sizeof(DWORD), &cbWritten)); + if (FAILED(sc)||cbWritten!=sizeof(DWORD)) return 0; + } + } + return 1; +fail: + lpSSIM->thumb.cBytes = m; //restore in mem value + lpSSIM->thumb.selector = n; + if (m!=0&&(n==VT_CF_WIN||VT_CF_NAME)) { //bytes are in global memory + GlobalUnlock((HANDLE)(DWORD)lps); + } + + return 0; +} + + +/************************************************************************* +** +** OleStdGetSecurityProperty +** +** Purpose: +** Retrieve the Security Property +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** +** Return Value: +** DWORD - security level +** AllSecurityFlagsEqNone 0 - no security +** fSecurityPassworded 1 - password required +** fSecurityRORecommended 2 - read-only is recommended +** fSecurityRO 4 - read-only is required +** fSecurityLockedForAnnotations 8 - locked for annotations +** +** Comments: +** by noting the (suggested; that is, application-enforced) security +** level on the document, an application other than the originator +** of the document can adjust its user interface to the properties +** appropriately. An application should not display any of the +** information about a password protected document, and should not +** allow modifications to enforced read-only or locked for +** annotations documents. It should warn the user about read-only +** recommended if the user attempts to modify properties. +** +*************************************************************************/ + +STDAPI_(DWORD) OleStdGetSecurityProperty(LPSUMINFO lp) +{ +STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + if (lpSSIM->rgInts[3].vtType == VT_I4) return lpSSIM->rgInts[3].value; + + return 0; +} + + +/************************************************************************* +** +** OleStdSetSecurityProperty +** +** Purpose: +** Set the Security Property +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD security - security level +** AllSecurityFlagsEqNone 0 - no security +** fSecurityPassworded 1 - password required +** fSecurityRORecommended 2 - read-only is recommended +** fSecurityRO 4 - read-only is required +** fSecurityLockedForAnnotations 8 - locked for annotations +** +** Return Value: +** int - 1 for success +** - 0 if error occurs +** (there are no errors) +** +** Comments: +** by noting the (suggested; that is, application-enforced) security +** level on the document, an application other than the originator +** of the document can adjust its user interface to the properties +** appropriately. An application should not display any of the +** information about a password protected document, and should not +** allow modifications to enforced read-only or locked for +** annotations documents. It should warn the user about read-only +** recommended if the user attempts to modify properties. +** +*************************************************************************/ + +STDAPI_(int) OleStdSetSecurityProperty(LPSUMINFO lp, DWORD security) +{ + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + + // REVIEW: check valid transitions; how do we know APP called us? + + if (security==0) { + lpSSIM->rgInts[3].vtType = VT_EMPTY; + return 1; + } + lpSSIM->rgInts[3].vtType = VT_I4; + lpSSIM->rgInts[3].value = security; + return 1; +} + + +/************************************************************************* +** +** OleStdGetStringProperty +** +** Purpose: +** Retrieve a String Propety. +** (returns zero terminated string -- C string) +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD pid - ID of String Property +** +** Return Value: +** LPTSTR - value of String Property +** (zero terminated string--C string) +** +** Comments: +** String should NOT be freed by caller. Memory for string will be +** freed when OleStdFreeSummaryInfo is called. +*************************************************************************/ + +STDAPI_(LPTSTR) OleStdGetStringProperty(LPSUMINFO lp, DWORD pid) +{ + LPTSTR l = OleStdGetStringZProperty(lp,pid); + if (l==NULL) return NULL; else return l+1; +} + + +/************************************************************************* +** +** OleStdSetStringProperty +** +** Purpose: +** Set a String Propety +** (takes zero terminated string -- C string) +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD pid - ID of String Property +** LPTSTR lpsz - new value for String Property. +** zero terminated string -- C string. +** May be NULL, in which case the +** propery is cleared. +** +** Return Value: +** int - 1 if successful +** - 0 invalid property id +** +** Comments: +** The input string is copied. +** +*************************************************************************/ + +STDAPI_(int) OleStdSetStringProperty(LPSUMINFO lp, DWORD pid, LPTSTR lpsz) +{ + LPRSI lprsi=(LPRSI)lp; + STANDARDSECINMEM FAR* lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + int i; + if (pid==PID_APPNAME) { + pid = MAXSTDZ-1; + } else if (pid<PID_TITLE || pid>PID_REVNUMBER) return 0; else pid -= 2; + OleDbgAssert(lpSSIM); + if (lpSSIM->rglpsz[pid]) MemFree(lpSSIM->rglpsz[pid]); + if ((lpsz==NULL)||(*lpsz==0)) { + lpSSIM->rglpsz[pid] = NULL; + return (1); + } + i = _fstrlen(lpsz); + lpSSIM->rglpsz[pid] = (STDZ FAR*)MemAlloc((i+1/*null*/)*sizeof(TCHAR)+ + sizeof(DWORD)*2); + if (lpSSIM->rglpsz[pid]==NULL) return 0; + _fstrcpy((LPTSTR)&lpSSIM->rglpsz[pid]->rgchars, lpsz); + lpSSIM->rglpsz[pid]->vtType = VT_LPSTR; + lpSSIM->rglpsz[pid]->vtByteCount = 0; + lpSSIM->rglpsz[pid]->VTCB = i; + return (1); +} + + +/************************************************************************* +** +** OleStdGetStringZProperty +** +** Purpose: +** Retrieve a String Propety. +** (returns zero-terminated with leading byte count string) +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD pid - ID of Property +** +** Return Value: +** LPSTZR - value of String Property +** (zero-terminated with leading +** byte count) +** +** Comments: +** String should NOT be freed by caller. Memory for string will be +** freed when OleStdFreeSummaryInfo is called. +*************************************************************************/ + +STDAPI_(LPSTZR) OleStdGetStringZProperty(LPSUMINFO lp, DWORD pid) +{ + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + if (pid==PID_APPNAME) { + pid = MAXSTDZ-1; + } else if (pid<PID_TITLE || pid>PID_REVNUMBER) return NULL; else pid -= 2; + if (lpSSIM->rglpsz[pid]!=NULL) { + return (LPTSTR)&lpSSIM->rglpsz[pid]->VTCB; + } + return NULL; +} + + +/************************************************************************* +** +** OleStdGetDocProperty +** +** Purpose: +** Retrieve document properties (no. pages, no. words, no. characters) +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD FAR *nPage - (OUT) number of pages in document +** DWORD FAR *nWords - (OUT) number of words in document +** DWORD FAR *nChars - (OUT) number of charactrs in doc +** +** Return Value: +** void +** +** Comments: +** +*************************************************************************/ + +STDAPI_(void) OleStdGetDocProperty( + LPSUMINFO lp, + DWORD FAR* nPage, + DWORD FAR* nWords, + DWORD FAR* nChars +) +{ +STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + *nPage=0; *nWords=0; *nChars=0; + if (lpSSIM->rgInts[0].vtType == VT_I4) *nPage = lpSSIM->rgInts[0].value; + if (lpSSIM->rgInts[1].vtType == VT_I4) *nWords = lpSSIM->rgInts[1].value; + if (lpSSIM->rgInts[2].vtType == VT_I4) *nChars = lpSSIM->rgInts[2].value; +} + + +/************************************************************************* +** +** OleStdSetDocProperty +** +** Purpose: +** Set document properties (no. pages, no. words, no. characters) +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD nPage - number of pages in document +** DWORD nWords - number of words in document +** DWORD nChars - number of charactrs in doc +** +** Return Value: +** int - 1 for success +** - 0 if error occurs +** (there are no errors) +** +** Comments: +** +*************************************************************************/ + +STDAPI_(int) OleStdSetDocProperty( + LPSUMINFO lp, + DWORD nPage, + DWORD nWords, + DWORD nChars +) +{ +DWORD vttype=VT_I4; +STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + if ((nPage|nWords|nChars)==0) { + vttype = VT_EMPTY; + nPage=0; nWords=0; nChars=0; + } + lpSSIM->rgInts[0].vtType = vttype; + lpSSIM->rgInts[1].vtType = vttype; + lpSSIM->rgInts[2].vtType = vttype; + lpSSIM->rgInts[0].value = nPage; + lpSSIM->rgInts[1].value = nWords; + lpSSIM->rgInts[2].value = nChars; + return 1; +} + + +/************************************************************************* +** +** OleStdGetThumbNailProperty +** +** Purpose: +** Retrieve a Thumbnail Property +** +** Parameters: +** LPSTREAM lps +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD FAR* clipFormatNo - clipboard format for thumbnail +** (type of value depends on vtcf +** return value.) +** NOTE: ONLY VT_CF_WIN is +** implemented, so clipFormatNo +** will be CF_METAFILEPICT +** LPTSTR FAR* lpszName - format name if VT_CF_NAME is +** returned +** NOTE: NOT IMPLEMENTED +** THUMBNAIL FAR* clip - handle to thumbnail +** for VT_CF_WIN clip will be +** handle to MetafilePict +** NOTE: only VT_CF_WIN IMPLEMENTED +** DWORD FAR* byteCount - size of thumbnail stream +** for VT_CF_WIN case this should +** be combined size of both the +** Metafile as well as the +** MetafilePict structure. +** BOOL transferClip - transfer ownership of thumbnail +** to caller. (see comment) +** +** Return Value: +** int vtcfNo - OLE thumbnail selector value +** VT_CF_WIN - Windows thumbnail +** (interpret clipFormatNo as +** Windows clipboard format) +** VT_CF_FMTID - (NOT IMPLEMENTED) +** thumbnail format is specified +** by ID. use clipFormatNo. +** (but NOT a Windows format ID) +** +** VT_CF_NAME - (NOT IMPLEMENTED) +** thumbnail format is specified +** by name. use lpszName. +** VT_CF_EMPTY - blank thumbnail +** (clip will be NULL) +** VT_CF_OOM - Memory allocation failure +** +** Comments: +** NOTE: Currently there is only proper support for VT_CF_WIN. +** OleStdSetThumbNailProperty does implement VT_CF_FMTID and VT_CF_NAME, +** however, OleStdGetThumbNailProperty, OleStdReadSummaryInfo and +** OleStdWriteSummaryInfo only support VT_CF_WIN. +** +** Note that on input, the thumbnail is read on demand while all the +** other properties are pre-loaded. The thumbnail is manipulated as +** a windows handle to a METAFILEPICT structure, which in turn +** contains a handle to the METAFILE. The transferClip argument on +** GetThumbNail, when set to true, transfers responsibility for +** storage management of the thumbnail to the caller; that is, after +** OleStdFreeSummaryInfo has been called, the handle is still valid. +*************************************************************************/ + +STDAPI_(int) OleStdGetThumbNailProperty( + LPSTREAM lps, + LPSUMINFO lp, + DWORD FAR* clipFormatNo, + LPTSTR FAR* lpszName, + THUMBNAIL FAR* clip, + DWORD FAR* byteCount, + BOOL transferClip +) +{ + int i; + LPRSI lprsi=(LPRSI)lp; + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + ULONG cbRead, cbToRead; + LARGE_INTEGER a; + ULARGE_INTEGER b; + CHAR FAR *lpst; + LPMETAFILEPICT lpmfp; + HANDLE hst, hmfp; + SCODE sc; + *byteCount = 0; + if (lpSSIM->thumb.cBytes==0) return VT_CF_EMPTY; + if (lpSSIM->thumb.lpByte==NULL) { + LISet32(a, lprsi->fileOffset); + sc = GetScode(lps->Seek(a, STREAM_SEEK_SET, &b)); + if (FAILED(sc)) return VT_CF_EMPTY; + i = (int) lpSSIM->thumb.selector; + if (i>0||i==VT_CF_FMTID) { + if (i>255) return VT_CF_EMPTY; + else if (i==VT_CF_FMTID) i = sizeof(FMTID); + else lpSSIM->thumb.selector = VT_CF_NAME; + cbToRead = ((i+3)>>2)<<2; + lpSSIM->thumb.lpstzName=(CHAR FAR*)MemAlloc(i+1/*n*/+1); + if (lpSSIM->thumb.lpstzName==NULL) return VT_CF_OOM; + sc = GetScode(lps->Read(lpSSIM->thumb.lpstzName+1, cbToRead, &cbRead)); + if (FAILED(sc)||cbRead!=cbToRead) return VT_CF_EMPTY; + *lpSSIM->thumb.lpstzName = i; + *(lpSSIM->thumb.lpstzName+i) = 0; + lpSSIM->thumb.cBytes -= cbToRead+sizeof(DWORD); + } + i = (int) lpSSIM->thumb.selector; + cbToRead = lpSSIM->thumb.cBytes; + if (cbToRead>65535) return VT_CF_OOM; + OleDbgAssert(i!=VT_CF_NAME); + if (i==VT_CF_WIN) { + cbToRead -= sizeof(METAFILEPICT); + hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT)); + if (hmfp==NULL) return VT_CF_OOM; + hst = GlobalAlloc(GMEM_MOVEABLE, cbToRead); + if (hst==NULL) { + GlobalFree(hmfp); + return VT_CF_OOM; + } + lpmfp = (LPMETAFILEPICT)GlobalLock(hmfp); + sc = GetScode(lps->Read(lpmfp, sizeof(METAFILEPICT), &cbRead)); + if (FAILED(sc)||cbRead!=sizeof(METAFILEPICT)) { + GlobalUnlock(hmfp); + GlobalFree(hmfp); + GlobalFree(hst); + return VT_CF_EMPTY; + } + lpst = (CHAR FAR*)GlobalLock(hst); + lpmfp->hMF = (HMETAFILE)hst; + lpSSIM->thumb.lpByte = (CHAR FAR*)hmfp; + } else { + lpst =(CHAR FAR*)MemAlloc((int)cbToRead); + if (lpst==NULL) return VT_CF_OOM; + lpSSIM->thumb.lpByte = lpst; + } + sc = GetScode(lps->Read(lpst, cbToRead, &cbRead)); + if (i==VT_CF_WIN) { + GlobalUnlock(hst); + GlobalUnlock(hmfp); + } + if (FAILED(sc)||cbRead!=cbToRead) { + if (i==VT_CF_WIN) { + GlobalFree(hst); + GlobalFree(hmfp); + } else MemFree(lpst); + lpSSIM->thumb.lpByte = NULL; + if ((i==VT_CF_NAME||i==VT_CF_FMTID)&&(lpSSIM->thumb.lpstzName!=NULL)) + MemFree(lpSSIM->thumb.lpstzName); + return VT_CF_EMPTY; + } + } + *clipFormatNo = lpSSIM->thumb.clipFormat; + *byteCount = lpSSIM->thumb.cBytes; + if(lpszName!=NULL) + *lpszName = (TCHAR FAR*)lpSSIM->thumb.lpstzName+1; + *clip = (TCHAR FAR*)lpSSIM->thumb.lpByte; + if (transferClip) lpSSIM->thumb.lpByte=NULL; + return (int)lpSSIM->thumb.selector; +} + + +/************************************************************************* +** +** OleStdSetThumbNailProperty +** +** Purpose: +** Set a Thumbnail Property +** +** Parameters: +** LPSTREAM lps - open SummaryInfo IStream* +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** int vtcfNo - OLE thumbnail selector value +** VT_CF_WIN - Windows thumbnail +** (interpret clipFormatNo as +** Windows clipboard format) +** VT_CF_FMTID - thumbnail format is specified +** by ID. use clipFormatNo. +** (but NOT a Windows format ID) +** +** VT_CF_NAME - thumbnail format is specified +** by name. use lpszName. +** VT_CF_EMPTY - blank thumbnail +** (clip will be NULL) +** +** DWORD FAR* clipFormatNo - clipboard format for thumbnail +** used if vtcfNo is VT_CF_WIN or +** VT_CF_FMTID. interpretation of +** value depends on vtcfNo specified. +** (normally vtcfNo==VT_CF_WIN and +** clipFormatNo==CF_METAFILEPICT) +** LPSTR FAR* lpszName - format name if vtcfNo is VT_CF_NAME +** THUMBNAIL clip - handle to thumbnail +** for VT_CF_WIN clip will be +** handle to MetafilePict +** DWORD FAR* byteCount - size of thumbnail stream +** for VT_CF_WIN case this should +** be combined size of both the +** Metafile as well as the +** MetafilePict structure. +** +** Return Value: +** int - 1 for success +** - 0 if error occurs +** +** Comments: +** NOTE: Currently there is only proper support for VT_CF_WIN. +** OleStdSetThumbNailProperty does implement VT_CF_FMTID and VT_CF_NAME, +** however, OleStdGetThumbNailProperty, OleStdReadSummaryInfo and +** OleStdWriteSummaryInfo only support VT_CF_WIN. +** +** This function copies lpszName but saves the "clip" handle passed. +** +** NOTE: overwriting or emptying frees space for clip and name. +** The thumbnail is manipulated as a windows handle to a +** METAFILEPICT structure, which in turn contains a handle to the +** METAFILE. +*************************************************************************/ + +STDAPI_(int) OleStdSetThumbNailProperty( + LPSTREAM lps, + LPSUMINFO lp, + int vtcfNo, + DWORD clipFormatNo, + LPTSTR lpszName, + THUMBNAIL clip, + DWORD byteCount +) +{ + int i; + LPRSI lprsi=(LPRSI)lp; + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + LPMETAFILEPICT lpmfp; + if (lpSSIM==NULL||vtcfNo>0||vtcfNo<VT_CF_EMPTY||(vtcfNo==VT_CF_NAME&&(lpszName==NULL||*lpszName==0))) { + return 0; + } + if (vtcfNo!=VT_CF_EMPTY&&(clip==0||byteCount==0)) return 0; + i = (int) lpSSIM->thumb.vtType; + if (i!=VT_EMPTY) { + i = (int) lpSSIM->thumb.selector; + OleDbgAssert(i!=VT_CF_NAME); + if (i==VT_CF_WIN) { + if (lpSSIM->thumb.lpByte!=NULL) { + lpmfp = (LPMETAFILEPICT)GlobalLock((HANDLE)(DWORD)lpSSIM->thumb.lpByte); + GlobalFree(lpmfp->hMF); + GlobalUnlock((HANDLE)(DWORD)lpSSIM->thumb.lpByte); + GlobalFree((HANDLE)(DWORD)lpSSIM->thumb.lpByte); + } + } else { + MemFree(lpSSIM->thumb.lpByte); + } + if ((i==VT_CF_NAME||i==VT_CF_FMTID)&&(lpSSIM->thumb.lpstzName!=NULL)) + MemFree(lpSSIM->thumb.lpstzName); + lpSSIM->thumb.lpstzName = NULL; + lpSSIM->thumb.lpByte = NULL; + } + if (vtcfNo==VT_CF_EMPTY) { + lpSSIM->thumb.vtType = VT_EMPTY; + lpSSIM->thumb.cBytes = 0; + } else { + lpSSIM->thumb.vtType = VT_CF; + lpSSIM->thumb.selector = vtcfNo; + lpSSIM->thumb.cBytes = byteCount; + lpSSIM->thumb.clipFormat = clipFormatNo; + lpSSIM->thumb.lpByte = (CHAR FAR*)clip; //just save the hnadle + if (vtcfNo==VT_CF_NAME||vtcfNo==VT_CF_FMTID) { + i = _fstrlen(lpszName); + if (vtcfNo==VT_CF_FMTID) OleDbgAssert(i*sizeof(TCHAR)==sizeof(FMTID)); + lpSSIM->thumb.lpstzName = + (CHAR FAR*)MemAlloc((i+1/*n*/+1/*null*/)*sizeof(TCHAR)); + if (lpSSIM->thumb.lpstzName==NULL) { + lpSSIM->thumb.vtType = VT_EMPTY; + return 0; + } + _fstrcpy((TCHAR FAR*)lpSSIM->thumb.lpstzName+1, lpszName); + *lpSSIM->thumb.lpstzName = i; + } + } + return 1; +} + + +/************************************************************************* +** +** OleStdGetDateProperty +** +** Purpose: +** Retrieve Data Property +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD pid - ID of Property +** int FAR *yr - (OUT) year +** int FAR *mo - (OUT) month +** int FAR *dy - (OUT) day +** DWORD FAR *sc - (OUT) seconds +** +** Return Value: +** void +** +** Comments: +** +*************************************************************************/ + +STDAPI_(void) OleStdGetDateProperty( + LPSUMINFO lp, + DWORD pid, + int FAR* yr, + int FAR* mo, + int FAR* dy, + DWORD FAR* sc +) +{ + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + SFFS sffs; + pid -= PID_EDITTIME; + *yr = 0; *mo = 0; *dy = 0; *sc = 0; + if (pid<0||pid>=MAXTIME) return; + if (lpSSIM->rgTime[pid].vtType == VT_FILETIME) { + if (pid==0) { + //convert from 100ns to seconds + ulargeDivide((ULARGE_INTEGER FAR*)&lpSSIM->rgTime[0].time, 10000); + ulargeDivide((ULARGE_INTEGER FAR*)&lpSSIM->rgTime[0].time, 1000); + pid = lpSSIM->rgTime[0].time.dwLowDateTime; + *sc = pid%((DWORD)60*60*24); + pid /= (DWORD)60*60*24; + *dy = (int)(pid%(DWORD)30); + pid /= (DWORD)30; + *mo = (int)(pid%(DWORD)12); + *yr = (int)(pid/(DWORD)12); + } else { + if (CoFileTimeToDosDateTime(&lpSSIM->rgTime[pid].time, + &sffs.dateVariable, &sffs.timeVariable)) { + *yr = sffs.yr+1980; + *mo = sffs.mon; + *dy = sffs.dom; + *sc = (DWORD)sffs.hr*3600+sffs.mint*60+sffs.sec*2; + } + } + } + return; +} + + + +/************************************************************************* +** +** OleStdSetDateProperty +** +** Purpose: +** Set Data Property +** +** Parameters: +** LPSUMINFO FAR *lp - pointer to open Summary Info struct +** DWORD pid - ID of Property +** int yr - year +** int mo - month +** int dy - day +** DWORD sc - seconds +** +** Return Value: +** int - 1 for success +** - 0 if error occurs +** +** Comments: +** Use all zeros to clear. +** The following is an example of valid input: +** yr=1993 mo=1(Jan) dy=1(1st) hr=12(noon) mn=30 sc=23 +** for PID_EDITTIME property, the values are a zero-origin duration +** of time. +** +*************************************************************************/ + +STDAPI_(int) OleStdSetDateProperty( + LPSUMINFO lp, + DWORD pid, + int yr, + int mo, + int dy, + int hr, + int mn, + int sc +) +{ + STANDARDSECINMEM FAR *lpSSIM=(STANDARDSECINMEM FAR*)&((LPRSI)lp)->section; + SFFS sffs; + pid -= PID_EDITTIME; + if (pid<0||pid>=MAXTIME) return 0; + if ((yr|mo|dy|hr|mn|sc)==0) { //all must be zero + lpSSIM->rgTime[pid].vtType = VT_EMPTY; + return 1; + } + lpSSIM->rgTime[pid].vtType = VT_FILETIME; + if (pid==0) { + lpSSIM->rgTime[0].time.dwLowDateTime = + (((((DWORD)yr*365+mo*30)+dy)*24+hr)*60+mn)*60+sc; + lpSSIM->rgTime[0].time.dwHighDateTime = 0; + //10^7 nanoseconds/second + ulargeMultiply((ULARGE_INTEGER FAR*)&lpSSIM->rgTime[0].time, 10000); + //convert to units of 100 ns + ulargeMultiply((ULARGE_INTEGER FAR*)&lpSSIM->rgTime[0].time, 1000); + } else { + sffs.yr = max(yr-1980,0); + sffs.mon = mo; + sffs.dom = dy; + sffs.hr = hr; + sffs.mint= mn; + sffs.sec = sc/2; //dos is 2 second intervals + if (!CoDosDateTimeToFileTime(sffs.date, sffs.time, + &lpSSIM->rgTime[pid].time)) { + lpSSIM->rgTime[pid].vtType = VT_EMPTY; + return 0; + } + } + return 1; +} + +} //END C diff --git a/private/oleutest/letest/ole2ui/suminfo.h b/private/oleutest/letest/ole2ui/suminfo.h new file mode 100644 index 000000000..ef803ab65 --- /dev/null +++ b/private/oleutest/letest/ole2ui/suminfo.h @@ -0,0 +1,331 @@ +/************************************************************************* +** +** OLE 2.0 Property Set Utilities +** +** suminfo.h +** +** This file contains file contains data structure defintions, +** function prototypes, constants, etc. for OLE 2.0 Property Set +** utilities used to manage the Summary Info property set. +** +** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved +** +*************************************************************************/ + +#ifndef SUMINFO_H +#define SUMINFO_H + +#include <ole2.h> + +/* A SUMINFO variable is an instance of an abstract data type. Thus, +** there can be an arbitrary number of SummaryInfo streams open +** simultaneously (subject to available memory). Each variable must +** be initialized prior to use by calling Init and freed after its +** last use by calling Free. The param argument to Init is reserved +** for future expansion and should be zero initially. Once a SUMINFO +** variable is allocated (by Init), the user can call the Set +** procedures to initialize fields. A copy of the arguments is made +** in every case except SetThumbnail where control of the storage +** occupied by the METAFILEPICT is merely transferred. When the +** Free routine is called, all storage will be deallocated including +** that of the thumbnail. The arguments to SetThumbNail and the +** return values from GetThumbNail correspond to the OLE2.0 spec. +** Note that on input, the thumbnail is read on demand but all the +** other properties are pre-loaded. The thumbnail is manipulated as +** a windows handle to a METAFILEPICT structure, which in turn +** contains a handle to the METAFILE. The transferClip argument on +** GetThumbNail, when set to true, transfers responsibility for +** storage management of the thumbnail to the caller; that is, after +** Free has been called, the handle is still valid. Clear can be +** used to free storage for all the properties but then you must +** call Read to load them again. All the code is based on FAR +** pointers. +** CoInitialize MUST be called PRIOR to calling OleStdInitSummaryInfo. +** Memory is allocated using the currently active IMalloc* +** allocator (as is returned by call CoGetMalloc(MEMCTX_TASK) ). +** +** Common scenarios: +** Read SummaryInfo +** ---------------- +** OleStdInitSummaryInfo() +** OleStdReadSummaryInfo() +** . . . . . +** call different Get routines +** . . . . . +** OleStdFreeSummaryInfo() +** +** Create SummaryInfo +** ------------------ +** OleStdInitSummaryInfo() +** call different Set routines +** OleStdWriteSummaryInfo() +** OleStdFreeSummaryInfo() +** +** Update SummaryInfo +** ------------------ +** OleStdInitSummaryInfo() +** OleStdReadSummaryInfo() +** OleStdGetThumbNailProperty(necessary only if no SetThumb) +** call different Set routines +** OleStdWriteSummaryInfo() +** OleStdFreeSummaryInfo() +*/ + +#define WORDMAX 256 //current string max for APPS; 255 + null terminator + + +typedef union { + short iVal; /* VT_I2 */ + long lVal; /* VT_I4 */ + float fltVal; /* VT_R4 */ + double dblVal; /* VT_R8 */ + DWORD bool; /* VT_BOOL */ + SCODE scodeVal; /* VT_ERROR */ + DWORD systimeVal; /* VT_SYSTIME */ +#ifdef UNICODE + TCHAR bstrVal[WORDMAX]; /* VT_BSTR */ +#else + unsigned char bstrVal[WORDMAX]; /* VT_BSTR */ +#endif + } VTUNION; + +#if 0 +typedef struct _FMTID + { + DWORD dword; + WORD words[2]; + BYTE bytes[8]; + } FMTID; +#endif + +typedef struct _PROPSETLIST + { + FMTID formatID; + DWORD byteOffset; + } PROPSETLIST; + +typedef struct _PROPIDLIST + { + DWORD propertyID; + DWORD byteOffset; + } PROPIDLIST; + +typedef struct _PROPVALUE + { + DWORD vtType; + VTUNION vtValue; + } PROPVALUE; + +typedef struct _SECTION + { + DWORD cBytes; + DWORD cProperties; + PROPIDLIST rgPropId[1/*cProperties*/]; //variable-length array + PROPVALUE rgPropValue[1]; //CANNOT BE ACCESSED BY NAME; ONLY BY POINTER + } SECTION; + +typedef struct _SUMMARYINFO + { + WORD byteOrder; + WORD formatVersion; + WORD getOSVersion; + WORD osVersion; + CLSID classId; //from compobj.h + DWORD cSections; + PROPSETLIST rgPropSet[1/*cSections*/]; //variable-length array + SECTION rgSections[1/*cSections*/]; //CANNOT BE ACCESSED BY NAME; ONLY BY POINTER + } SUMMARYINFO; + +#define osWinOnDos 0 +#define osMac 1 +#define osWinNT 2 + +#define PID_DICTIONARY 0X00000000 +#define PID_CODEPAGE 0X00000001 +#define PID_TITLE 0X00000002 +#define PID_SUBJECT 0X00000003 +#define PID_AUTHOR 0X00000004 +#define PID_KEYWORDS 0X00000005 +#define PID_COMMENTS 0X00000006 +#define PID_TEMPLATE 0X00000007 +#define PID_LASTAUTHOR 0X00000008 +#define PID_REVNUMBER 0X00000009 +#define PID_EDITTIME 0X0000000A +#define PID_LASTPRINTED 0X0000000B +#define PID_CREATE_DTM_RO 0X0000000C +#define PID_LASTSAVE_DTM 0X0000000D +#define PID_PAGECOUNT 0X0000000E +#define PID_WORDCOUNT 0X0000000F +#define PID_CHARCOUNT 0X00000010 +#define PID_THUMBNAIL 0X00000011 +#define PID_APPNAME 0X00000012 +#define PID_SECURITY 0X00000013 +#define cPID_STANDARD (PID_SECURITY+1-2) + +#define MAXWORD 256 //maximum string size for APPS at present + +typedef struct _STDZ + { + DWORD vtType; + union { + DWORD vtByteCount; +#ifdef UNICODE + TCHAR fill[4]; //use last byte as byte count for stz requests +#else + unsigned char fill[4]; //use last byte as byte count for stz requests +#endif + }; + +#ifdef UNICODE + TCHAR rgchars[MAXWORD]; +#else + unsigned char rgchars[MAXWORD]; +#endif + } STDZ; +#define VTCB fill[3] //used to set/get the count byte when in memory + +typedef struct _THUMB + { + DWORD vtType; + DWORD cBytes; //clip size in memory + DWORD selector; //on disk -1,win clip no. -2,mac clip no. -3,ole FMTID 0,bytes nameLength, format name + DWORD clipFormat; + char FAR *lpstzName; + char FAR *lpByte; + } THUMB; + +#define VT_CF_BYTES 0 +#define VT_CF_WIN ((DWORD)(-1)) +#define VT_CF_MAC ((DWORD)(-2)) +#define VT_CF_FMTID ((DWORD)(-3)) +#define VT_CF_NAME ((DWORD)(-4)) +#define VT_CF_EMPTY ((DWORD)(-5)) +#define VT_CF_OOM ((DWORD)(-6)) // Out of memory +typedef THUMB FAR *LPTHUMB; + +typedef STDZ FAR *LPSTDZ; + +typedef struct _TIME + { + DWORD vtType; + FILETIME time; + } TIME; + +typedef struct _INTS + { + DWORD vtType; + DWORD value; + } INTS; + +#define MAXTIME (PID_LASTSAVE_DTM-PID_EDITTIME+1) +#define MAXINTS (PID_CHARCOUNT-PID_PAGECOUNT+1+1) +#define MAXSTDZ (PID_REVNUMBER-PID_TITLE+1+1) + +typedef struct _STANDARDSECINMEM + { + DWORD cBytes; + DWORD cProperties; + PROPIDLIST rgPropId[cPID_STANDARD/*cProperties*/]; //variable-length array + TIME rgTime[MAXTIME]; + INTS rgInts[MAXINTS]; + LPSTDZ rglpsz[MAXSTDZ]; + THUMB thumb; + } STANDARDSECINMEM; + + +#define OFFSET_NIL 0X00000000 + +#define AllSecurityFlagsEqNone 0 +#define fSecurityPassworded 1 +#define fSecurityRORecommended 2 +#define fSecurityRO 4 +#define fSecurityLockedForAnnotations 8 + +#define PropStreamNamePrefixByte '\005' +#define PropStreamName "\005SummaryInformation" +#define cbNewSummaryInfo(nSection) (sizeof(SUMMARYINFO)-sizeof(SECTION)+sizeof(PROPSETLIST)*((nSection)-1)) +#define cbNewSection(nPropIds) (sizeof(SECTION)-sizeof(PROPVALUE)+sizeof(PROPIDLIST)*((nPropIds)-1)) + +#define FIntelOrder(prop) ((prop)->byteOrder==0xfffe) +#define SetOs(prop, os) {(prop)->osVersion=os; (prop)->getOSVersion=LOWORD(GetVersion());} +#define SetSumInfFMTID(fmtId) {(fmtId)->Data1=0XF29F85E0; *(long FAR *)&(fmtId)->Data2=0X10684FF9;\ + *(long FAR *)&(fmtId)->Data4[0]=0X000891AB; *(long FAR *)&(fmtId)->Data4[4]=0XD9B3272B;} +#define FEqSumInfFMTID(fmtId) ((fmtId)->Data1==0XF29F85E0&&*((long FAR *)&(fmtId)->Data2)==0X10684FF9&&\ + *((long FAR *)&(fmtId)->Data4[0])==0X000891AB&&*((long FAR *)&(fmtId)->Data4[4])==0XD9B3272B) +#define FSzEqPropStreamName(sz) _fstricmp(sz, PropStreamName) +#define ClearSumInf(lpsuminf, cb) {_fmemset(lpsuminf,0,cb); (lpsuminf)->byteOrder=0xfffe;\ + SetOs(lpsuminf, osWinOnDos);} + +typedef void FAR *LPSUMINFO; +typedef LPTSTR LPSTZR; +typedef void FAR *THUMBNAIL; //for VT_CF_WIN this is an unlocked global handle +#define API __far __pascal + + +/************************************************************************* +** Public Summary Info Property Set Management API +*************************************************************************/ + +extern "C" { +STDAPI_(LPSUMINFO) OleStdInitSummaryInfo(int reserved); +STDAPI_(void) OleStdFreeSummaryInfo(LPSUMINFO FAR *lplp); +STDAPI_(void) OleStdClearSummaryInfo(LPSUMINFO lp); +STDAPI_(int) OleStdReadSummaryInfo(LPSTREAM lpStream, LPSUMINFO lp); +STDAPI_(int) OleStdWriteSummaryInfo(LPSTREAM lpStream, LPSUMINFO lp); +STDAPI_(DWORD) OleStdGetSecurityProperty(LPSUMINFO lp); +STDAPI_(int) OleStdSetSecurityProperty(LPSUMINFO lp, DWORD security); +STDAPI_(LPTSTR) OleStdGetStringProperty(LPSUMINFO lp, DWORD pid); +STDAPI_(int) OleStdSetStringProperty(LPSUMINFO lp, DWORD pid, LPTSTR lpsz); +STDAPI_(LPSTZR) OleStdGetStringZProperty(LPSUMINFO lp, DWORD pid); +STDAPI_(void) OleStdGetDocProperty( + LPSUMINFO lp, + DWORD FAR* nPage, + DWORD FAR* nWords, + DWORD FAR* nChars +); +STDAPI_(int) OleStdSetDocProperty( + LPSUMINFO lp, + DWORD nPage, + DWORD nWords, + DWORD nChars +); +STDAPI_(int) OleStdGetThumbNailProperty( + LPSTREAM lps, + LPSUMINFO lp, + DWORD FAR* clipFormatNo, + LPTSTR FAR* lpszName, + THUMBNAIL FAR* clip, + DWORD FAR* byteCount, + BOOL transferClip +); +STDAPI_(int) OleStdSetThumbNailProperty( + LPSTREAM lps, + LPSUMINFO lp, + int vtcfNo, + DWORD clipFormatNo, + LPTSTR lpszName, + THUMBNAIL clip, + DWORD byteCount +); +STDAPI_(void) OleStdGetDateProperty( + LPSUMINFO lp, + DWORD pid, + int FAR* yr, + int FAR* mo, + int FAR* dy, + DWORD FAR* sc +); +STDAPI_(int) OleStdSetDateProperty( + LPSUMINFO lp, + DWORD pid, + int yr, + int mo, + int dy, + int hr, + int mn, + int sc +); + +} //END C + +#endif // SUMINFO_H diff --git a/private/oleutest/letest/ole2ui/targtdev.c b/private/oleutest/letest/ole2ui/targtdev.c new file mode 100644 index 000000000..55b6b0886 --- /dev/null +++ b/private/oleutest/letest/ole2ui/targtdev.c @@ -0,0 +1,328 @@ +/************************************************************************* +** +** 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 +** +*************************************************************************/ + +#define STRICT 1 +#include "ole2ui.h" +#ifndef WIN32 +#include <print.h> +#endif + +/* + * OleStdCreateDC() + * + * Purpose: + * + * Parameters: + * + * Return Value: + * SCODE - S_OK if successful + */ +STDAPI_(HDC) OleStdCreateDC(DVTARGETDEVICE FAR* ptd) +{ + HDC hdc=NULL; + LPDEVNAMES lpDevNames; + LPDEVMODE lpDevMode; + LPTSTR lpszDriverName; + LPTSTR lpszDeviceName; + LPTSTR lpszPortName; + + if (ptd == NULL) { + hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); + goto errReturn; + } + + lpDevNames = (LPDEVNAMES) ptd; // offset for size field + + if (ptd->tdExtDevmodeOffset == 0) { + lpDevMode = NULL; + }else{ + lpDevMode = (LPDEVMODE) ((LPSTR)ptd + ptd->tdExtDevmodeOffset); + } + + lpszDriverName = (LPTSTR) lpDevNames + ptd->tdDriverNameOffset; + lpszDeviceName = (LPTSTR) lpDevNames + ptd->tdDeviceNameOffset; + lpszPortName = (LPTSTR) lpDevNames + ptd->tdPortNameOffset; + + hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, lpDevMode); + +errReturn: + return hdc; +} + + +/* + * OleStdCreateIC() + * + * Purpose: Same as OleStdCreateDC, except that information context is + * created, rather than a whole device context. (CreateIC is + * used rather than CreateDC). + * OleStdDeleteDC is still used to delete the information context. + * + * Parameters: + * + * Return Value: + * SCODE - S_OK if successful + */ +STDAPI_(HDC) OleStdCreateIC(DVTARGETDEVICE FAR* ptd) +{ + HDC hdcIC=NULL; + LPDEVNAMES lpDevNames; + LPDEVMODE lpDevMode; + LPTSTR lpszDriverName; + LPTSTR lpszDeviceName; + LPTSTR lpszPortName; + + if (ptd == NULL) { + hdcIC = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL); + goto errReturn; + } + + lpDevNames = (LPDEVNAMES) ptd; // offset for size field + + lpDevMode = (LPDEVMODE) ((LPTSTR)ptd + ptd->tdExtDevmodeOffset); + + lpszDriverName = (LPTSTR) lpDevNames + ptd->tdDriverNameOffset; + lpszDeviceName = (LPTSTR) lpDevNames + ptd->tdDeviceNameOffset; + lpszPortName = (LPTSTR) lpDevNames + ptd->tdPortNameOffset; + + hdcIC = CreateIC(lpszDriverName, lpszDeviceName, lpszPortName, lpDevMode); + +errReturn: + return hdcIC; +} + + +#ifdef NEVER +// This code is wrong +/* + * OleStdCreateTargetDevice() + * + * Purpose: + * + * Parameters: + * + * Return Value: + * SCODE - S_OK if successful + */ +STDAPI_(DVTARGETDEVICE FAR*) OleStdCreateTargetDevice(LPPRINTDLG lpPrintDlg) +{ + DVTARGETDEVICE FAR* ptd=NULL; + LPDEVNAMES lpDevNames, pDN; + LPDEVMODE lpDevMode, pDM; + UINT nMaxOffset; + LPTSTR pszName; + DWORD dwDevNamesSize, dwDevModeSize, dwPtdSize; + + if ((pDN = (LPDEVNAMES)GlobalLock(lpPrintDlg->hDevNames)) == NULL) { + goto errReturn; + } + + if ((pDM = (LPDEVMODE)GlobalLock(lpPrintDlg->hDevMode)) == NULL) { + goto errReturn; + } + + nMaxOffset = (pDN->wDriverOffset > pDN->wDeviceOffset) ? + pDN->wDriverOffset : pDN->wDeviceOffset ; + + nMaxOffset = (pDN->wOutputOffset > nMaxOffset) ? + pDN->wOutputOffset : nMaxOffset ; + + pszName = (LPTSTR)pDN + nMaxOffset; + + dwDevNamesSize = (DWORD)((nMaxOffset+lstrlen(pszName) + 1/* NULL term */)*sizeof(TCHAR)); + dwDevModeSize = (DWORD) (pDM->dmSize + pDM->dmDriverExtra); + + dwPtdSize = sizeof(DWORD) + dwDevNamesSize + dwDevModeSize; + + if ((ptd = (DVTARGETDEVICE FAR*)OleStdMalloc(dwPtdSize)) != NULL) { + + // copy in the info + ptd->tdSize = (UINT)dwPtdSize; + + lpDevNames = (LPDEVNAMES) &ptd->tdDriverNameOffset; + _fmemcpy(lpDevNames, pDN, (size_t)dwDevNamesSize); + + lpDevMode=(LPDEVMODE)((LPTSTR)&ptd->tdDriverNameOffset+dwDevNamesSize); + _fmemcpy(lpDevMode, pDM, (size_t)dwDevModeSize); + + ptd->tdDriverNameOffset += 4 ; + ptd->tdDeviceNameOffset += 4 ; + ptd->tdPortNameOffset += 4 ; + ptd->tdExtDevmodeOffset = (UINT)dwDevNamesSize + 4 ; + } + +errReturn: + GlobalUnlock(lpPrintDlg->hDevNames); + GlobalUnlock(lpPrintDlg->hDevMode); + + return ptd; +} +#endif // NEVER + + + +/* + * OleStdDeleteTargetDevice() + * + * Purpose: + * + * Parameters: + * + * Return Value: + * SCODE - S_OK if successful + */ +STDAPI_(BOOL) OleStdDeleteTargetDevice(DVTARGETDEVICE FAR* ptd) +{ + BOOL res=TRUE; + + if (ptd != NULL) { + OleStdFree(ptd); + } + + return res; +} + + + +/* + * OleStdCopyTargetDevice() + * + * Purpose: + * duplicate a TARGETDEVICE struct. this function allocates memory for + * the copy. the caller MUST free the allocated copy when done with it + * using the standard allocator returned from CoGetMalloc. + * (OleStdFree can be used to free the copy). + * + * Parameters: + * ptdSrc pointer to source TARGETDEVICE + * + * Return Value: + * pointer to allocated copy of ptdSrc + * if ptdSrc==NULL then retuns NULL is returned. + * if ptdSrc!=NULL and memory allocation fails, then NULL is returned + */ +STDAPI_(DVTARGETDEVICE FAR*) OleStdCopyTargetDevice(DVTARGETDEVICE FAR* ptdSrc) +{ + DVTARGETDEVICE FAR* ptdDest = NULL; + + if (ptdSrc == NULL) { + return NULL; + } + + if ((ptdDest = (DVTARGETDEVICE FAR*)OleStdMalloc(ptdSrc->tdSize)) != NULL) { + _fmemcpy(ptdDest, ptdSrc, (size_t)ptdSrc->tdSize); + } + + return ptdDest; +} + + +/* + * OleStdCopyFormatEtc() + * + * Purpose: + * Copies the contents of a FORMATETC structure. this function takes + * special care to copy correctly copying the pointer to the TARGETDEVICE + * contained within the source FORMATETC structure. + * if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy + * of the TARGETDEVICE will be allocated for the destination of the + * FORMATETC (petcDest). + * + * OLE2NOTE: the caller MUST free the allocated copy of the TARGETDEVICE + * within the destination FORMATETC when done with it + * using the standard allocator returned from CoGetMalloc. + * (OleStdFree can be used to free the copy). + * + * Parameters: + * petcDest pointer to destination FORMATETC + * petcSrc pointer to source FORMATETC + * + * Return Value: + * returns TRUE is copy is successful; retuns FALSE if not successful + */ +STDAPI_(BOOL) OleStdCopyFormatEtc(LPFORMATETC petcDest, LPFORMATETC petcSrc) +{ + if ((petcDest == NULL) || (petcSrc == NULL)) { + return FALSE; + } + + petcDest->cfFormat = petcSrc->cfFormat; + petcDest->ptd = OleStdCopyTargetDevice(petcSrc->ptd); + petcDest->dwAspect = petcSrc->dwAspect; + petcDest->lindex = petcSrc->lindex; + petcDest->tymed = petcSrc->tymed; + + return TRUE; + +} + + +// returns 0 for exact match, 1 for no match, -1 for partial match (which is +// defined to mean the left is a subset of the right: fewer aspects, null target +// device, fewer medium). + +STDAPI_(int) OleStdCompareFormatEtc(FORMATETC FAR* pFetcLeft, FORMATETC FAR* pFetcRight) +{ + BOOL bExact = TRUE; + + if (pFetcLeft->cfFormat != pFetcRight->cfFormat) + return 1; + else if (!OleStdCompareTargetDevice (pFetcLeft->ptd, pFetcRight->ptd)) + return 1; + if (pFetcLeft->dwAspect == pFetcRight->dwAspect) + // same aspects; equal + ; + else if ((pFetcLeft->dwAspect & ~pFetcRight->dwAspect) != 0) + // left not subset of aspects of right; not equal + return 1; + else + // left subset of right + bExact = FALSE; + + if (pFetcLeft->tymed == pFetcRight->tymed) + // same medium flags; equal + ; + else if ((pFetcLeft->tymed & ~pFetcRight->tymed) != 0) + // left not subset of medium flags of right; not equal + return 1; + else + // left subset of right + bExact = FALSE; + + return bExact ? 0 : -1; +} + + + +STDAPI_(BOOL) OleStdCompareTargetDevice + (DVTARGETDEVICE FAR* ptdLeft, DVTARGETDEVICE FAR* 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; +#ifdef WIN32 + else if (memcmp(ptdLeft, ptdRight, ptdLeft->tdSize) != 0) +#else + else if (_fmemcmp(ptdLeft, ptdRight, (int)ptdLeft->tdSize) != 0) +#endif + // not same target device, not equal + return FALSE; + + return TRUE; +} + diff --git a/private/oleutest/letest/ole2ui/template.c b/private/oleutest/letest/ole2ui/template.c new file mode 100644 index 000000000..9c35b4c2f --- /dev/null +++ b/private/oleutest/letest/ole2ui/template.c @@ -0,0 +1,243 @@ +/* + * TEMPLATE.C + * + * 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>.C + * + * Implements the OleUI<NAME> function which invokes the complete + * <FULLNAME> dialog. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include "common.h" + +#ifndef WIN32 +#include "<FILE>.h" +#else + #include "template.h" +#endif + + + + +/* + * 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: + * { + * if (NULL!=hMemDlg) + * FreeResource(hMemDlg) + * + * 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 EXPORT <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) + { + //Free any specific allocations before calling StandardCleanup + StandardCleanup((PVOID)p<ABBREV>, hDlg); + EndDialog(hDlg, wParam); + return TRUE; + } + + switch (iMsg) + { + 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/oleutest/letest/ole2ui/template.h b/private/oleutest/letest/ole2ui/template.h new file mode 100644 index 000000000..3f277aec1 --- /dev/null +++ b/private/oleutest/letest/ole2ui/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. + + /* + * 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>.C +BOOL FAR PASCAL <NAME>DialogProc(HWND, UINT, WPARAM, LPARAM); +BOOL F<NAME>Init(HWND hDlg, WPARAM, LPARAM); +<UFILL> + + + +#endif //<UFILL> diff --git a/private/oleutest/letest/ole2ui/uiclass.h b/private/oleutest/letest/ole2ui/uiclass.h new file mode 100644 index 000000000..801819141 --- /dev/null +++ b/private/oleutest/letest/ole2ui/uiclass.h @@ -0,0 +1,2 @@ +#define SZCLASSICONBOX TEXT("OLE2UIIBClass") +#define SZCLASSRESULTIMAGE TEXT("OLE2UIRIClass") diff --git a/private/oleutest/letest/ole2ui/uimake.cmd b/private/oleutest/letest/ole2ui/uimake.cmd new file mode 100644 index 000000000..b6bd1f6c7 --- /dev/null +++ b/private/oleutest/letest/ole2ui/uimake.cmd @@ -0,0 +1 @@ +nmake -f ole2ui.mak %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/private/oleutest/letest/ole2ui/uimake.ini b/private/oleutest/letest/ole2ui/uimake.ini new file mode 100644 index 000000000..a7d847908 --- /dev/null +++ b/private/oleutest/letest/ole2ui/uimake.ini @@ -0,0 +1,24 @@ +# This is the DEBUG static .LIB UILibrary INI file +MSG=DEBUG Static LIB Version ($(LANG)) +DEBUG=1 +MODEL=M +# Make a static library called OLE2UI.LIB +LIBNAME=OLE2UI +REL_DIR=d:\cairo\cairole\h\export +OLEREL_DIR=d:\cairo\cairole\h\export +OBJ=DEBUGLIB +BUILD=LIB +RESOURCE=RESOURCE + +# 16 bit CFLAGS=-c -Od -GA2s -W3 -Zpei -AM -D_DEBUG -DWIN32 -DUNICODE + +CFLAGS=-c -Od -Gs -W3 -Zpei -D_DEBUG -DWIN32 -DUNICODE +RFLAGS=-D DEBUG +LFLAGS=/MAP:FULL /CO /LINE /NOD /NOE /SE:300 /NOPACKCODE +UILIBS=mlibcew libw ole2 storage shell commdlg toolhelp +CC=cl +AS=masm +RS=rc +LK=link +LANG=USA +LIBOBJS = $(UI_COBJS:D^\=DEBUGLIB^\) $(UI_NOPCOBJS:D^\=DEBUGLIB\NOPC^\) diff --git a/private/oleutest/letest/ole2ui/utility.c b/private/oleutest/letest/ole2ui/utility.c new file mode 100644 index 000000000..98deecc25 --- /dev/null +++ b/private/oleutest/letest/ole2ui/utility.c @@ -0,0 +1,1039 @@ +/* + * UTILITY.C + * + * Utility routines for functions inside OLE2UI.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 + * + * Registration Database: + * ---------------------- + * HIconFromClass Extracts the first icon in a class's server path + * FServerFromClass Retrieves the server path for a class name (fast) + * UClassFromDescription Finds the classname given a description (slow) + * UDescriptionFromClass Retrieves the description for a class name (fast) + * FGetVerb Retrieves a specific verb for a class (fast) + * + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + +#define STRICT 1 +#include "ole2ui.h" +#include <stdlib.h> +#include <commdlg.h> +#include <memory.h> +#include <cderr.h> +#include "common.h" +#include "utility.h" +#include "geticon.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 + * + * 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 cch; + TCHAR szFilters[256]; + OPENFILENAME ofn; + BOOL fStatus; + DWORD dwError; + TCHAR szDlgTitle[128]; // that should be big enough + + if (NULL==lpszFile || 0==cchFile) + return FALSE; + + /* + * REVIEW: 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(ghInst, iFilterString, (LPTSTR)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. + _fmemset((LPOPENFILENAME)&ofn, 0, sizeof(ofn)); + ofn.lStructSize =sizeof(ofn); + ofn.hwndOwner =hWndOwner; + ofn.lpstrFile =lpszFile; + ofn.nMaxFile =cchFile; + ofn.lpstrFilter =(LPTSTR)szFilters; + ofn.nFilterIndex=1; + if (LoadString(ghInst, IDS_BROWSE, (LPTSTR)szDlgTitle, sizeof(szDlgTitle)/sizeof(TCHAR))) + ofn.lpstrTitle =(LPTSTR)szDlgTitle; + ofn.hInstance = ghInst; + ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEOPEN); + if (NULL != lpszInitialDir) + ofn.lpstrInitialDir = lpszInitialDir; + + ofn.Flags= OFN_HIDEREADONLY | OFN_ENABLETEMPLATE | (dwOfnFlags) ; + + //On success, copy the chosen filename to the static display + fStatus = GetOpenFileName((LPOPENFILENAME)&ofn); + dwError = CommDlgExtendedError(); + return fStatus; + + } + + + + + +/* + * 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=-1; + + if (NULL!=psz) + { + while (0!=*psz) + { + if (ch==*psz) + { + *psz=TEXT('\0'); + cChanged++; + } + 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*OLEUI_CCHPATHMAX_SIZE); + LPTSTR psz1, psz2, psz3; + + if (NULL==hInst || NULL==pszFile) + return iRet; + + //Allocate three 2*OLEUI_CCHPATHMAX byte work buffers + hMem=GlobalAlloc(GHND, (DWORD)(3*cb)); + + if (NULL==hMem) + return iRet; + + psz1=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; + } + + + + + + + + + +/* + * HIconFromClass + * + * Purpose: + * Given an object class name, finds an associated executable in the + * registration database and extracts the first icon from that + * executable. If none is available or the class has no associated + * executable, this function returns NULL. + * + * Parameters: + * pszClass LPSTR giving the object class to look up. + * + * Return Value: + * HICON Handle to the extracted icon if there is a module + * associated to pszClass. NULL on failure to either + * find the executable or extract and icon. + */ + +HICON WINAPI HIconFromClass(LPTSTR pszClass) + { + HICON hIcon; + TCHAR szEXE[OLEUI_CCHPATHMAX]; + UINT Index; + CLSID clsid; + + if (NULL==pszClass) + return NULL; + + CLSIDFromStringA(pszClass, &clsid); + + if (!FIconFileFromClass((REFCLSID)&clsid, szEXE, OLEUI_CCHPATHMAX_SIZE, &Index)) + return NULL; + + hIcon=ExtractIcon(ghInst, szEXE, Index); + + if ((HICON)32 > hIcon) + hIcon=NULL; + + return hIcon; + } + + + + + +/* + * FServerFromClass + * + * Purpose: + * Looks up the classname in the registration database and retrieves + * the name undet protocol\StdFileEditing\server. + * + * Parameters: + * pszClass LPSTR to the classname to look up. + * pszEXE LPSTR at which to store the server name + * cch UINT size of pszEXE + * + * Return Value: + * BOOL TRUE if one or more characters were loaded into pszEXE. + * FALSE otherwise. + */ + +BOOL WINAPI FServerFromClass(LPTSTR pszClass, LPTSTR pszEXE, UINT cch) +{ + + DWORD dw; + LONG lRet; + HKEY hKey; + + if (NULL==pszClass || NULL==pszEXE || 0==cch) + return FALSE; + + /* + * We have to go walking in the registration database under the + * classname, so we first open the classname key and then check + * under "\\LocalServer" to get the .EXE. + */ + + //Open up the class key + lRet=RegOpenKey(HKEY_CLASSES_ROOT, pszClass, &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return FALSE; + + //Get the executable path. + dw=(DWORD)cch; + lRet=RegQueryValue(hKey, TEXT("LocalServer"), pszEXE, &dw); + + RegCloseKey(hKey); + + return ((ERROR_SUCCESS == lRet) && (dw > 0)); +} + + + +/* + * UClassFromDescription + * + * Purpose: + * Looks up the actual OLE class name in the registration database + * for the given descriptive name chosen from a listbox. + * + * Parameters: + * psz LPSTR to the descriptive name. + * pszClass LPSTR in which to store the class name. + * cb UINT maximum length of pszClass. + * + * Return Value: + * UINT Number of characters copied to pszClass. 0 on failure. + */ + +UINT WINAPI UClassFromDescription(LPTSTR psz, LPTSTR pszClass, UINT cb) + { + DWORD dw; + HKEY hKey; + TCHAR szClass[OLEUI_CCHKEYMAX]; + LONG lRet; + UINT i; + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return 0; + + i=0; + lRet=RegEnumKey(hKey, i++, szClass, OLEUI_CCHKEYMAX_SIZE); + + //Walk the available keys + while ((LONG)ERROR_SUCCESS==lRet) + { + dw=(DWORD)cb; + lRet=RegQueryValue(hKey, szClass, pszClass, &dw); + + //Check if the description matches the one just enumerated + if ((LONG)ERROR_SUCCESS==lRet) + { + if (!lstrcmp(pszClass, psz)) + break; + } + + //Continue with the next key. + lRet=RegEnumKey(hKey, i++, szClass, OLEUI_CCHKEYMAX_SIZE); + } + + //If we found it, copy to the return buffer + if ((LONG)ERROR_SUCCESS==lRet) + lstrcpy(pszClass, szClass); + else + dw=0L; + + RegCloseKey(hKey); + return (UINT)dw; + } + + + + + + + + +/* + * UDescriptionFromClass + * + * Purpose: + * Looks up the actual OLE descriptive name name in the registration + * database for the given class name. + * + * Parameters: + * pszClass LPSTR to the class name. + * psz LPSTR in which to store the descriptive name. + * cb UINT maximum length of psz. + * + * Return Value: + * UINT Number of characters copied to pszClass. 0 on failure. + */ + +UINT WINAPI UDescriptionFromClass(LPTSTR pszClass, LPTSTR psz, UINT cb) + { + DWORD dw; + HKEY hKey; + LONG lRet; + + if (NULL==pszClass || NULL==psz) + return 0; + + //Open up the root key. + lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey); + + if ((LONG)ERROR_SUCCESS!=lRet) + return 0; + + //Get the descriptive name using the class name. + dw=(DWORD)cb; + lRet=RegQueryValue(hKey, pszClass, psz, &dw); + + RegCloseKey(hKey); + + psz+=lstrlen(psz)+1; + *psz=0; + + if ((LONG)ERROR_SUCCESS!=lRet) + return 0; + + return (UINT)dw; + } + + + +// 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; + } +} + + +/* + * 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 + * + * Return Value: + * pointer to the modified string + */ +LPTSTR WINAPI ChopText(HWND hWnd, int nWidth, LPTSTR lpch) +{ +#define PREFIX_SIZE 7 + 1 +#define PREFIX_FORMAT TEXT("%c%c%c...\\") + + TCHAR szPrefix[PREFIX_SIZE]; + BOOL fDone = FALSE; + int i; + RECT rc; + HDC hdc; + HFONT hfont; + HFONT hfontOld = NULL; + + if (!hWnd || !lpch) + return NULL; + + /* 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 = GetDC(hWnd); + hfont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0L); + + if (NULL != hfont) // WM_GETFONT returns NULL if window uses system font + hfontOld = SelectObject(hdc, hfont); + + /* check horizontal extent of string */ + if (GetTextWSize(hdc, lpch) > nWidth) { + + /* string is too long to fit in static control; chop it */ + /* set up new prefix & determine remaining space in control */ + wsprintf((LPTSTR) szPrefix, PREFIX_FORMAT, lpch[0], lpch[1], lpch[2]); + nWidth -= (int)GetTextWSize(hdc, (LPTSTR) szPrefix); + + /* + ** advance a directory at a time until the remainder of the + ** string fits into the static control after the "x:\...\" prefix + */ + while (!fDone) { + +#ifdef DBCS + while (*lpch && (*lpch != TEXT('\\'))) +#ifdef WIN32 + lpch = CharNext(lpch); +#else + lpch = AnsiNext(lpch); +#endif + if (*lpch) +#ifdef WIN32 + lpch = CharNext(lpch); +#else + lpch = AnsiNext(lpch); +#endif +#else + while (*lpch && (*lpch++ != TEXT('\\'))); +#endif + + if (!*lpch || GetTextWSize(hdc, lpch) <= nWidth) { + if (!*lpch) + /* + ** Nothing could fit after the prefix; remove the + ** final "\" from the prefix + */ + szPrefix[lstrlen((LPTSTR) szPrefix) - 1] = 0; + + /* rest or string fits -- stick prefix on front */ + for (i = lstrlen((LPTSTR) szPrefix) - 1; i >= 0; --i) + *--lpch = szPrefix[i]; + fDone = TRUE; + } + } + } + + if (NULL != hfont) + SelectObject(hdc, hfontOld); + ReleaseDC(hWnd, hdc); + + return(lpch); + +#undef PREFIX_SIZE +#undef PREFIX_FORMAT +} + + +/* + * 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, ghInst, IDS_CIFILEACCESS, lpszFile, MB_OK); + break; + + case 0x0020: // Sharing violation + ErrorWithFile(hDlg, ghInst, IDS_CIFILESHARE, lpszFile, MB_OK); + break; + + case 0x0002: // File not found + case 0x0003: // Path not found + ErrorWithFile(hDlg, ghInst, IDS_CIINVALIDFILE, lpszFile, MB_OK); + break; + + default: + ErrorWithFile(hDlg, ghInst, IDS_CIFILEOPENFAIL, lpszFile, MB_OK); + break; + } +} + +#define chSpace TEXT(' ') +#define chPeriod TEXT('.') +#define PARSE_EMPTYSTRING -1 +#define PARSE_INVALIDDRIVE -2 +#define PARSE_INVALIDPERIOD -3 +#define PARSE_INVALIDDIRCHAR -4 +#define PARSE_INVALIDCHAR -5 +#define PARSE_WILDCARDINDIR -6 +#define PARSE_INVALIDNETPATH -7 +#define PARSE_INVALIDSPACE -8 +#define PARSE_EXTENTIONTOOLONG -9 +#define PARSE_DIRECTORYNAME -10 +#define PARSE_FILETOOLONG -11 + +/*--------------------------------------------------------------------------- + * ParseFile + * Purpose: Determine if the filename is a legal DOS name + * Input: Long pointer to a SINGLE file name + * Circumstance checked: + * 1) Valid as directory name, but not as file name + * 2) Empty String + * 3) Illegal Drive label + * 4) Period in invalid location (in extention, 1st in file name) + * 5) Missing directory character + * 6) Illegal character + * 7) Wildcard in directory name + * 8) Double slash beyond 1st 2 characters + * 9) Space character in the middle of the name (trailing spaces OK) + * 10) Filename greater than 8 characters + * 11) Extention greater than 3 characters + * Notes: + * Filename length is NOT checked. + * Valid filenames will have leading spaces, trailing spaces and + * terminating period stripped in place. + * + * Returns: If valid, LOWORD is byte offset to filename + * HIWORD is byte offset to extention + * if string ends with period, 0 + * if no extention is given, string length + * If invalid, LOWORD is error code suggesting problem (< 0) + * HIWORD is approximate offset where problem found + * Note that this may be beyond the offending character + *--------------------------------------------------------------------------*/ + +static long ParseFile(LPTSTR lpstrFileName) +{ + short nFile, nExt, nFileOffset, nExtOffset; + BOOL bExt; + BOOL bWildcard; + short nNetwork = 0; + BOOL bUNCPath = FALSE; + LPTSTR lpstr = lpstrFileName; + +/* Strip off initial white space. Note that TAB is not checked */ +/* because it cannot be received out of a standard edit control */ +/* 30 January 1991 clarkc */ + while (*lpstr == chSpace) + lpstr++; + + if (!*lpstr) + { + nFileOffset = PARSE_EMPTYSTRING; + goto FAILURE; + } + + if (lpstr != lpstrFileName) + { + lstrcpy(lpstrFileName, lpstr); + lpstr = lpstrFileName; + } + + if ( + +#ifdef WIN32 + *CharNext(lpstr) +#else + *AnsiNext(lpstr) +#endif + == TEXT(':') + ) + + { + TCHAR cDrive = (*lpstr | (BYTE) 0x20); /* make lowercase */ + +/* This does not test if the drive exists, only if it's legal */ + if ((cDrive < TEXT('a')) || (cDrive > TEXT('z'))) + { + nFileOffset = PARSE_INVALIDDRIVE; + goto FAILURE; + } +#ifdef WIN32 + lpstr = CharNext(CharNext(lpstr)); +#else + lpstr = AnsiNext(AnsiNext(lpstr)); +#endif + } + + if ((*lpstr == TEXT('\\')) || (*lpstr == TEXT('/'))) + { + if (*++lpstr == chPeriod) /* cannot have c:\. */ + { + if ((*++lpstr != TEXT('\\')) && (*lpstr != TEXT('/'))) /* unless it's stupid */ + { + if (!*lpstr) /* it's the root directory */ + goto MustBeDir; + + nFileOffset = PARSE_INVALIDPERIOD; + goto FAILURE; + } + else + ++lpstr; /* it's saying top directory (again), thus allowed */ + } + else if ((*lpstr == TEXT('\\')) && (*(lpstr-1) == TEXT('\\'))) + { +/* It seems that for a full network path, whether a drive is declared or + * not is insignificant, though if a drive is given, it must be valid + * (hence the code above should remain there). + * 13 February 1991 clarkc + */ + ++lpstr; /* ...since it's the first slash, 2 are allowed */ + nNetwork = -1; /* Must receive server and share to be real */ + bUNCPath = TRUE; /* No wildcards allowed if UNC name */ + } + else if (*lpstr == TEXT('/')) + { + nFileOffset = PARSE_INVALIDDIRCHAR; + goto FAILURE; + } + } + else if (*lpstr == chPeriod) + { + if (*++lpstr == chPeriod) /* Is this up one directory? */ + ++lpstr; + if (!*lpstr) + goto MustBeDir; + if ((*lpstr != TEXT('\\')) && (*lpstr != TEXT('/'))) + { + nFileOffset = PARSE_INVALIDPERIOD; + goto FAILURE; + } + else + ++lpstr; /* it's saying directory, thus allowed */ + } + + if (!*lpstr) + { + goto MustBeDir; + } + +/* Should point to first char in 8.3 filename by now */ + nFileOffset = nExtOffset = nFile = nExt = 0; + bWildcard = bExt = FALSE; + while (*lpstr) + { +/* + * The next comparison MUST be unsigned to allow for extended characters! + * 21 Feb 1991 clarkc + */ + if (*lpstr < chSpace) + { + nFileOffset = PARSE_INVALIDCHAR; + goto FAILURE; + } + switch (*lpstr) + { + case TEXT('"'): /* All invalid */ + case TEXT('+'): + case TEXT(','): + case TEXT(':'): + case TEXT(';'): + case TEXT('<'): + case TEXT('='): + case TEXT('>'): + case TEXT('['): + case TEXT(']'): + case TEXT('|'): + { + nFileOffset = PARSE_INVALIDCHAR; + goto FAILURE; + } + + case TEXT('\\'): /* Subdirectory indicators */ + case TEXT('/'): + nNetwork++; + if (bWildcard) + { + nFileOffset = PARSE_WILDCARDINDIR; + goto FAILURE; + } + + else if (nFile == 0) /* can't have 2 in a row */ + { + nFileOffset = PARSE_INVALIDDIRCHAR; + goto FAILURE; + } + else + { /* reset flags */ + ++lpstr; + if (!nNetwork && !*lpstr) + { + nFileOffset = PARSE_INVALIDNETPATH; + goto FAILURE; + } + nFile = nExt = 0; + bExt = FALSE; + } + break; + + case chSpace: + { + LPTSTR lpSpace = lpstr; + + *lpSpace = TEXT('\0'); + while (*++lpSpace) + { + if (*lpSpace != chSpace) + { + *lpstr = chSpace; /* Reset string, abandon ship */ + nFileOffset = PARSE_INVALIDSPACE; + goto FAILURE; + } + } + } + break; + + case chPeriod: + if (nFile == 0) + { + if (*++lpstr == chPeriod) + ++lpstr; + if (!*lpstr) + goto MustBeDir; + + if ((*lpstr != TEXT('\\')) && (*lpstr != TEXT('/'))) + { + nFileOffset = PARSE_INVALIDPERIOD; + goto FAILURE; + } + + ++lpstr; /* Flags are already set */ + } + else if (bExt) + { + nFileOffset = PARSE_INVALIDPERIOD; /* can't have one in ext */ + goto FAILURE; + } + else + { + nExtOffset = 0; + ++lpstr; + bExt = TRUE; + } + break; + + case TEXT('*'): + case TEXT('?'): + if (bUNCPath) + { + nFileOffset = PARSE_INVALIDNETPATH; + goto FAILURE; + } + bWildcard = TRUE; +/* Fall through to normal character processing */ + + default: + if (bExt) + { + if (++nExt == 1) + nExtOffset = lpstr - lpstrFileName; + else if (nExt > 3) + { + nFileOffset = PARSE_EXTENTIONTOOLONG; + goto FAILURE; + } + if ((nNetwork == -1) && (nFile + nExt > 11)) + { + nFileOffset = PARSE_INVALIDNETPATH; + goto FAILURE; + } + } + else if (++nFile == 1) + nFileOffset = lpstr - lpstrFileName; + else if (nFile > 8) + { + /* If it's a server name, it can have 11 characters */ + if (nNetwork != -1) + { + nFileOffset = PARSE_FILETOOLONG; + goto FAILURE; + } + else if (nFile > 11) + { + nFileOffset = PARSE_INVALIDNETPATH; + goto FAILURE; + } + } + +#ifdef WIN32 + lpstr = CharNext(lpstr); +#else + lpstr = AnsiNext(lpstr); +#endif + break; + } + } + +/* Did we start with a double backslash but not have any more slashes? */ + if (nNetwork == -1) + { + nFileOffset = PARSE_INVALIDNETPATH; + goto FAILURE; + } + + if (!nFile) + { +MustBeDir: + nFileOffset = PARSE_DIRECTORYNAME; + goto FAILURE; + } + + if ((*(lpstr - 1) == chPeriod) && /* if true, no extention wanted */ + ( +#ifdef WIN32 + *CharNext(lpstr-2) +#else + *AnsiNext(lpstr-2) +#endif + == chPeriod + )) + *(lpstr - 1) = TEXT('\0'); /* Remove terminating period */ + else if (!nExt) +FAILURE: + nExtOffset = lpstr - lpstrFileName; + + return(MAKELONG(nFileOffset, nExtOffset)); +} + + +/* + * DoesFileExist + * + * Purpose: + * Determines if a file path exists + * + * Parameters: + * lpszFile LPTSTR - file name + * lpOpenBuf OFSTRUCT FAR* - points to the OFSTRUCT structure that + * will receive information about the file when the + * file is first opened. this field is filled by the + * Windows OpenFile API. + * + * Return Value: + * HFILE HFILE_ERROR - file does NOT exist + * file handle (as returned from OpenFile) - file exists + */ +HFILE WINAPI DoesFileExist(LPTSTR lpszFile, OFSTRUCT FAR* lpOpenBuf) +{ + long nRet; + int i; + static TCHAR *arrIllegalNames[] = { + TEXT("LPT1"), + TEXT("LPT2"), + TEXT("LPT3"), + TEXT("COM1"), + TEXT("COM2"), + TEXT("COM3"), + TEXT("COM4"), + TEXT("CON"), + TEXT("AUX"), + TEXT("PRN") + }; + + // Check if file name is syntactically correct. + // (OpenFile sometimes crashes if path is not syntactically correct) + nRet = ParseFile(lpszFile); + if (LOWORD(nRet) < 0) + goto error; + + // Check is the name is an illegal name (eg. the name of a device) + for (i=0; i < (sizeof(arrIllegalNames)/sizeof(arrIllegalNames[0])); i++) { + if (lstrcmpi(lpszFile, arrIllegalNames[i])==0) + goto error; // illegal name FOUND + } + + return OpenFile(lpszFile, lpOpenBuf, OF_EXIST); + +error: + _fmemset(lpOpenBuf, 0, sizeof(OFSTRUCT)); + lpOpenBuf->nErrCode = 0x0002; // File not found + return HFILE_ERROR; +} + diff --git a/private/oleutest/letest/ole2ui/utility.h b/private/oleutest/letest/ole2ui/utility.h new file mode 100644 index 000000000..10b295cd5 --- /dev/null +++ b/private/oleutest/letest/ole2ui/utility.h @@ -0,0 +1,37 @@ +/* + * UTILITY.H + * + * Miscellaneous prototypes and definitions for OLE UI dialogs. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + + +#ifndef _UTILITY_H_ +#define _UTILITY_H_ + +//Function prototypes +//UTILITY.C +HCURSOR WINAPI HourGlassOn(void); +void WINAPI HourGlassOff(HCURSOR); + +BOOL WINAPI Browse(HWND, LPTSTR, LPTSTR, UINT, UINT, DWORD); +int WINAPI ReplaceCharWithNull(LPTSTR, int); +int WINAPI ErrorWithFile(HWND, HINSTANCE, UINT, LPTSTR, UINT); +HFILE WINAPI DoesFileExist(LPTSTR lpszFile, OFSTRUCT FAR* lpOpenBuf); + + +HICON FAR PASCAL HIconAndSourceFromClass(REFCLSID, LPTSTR, UINT FAR *); +BOOL FAR PASCAL FIconFileFromClass(REFCLSID, LPTSTR, UINT, UINT FAR *); +LPTSTR FAR PASCAL PointerToNthField(LPTSTR, int, TCHAR); +BOOL FAR PASCAL GetAssociatedExecutable(LPTSTR, LPTSTR); +HICON WINAPI HIconFromClass(LPTSTR); +BOOL WINAPI FServerFromClass(LPTSTR, LPTSTR, UINT); +UINT WINAPI UClassFromDescription(LPTSTR, LPTSTR, UINT); +UINT WINAPI UDescriptionFromClass(LPTSTR, LPTSTR, UINT); +BOOL WINAPI FVerbGet(LPTSTR, UINT, LPTSTR); +LPTSTR WINAPI ChopText(HWND hwndStatic, int nWidth, LPTSTR lpch); +void WINAPI OpenFileError(HWND hDlg, UINT nErrCode, LPTSTR lpszFile); + + +#endif //_UTILITY_H_ diff --git a/private/oleutest/letest/ole2ui/verlocal.h b/private/oleutest/letest/ole2ui/verlocal.h new file mode 100644 index 000000000..92b7000c8 --- /dev/null +++ b/private/oleutest/letest/ole2ui/verlocal.h @@ -0,0 +1,54 @@ +/* + * VERLOCAL.H + * + * Version resource file for the OLE 2.0 UI Support DLL. + * + * Copyright (c)1993 Microsoft Corporation, All Rights Reserved. + * + * This file contains the text that needs to be translated in the version + * resource. All of the following variables must be localized: + * + * wLanguage + * szTranslation + * szzCompanyName + * szzProductName + * szzLegalCopyright + */ + +/* wLanguage comes from the table of "langID" values on page 218 of + the Windows 3.1 SDK Programmer's Reference, Volume 4: Resources. + This page is in Chapter 13, "Resource-Definition Statements", in the + description of the "VERSIONINFO" statment. + + For example, + 0x0407 German + 0x0409 U.S. English + 0x0809 U.K. English + 0x040C French + 0x040A Castilian Spanish +*/ +#define wLanguage 0x0409 /* U.S. English */ + +/* The first 4 characters of szTranslation must be the same as wLanguage, + without the "0x". The last 4 characters of szTranslation MUST be + 04E4. Note that any alphabetic characters in szTranslation must + be capitalized. */ +#define szTranslation "040904E4" /* U.S. English */ + + +/* The following szz strings must all end with the two characters "\0" */ +/* Note that the "\251" in szzLegalCopyright stands for the "circle c" + copyright symbol, and it should be left as \251 rather than + substituting the actual ANSI copyright character in the string. */ +#define szzCompanyName "Microsoft Corporation\0" +#define szzFileDescription "Microsoft Windows(TM) OLE 2.0 User Interface Support\0" +#define szzLegalCopyright "Copyright \251 1992-1993 Microsoft Corp. All rights reserved.\0" + +#ifdef PUBLISHER +#define szzProductName "Microsoft Publisher for Windows 2.0\0" +#else +#define szzProductName szzFileDescription +#endif + + +/* DO NOT CHANGE ANY LINES BELOW THIS POINT */ diff --git a/private/oleutest/letest/ole2ui/vgares.bmp b/private/oleutest/letest/ole2ui/vgares.bmp Binary files differnew file mode 100644 index 000000000..496902f9f --- /dev/null +++ b/private/oleutest/letest/ole2ui/vgares.bmp diff --git a/private/oleutest/letest/ole2ui/wn_dos.h b/private/oleutest/letest/ole2ui/wn_dos.h new file mode 100644 index 000000000..dbc75a643 --- /dev/null +++ b/private/oleutest/letest/ole2ui/wn_dos.h @@ -0,0 +1,174 @@ +/************************************************************************* +** +** OLE 2.0 Property Set Utilities +** +** wn_dos.h +** +** This file contains file contains data structure defintions, +** function prototypes, constants, etc. for Windows 3.x form of +** DOS calls. This is used by the SUMINFO OLE 2.0 Property Set +** utilities used to manage the Summary Info property set. +** +** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved +** +*************************************************************************/ + +#ifndef WN_DOS_H +#define WN_DOS_H + +#include <dos.h> + +#define WIN 1 + +#define cbMaxFile 146 //from inc\path.h +#define SEEK_FROM_BEGINNING 0 +#define SEEK_FROM_END 2 +#define chDOSPath ('\\') // FUTURE: not used all places it could be +#define chDOSWildAll '*' /* DOS File name wild card. */ +#define chDOSWildSingle '?' + + + +// Close, seek, delete, rename, flush, get attributes, read, write +/* RPC TEMP +int FCloseOsfnWin(WORD); +#define FCloseOsfn(osfn) FCloseOsfnWin(osfn) +long DwSeekDwWin(WORD,LONG,WORD); +#define DwSeekDw(osfn, dwSeek, bSeekFrom) DwSeekDwWin(osfn, dwSeek, bSeekFrom) +EC EcDeleteSzFfnameWin(char *); +#define EcDeleteSzFfname(szFile) EcDeleteSzFfnameWin(szFile) +EC EcRenameSzFfnameWin(char *,char *); +#define EcRenameSzFfname(szFileCur,szFileNew) EcRenameSzFfnameWin(szFileCur,szFileNew) +int FFlushOsfnWin(int); +#define FFlushOsfn(osfn) FFlushOsfnWin(osfn) +WORD DaGetFileModeSzWin(char *); +#define DaGetFileModeSz(szFile) DaGetFileModeSzWin(szFile) +int CbReadOsfnWin(int, void far *, UINT); +int CbWriteOsfnWin(int, void far *, UINT); +#define CbWriteOsfn(osfn,lpch,cbWrite) CbWriteOsfnWin(osfn,lpch,cbWrite) +*/ +#define WinOpenFile(sz,ofs,n) OpenFile(sz,ofs,n) +#define SeekHfile(f,off,kind) _llseek(f,off,kind) +#define CbReadOsfn(osfn,lpch,cbRead) CbReadOsfnWin(osfn,lpch,cbRead) +#define CbReadHfile(f,buf,n) _lread(f,buf,n) +#define CbReadOsfnWin(f,buf,n) CbReadHfile(f,buf,n) +#define EcFindFirst4dm(a,b,c) _dos_findfirst((const char *)(b),c,(struct find_t*)a) +#define EcFindNext4dm(a) _dos_findnext((struct find_t*)a) +#define FHfileToSffsDate(handle,date,time) _dos_getftime(handle, (unsigned *)(date), (unsigned *)(time)) +#define SeekHfile(f, off, kind) _llseek(f,off,kind) + +/* buffer structure to be used with EcFindFirst() and EcFindNext() */ +typedef struct _SFFS + { /* Search Find File Structure */ + uchar buff[21]; // dos search info + uchar wAttr; + union + { + unsigned short timeVariable; /*RPC47*/ + BF time:16; + struct + { + BF sec : 5; + BF mint: 6; + BF hr : 5; + }; + }; + union + { + unsigned short dateVariable; + BF date:16; + struct + { + BF dom : 5; + BF mon : 4; + BF yr : 7; + }; + }; + ulong cbFile; + uchar szFileName[13]; + } SFFS; + +// find first file/find next file +#define PszFromPsffs(psffs) ((psffs)->szFileName) +#define CopySzFilePsffs(psffs,sz) OemToAnsi((char HUGE *)&((psffs)->szFileName[0]),(char HUGE *)(sz)) +#define CbSzFilePsffs(psffs) CbSz((psffs)->szFileName) +#define CbFileSizePsffs(psffs) (psffs)->cbFile +#define AttribPsffs(psffs) (psffs)->wAttr +#define EcFindFirstCore(psffs, sz, wAttr) EcFindFirst(psffs, sz, wAttr) /*RPC22*/ +#define FDotPsffs(psffs) ((psffs)->szFileName[0]=='.') /*RPC23*/ +#define AppendSzWild(sz) {int i=_fstrlen((char FAR *)(sz)); sz[i]='*'; sz[i+1]='.'; sz[i+2]='*'; sz[i+3]='\0';} +// disk free space + +unsigned long LcbDiskFreeSpaceWin(int); +#define LcbDiskFreeSpace(chDrive) LcbDiskFreeSpaceWin(chDrive) + +// date and time /*RPC39*/ +/* +typedef struct _TIM { // Time structure returned by OsTime + CHAR minutes, hour, hsec, sec; + } TIM; + +typedef struct _DAT { // Date structure returned by OsDate + int year; + CHAR month, day, dayOfWeek; + } DAT; +*/ +#define TIM dostime_t /*RPC39*/ +#define DAT dosdate_t +#define OsTimeWin(TIM) _dos_gettime(TIM) +#define OsDateWin(DAT) _dos_getdate(DAT) + + +/* DOS File Attributes */ +#define DA_NORMAL 0x00 +#define DA_READONLY 0x01 +#define DA_HIDDEN 0x02 +#define DA_SYSTEM 0x04 +#define DA_VOLUME 0x08 +#define DA_SUBDIR 0x10 +#define DA_ARCHIVE 0x20 +#define DA_NIL 0xFFFF /* Error DA */ +#define dosxSharing 32 /* Extended error code for sharing viol. */ +#define nErrNoAcc 5 /* OpenFile error code for Access Denied */ +#define nErrFnf 2 /* OpenFile error code for File Not Found */ + +/* Components of the Open mode for OpenSzFfname (DOS FUNC 3DH) */ +#define MASK_fINH 0x80 +#define MASK_bSHARE 0x70 +#define MASK_bACCESS 0x07 + +#define bSHARE_DENYRDWR 0x10 +#define bSHARE_DENYWR 0x20 +#define bSHARE_DENYNONE 0x40 + +/* Seek-from type codes passed to DOS function 42H */ + +#define SF_BEGINNING 0 /* Seek from beginning of file */ +#define SF_CURRENT 1 /* Seek from current file pointer */ +#define SF_END 2 /* Seek from end of file */ + + +typedef struct _DOSDTTM /* DOS DaTe TiMe */ + { + union + { + long lDOSDttm; + struct + { + BF day: 5; + BF month: 4; + BF year: 7; + BF sec: 5; + BF mint: 6; + BF hours: 5; + } S1; + } U1; + } DOSDTTM; + +int FOsfnIsFile(int); + +void DateStamp(int, LONG *, int); +int DosxError(void); +int ShellExec(int, int); + +#endif //WN_DOS_H |