|
|
1.1 ! root 1: /* ! 2: * PASTESPL.C ! 3: * ! 4: * Implements the OleUIPasteSpecial function which invokes the complete ! 5: * Paste Special dialog. ! 6: * ! 7: * Copyright (c)1992 Microsoft Corporation, All Rights Reserved ! 8: */ ! 9: ! 10: #define STRICT 1 ! 11: #include "ole2ui.h" ! 12: #include "pastespl.h" ! 13: #include "common.h" ! 14: #include "utility.h" ! 15: #include "resimage.h" ! 16: #include "iconbox.h" ! 17: #include "geticon.h" ! 18: #include "regdb.h" ! 19: #include <stdlib.h> ! 20: ! 21: OLEDBGDATA ! 22: ! 23: /* ! 24: * OleUIPasteSpecial ! 25: * ! 26: * Purpose: ! 27: * Invokes the standard OLE Paste Special dialog box which allows the user ! 28: * to select the format of the clipboard object to be pasted or paste linked. ! 29: * ! 30: * Parameters: ! 31: * lpPS LPOLEUIPasteSpecial pointing to the in-out structure ! 32: * for this dialog. ! 33: * ! 34: * Return Value: ! 35: * UINT One of the following codes or one of the standard error codes (OLEUI_ERR_*) ! 36: * defined in OLE2UI.H, indicating success or error: ! 37: * OLEUI_OK User selected OK ! 38: * OLEUI_CANCEL User cancelled the dialog ! 39: * OLEUI_IOERR_SRCDATAOBJECTINVALID lpSrcDataObject field of OLEUIPASTESPECIAL invalid ! 40: * OLEUI_IOERR_ARRPASTEENTRIESINVALID arrPasteEntries field of OLEUIPASTESPECIAL invalid ! 41: * OLEUI_IOERR_ARRLINKTYPESINVALID arrLinkTypes field of OLEUIPASTESPECIAL invalid ! 42: * OLEUI_PSERR_CLIPBOARDCHANGED Clipboard contents changed while dialog was up ! 43: */ ! 44: ! 45: STDAPI_(UINT) OleUIPasteSpecial(LPOLEUIPASTESPECIAL lpPS) ! 46: { ! 47: UINT uRet; ! 48: HGLOBAL hMemDlg=NULL; ! 49: ! 50: uRet=UStandardValidation((LPOLEUISTANDARD)lpPS, sizeof(OLEUIPASTESPECIAL) ! 51: , &hMemDlg); ! 52: ! 53: if (uRet != OLEUI_SUCCESS) ! 54: return uRet; ! 55: ! 56: //Validate PasteSpecial specific fields ! 57: if (NULL == lpPS->lpSrcDataObj || IsBadReadPtr(lpPS->lpSrcDataObj, sizeof(IDataObject))) ! 58: uRet = OLEUI_IOERR_SRCDATAOBJECTINVALID; ! 59: if (NULL == lpPS->arrPasteEntries || IsBadReadPtr(lpPS->arrPasteEntries, sizeof(OLEUIPASTEENTRY))) ! 60: uRet = OLEUI_IOERR_ARRPASTEENTRIESINVALID; ! 61: if (NULL != lpPS->arrLinkTypes && IsBadReadPtr(lpPS->arrLinkTypes, sizeof(UINT))) ! 62: uRet = OLEUI_IOERR_ARRLINKTYPESINVALID; ! 63: if (uRet >= OLEUI_ERR_STANDARDMIN) ! 64: { ! 65: if (NULL != hMemDlg) ! 66: FreeResource(hMemDlg); ! 67: return uRet; ! 68: } ! 69: ! 70: //Now that we've validated everything, we can invoke the dialog. ! 71: uRet = UStandardInvocation(PasteSpecialDialogProc, (LPOLEUISTANDARD)lpPS ! 72: , hMemDlg, MAKEINTRESOURCE(IDD_PASTESPECIAL)); ! 73: ! 74: /* ! 75: * IF YOU ARE CREATING ANYTHING BASED ON THE RESULTS, DO IT HERE. ! 76: */ ! 77: ! 78: return uRet; ! 79: } ! 80: ! 81: ! 82: /* ! 83: * PasteSpecialDialogProc ! 84: * ! 85: * Purpose: ! 86: * Implements the OLE Paste Special dialog as invoked through the ! 87: * OleUIPasteSpecial function. ! 88: * ! 89: * Parameters: ! 90: * Standard ! 91: * ! 92: * Return Value: ! 93: * Standard ! 94: */ ! 95: ! 96: BOOL CALLBACK EXPORT PasteSpecialDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) ! 97: { ! 98: LPOLEUIPASTESPECIAL lpOPS; ! 99: LPPASTESPECIAL lpPS; ! 100: BOOL fHook=FALSE; ! 101: HCURSOR hCursorOld; ! 102: ! 103: //Declare Win16/Win32 compatible WM_COMMAND parameters. ! 104: COMMANDPARAMS(wID, wCode, hWndMsg); ! 105: ! 106: //This will fail under WM_INITDIALOG, where we allocate it. ! 107: lpPS=(LPPASTESPECIAL)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &fHook); ! 108: ! 109: //If the hook processed the message, we're done. ! 110: if (0!=fHook) ! 111: return fHook; ! 112: ! 113: // Process help message from Change Icon ! 114: if (iMsg == uMsgHelp) ! 115: { ! 116: PostMessage(lpPS->lpOPS->hWndOwner, uMsgHelp, wParam, lParam); ! 117: return FALSE; ! 118: } ! 119: ! 120: //Process the temination message ! 121: if (iMsg==uMsgEndDialog) ! 122: { ! 123: HWND hwndNextViewer; ! 124: ! 125: // Free the icon/icon-title metafile corresponding to Paste/PasteList option which is not selected ! 126: if (lpPS->fLink) ! 127: OleUIMetafilePictIconFree(lpPS->hMetaPictOD); ! 128: else OleUIMetafilePictIconFree(lpPS->hMetaPictLSD); ! 129: ! 130: // Free data associated with each list box entry ! 131: FreeListData(GetDlgItem(hDlg, ID_PS_PASTELIST)); ! 132: FreeListData(GetDlgItem(hDlg, ID_PS_PASTELINKLIST)); ! 133: ! 134: //Free any specific allocations before calling StandardCleanup ! 135: if (lpPS->hObjDesc) GlobalFree(lpPS->hObjDesc); ! 136: if (lpPS->hLinkSrcDesc) GlobalFree(lpPS->hLinkSrcDesc); ! 137: if (lpPS->hBuff) GlobalFree(lpPS->hBuff); ! 138: ! 139: // Change the clipboard notification chain ! 140: hwndNextViewer = GetProp(hDlg, NEXTCBVIEWER); ! 141: if (hwndNextViewer != HWND_BROADCAST) ! 142: { ! 143: SetProp(hDlg, NEXTCBVIEWER, HWND_BROADCAST); ! 144: ChangeClipboardChain(hDlg, hwndNextViewer); ! 145: } ! 146: RemoveProp(hDlg, NEXTCBVIEWER); ! 147: ! 148: StandardCleanup(lpPS, hDlg); ! 149: EndDialog(hDlg, wParam); ! 150: return TRUE; ! 151: } ! 152: ! 153: switch (iMsg) ! 154: { ! 155: case WM_INITDIALOG: ! 156: hCursorOld = HourGlassOn(); ! 157: FPasteSpecialInit(hDlg, wParam, lParam); ! 158: HourGlassOff(hCursorOld); ! 159: return TRUE; ! 160: ! 161: case WM_DRAWCLIPBOARD: ! 162: { ! 163: HWND hwndNextViewer = GetProp(hDlg, NEXTCBVIEWER); ! 164: ! 165: if (hwndNextViewer == HWND_BROADCAST) ! 166: break; ! 167: ! 168: if (hwndNextViewer) ! 169: { ! 170: SendMessage(hwndNextViewer, iMsg, wParam, lParam); ! 171: // Refresh next viewer in case it got modified ! 172: // by the SendMessage() (likely if multiple ! 173: // PasteSpecial dialogs are up simultaneously) ! 174: hwndNextViewer = GetProp(hDlg, NEXTCBVIEWER); ! 175: } ! 176: SetProp(hDlg, NEXTCBVIEWER, HWND_BROADCAST); ! 177: ChangeClipboardChain(hDlg, hwndNextViewer); ! 178: wParam = OLEUI_PSERR_CLIPBOARDCHANGED; ! 179: goto LCancel; ! 180: } ! 181: ! 182: case WM_CHANGECBCHAIN: ! 183: { ! 184: HWND hwndNextViewer = GetProp(hDlg, NEXTCBVIEWER); ! 185: ! 186: if (wParam == (WORD)hwndNextViewer) ! 187: SetProp(hDlg, NEXTCBVIEWER, (hwndNextViewer = (HWND)LOWORD(lParam))); ! 188: else if (hwndNextViewer && hwndNextViewer != HWND_BROADCAST) ! 189: SendMessage(hwndNextViewer, iMsg, wParam, lParam); ! 190: break; ! 191: } ! 192: ! 193: case WM_COMMAND: ! 194: switch (wID) ! 195: { ! 196: case ID_PS_PASTE: ! 197: FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTE); ! 198: break; ! 199: ! 200: case ID_PS_PASTELINK: ! 201: FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTELINK); ! 202: break; ! 203: ! 204: case ID_PS_DISPLAYLIST: ! 205: switch (wCode) ! 206: { ! 207: case LBN_SELCHANGE: ! 208: ChangeListSelection(hDlg, lpPS, hWndMsg); ! 209: break; ! 210: ! 211: case LBN_DBLCLK: ! 212: // Same as pressing OK ! 213: SendCommand(hDlg, IDOK, BN_CLICKED, hWndMsg); ! 214: break; ! 215: } ! 216: break; ! 217: ! 218: case ID_PS_DISPLAYASICON: ! 219: ToggleDisplayAsIcon(hDlg, lpPS); ! 220: break; ! 221: ! 222: case ID_PS_CHANGEICON: ! 223: ChangeIcon(hDlg, lpPS); ! 224: break; ! 225: ! 226: case IDOK: ! 227: lpOPS = lpPS->lpOPS; ! 228: // Return current flags ! 229: lpOPS->dwFlags = lpPS->dwFlags; ! 230: // Return index of arrPasteEntries[] corresponding to format selected by user ! 231: lpOPS->nSelectedIndex = lpPS->nSelectedIndex; ! 232: // Return if user selected Paste or PasteLink ! 233: lpOPS->fLink = lpPS->fLink; ! 234: // Return metafile with icon and icon title that the user selected ! 235: lpOPS->hMetaPict=(HGLOBAL)SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, ! 236: IBXM_IMAGEGET, 0, 0L); ! 237: SendMessage(hDlg, uMsgEndDialog, OLEUI_OK, 0L); ! 238: break; ! 239: ! 240: case IDCANCEL: ! 241: wParam = OLEUI_CANCEL; ! 242: LCancel: ! 243: // Free icon and icon title metafile ! 244: SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGEFREE, 0, 0L); ! 245: SendMessage(hDlg, uMsgEndDialog, wParam, 0L); ! 246: break; ! 247: ! 248: case ID_OLEUIHELP: ! 249: PostMessage(lpPS->lpOPS->hWndOwner, uMsgHelp, ! 250: (WPARAM)hDlg, MAKELPARAM(IDD_PASTESPECIAL, 0)); ! 251: break; ! 252: } ! 253: break; ! 254: } ! 255: return FALSE; ! 256: } ! 257: ! 258: ! 259: /* ! 260: * FPasteSpecialInit ! 261: * ! 262: * Purpose: ! 263: * WM_INITIDIALOG handler for the Paste Special dialog box. ! 264: * ! 265: * Parameters: ! 266: * hDlg HWND of the dialog ! 267: * wParam WPARAM of the message ! 268: * lParam LPARAM of the message ! 269: * ! 270: * Return Value: ! 271: * BOOL Value to return for WM_INITDIALOG. ! 272: */ ! 273: ! 274: BOOL FPasteSpecialInit(HWND hDlg, WPARAM wParam, LPARAM lParam) ! 275: { ! 276: LPPASTESPECIAL lpPS; ! 277: LPOLEUIPASTESPECIAL lpOPS; ! 278: HFONT hFont; ! 279: BOOL fPasteAvailable, fPasteLinkAvailable; ! 280: STGMEDIUM medium; ! 281: LPOBJECTDESCRIPTOR lpOD; ! 282: LPLINKSRCDESCRIPTOR lpLSD; ! 283: int n; ! 284: CLIPFORMAT cfFormat; ! 285: ! 286: // Copy the structure at lParam into our instance memory. ! 287: lpPS = (LPPASTESPECIAL)LpvStandardInit(hDlg, sizeof(PASTESPECIAL), TRUE, &hFont); ! 288: ! 289: // PvStandardInit sent a termination to us already. ! 290: if (NULL == lpPS) ! 291: return FALSE; ! 292: ! 293: lpOPS=(LPOLEUIPASTESPECIAL)lParam; ! 294: ! 295: // Copy other information from lpOPS that we might modify. ! 296: lpPS->lpOPS = lpOPS; ! 297: lpPS->dwFlags = lpOPS->dwFlags; ! 298: ! 299: // Initialize user selections in the Paste and PasteLink listboxes ! 300: lpPS->nPasteListCurSel = 0; ! 301: lpPS->nPasteLinkListCurSel = 0; ! 302: ! 303: // If we got a font, send it to the necessary controls. ! 304: if (NULL!=hFont) ! 305: { ! 306: SendDlgItemMessage(hDlg, ID_PS_SOURCETEXT, WM_SETFONT, (WPARAM)hFont, 0L); ! 307: SendDlgItemMessage(hDlg, ID_PS_RESULTTEXT, WM_SETFONT, (WPARAM)hFont, 0L); ! 308: } ! 309: ! 310: // Hide the help button if required ! 311: if (!(lpPS->lpOPS->dwFlags & PSF_SHOWHELP)) ! 312: StandardShowDlgItem(hDlg, ID_OLEUIHELP, SW_HIDE); ! 313: ! 314: // PSF_CHECKDISPLAYASICON is an OUT flag. Clear it if has been set on the way in. ! 315: lpPS->dwFlags = lpPS->dwFlags & ~PSF_CHECKDISPLAYASICON; ! 316: ! 317: // Change the caption if required ! 318: if (NULL != lpOPS->lpszCaption) ! 319: SetWindowText(hDlg, lpOPS->lpszCaption); ! 320: ! 321: // Load 'Unknown Source' and 'Unknown Type' strings ! 322: n = LoadString(ghInst, IDS_PSUNKNOWNTYPE, lpPS->szUnknownType, PS_UNKNOWNSTRLEN); ! 323: if (n) ! 324: n = LoadString(ghInst, IDS_PSUNKNOWNSRC, lpPS->szUnknownSource, PS_UNKNOWNSTRLEN); ! 325: if (!n) ! 326: { ! 327: PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L); ! 328: return FALSE; ! 329: } ! 330: lpPS->szAppName[0]='\0'; ! 331: ! 332: // GetData CF_OBJECTDESCRIPTOR. If the object on the clipboard in an OLE1 object (offering CF_OWNERLINK) ! 333: // or has been copied to clipboard by FileMaager (offering CF_FILENAME), an OBJECTDESCRIPTOR will be ! 334: // created will be created from CF_OWNERLINK or CF_FILENAME. See OBJECTDESCRIPTOR for more info. ! 335: ! 336: if (lpPS->hObjDesc = OleStdFillObjectDescriptorFromData(lpOPS->lpSrcDataObj, &medium, &cfFormat)) ! 337: { ! 338: lpOD = GlobalLock(lpPS->hObjDesc); ! 339: ! 340: // Get FullUserTypeName, SourceOfCopy and CLSID ! 341: if (lpOD->dwFullUserTypeName) ! 342: lpPS->szFullUserTypeNameOD = (LPSTR)lpOD+lpOD->dwFullUserTypeName; ! 343: else lpPS->szFullUserTypeNameOD = lpPS->szUnknownType; ! 344: ! 345: if (lpOD->dwSrcOfCopy) ! 346: { ! 347: lpPS->szSourceOfDataOD = (LPSTR)lpOD+lpOD->dwSrcOfCopy; ! 348: // If CF_FILENAME was offered, source of copy is a path name. Fit the path to the ! 349: // static control that will display it. ! 350: if (cfFormat == cfFileName) ! 351: lpPS->szSourceOfDataOD = ChopText(GetDlgItem(hDlg, ID_PS_SOURCETEXT), 0, lpPS->szSourceOfDataOD); ! 352: } ! 353: else lpPS->szSourceOfDataOD = lpPS->szUnknownSource; ! 354: ! 355: lpPS->clsidOD = lpOD->clsid; ! 356: ! 357: // Does source specify DVASPECT_ICON? ! 358: if (lpOD->dwDrawAspect & DVASPECT_ICON) ! 359: lpPS->fSrcAspectIconOD = TRUE; ! 360: else lpPS->fSrcAspectIconOD = FALSE; ! 361: ! 362: // Does source specify OLEMISC_ONLYICONIC? ! 363: if (lpOD->dwStatus & OLEMISC_ONLYICONIC) ! 364: lpPS->fSrcOnlyIconicOD = TRUE; ! 365: else lpPS->fSrcOnlyIconicOD = FALSE; ! 366: ! 367: // Get application name of source from auxusertype3 in the registration database ! 368: if (0==OleStdGetAuxUserType(&lpPS->clsidOD, 3, lpPS->szAppName, OLEUI_CCHKEYMAX, NULL)) ! 369: { ! 370: // Use "the application which created it" as the name of the application ! 371: if (0==LoadString(ghInst, IDS_PSUNKNOWNAPP, lpPS->szAppName, PS_UNKNOWNSTRLEN)) ! 372: { ! 373: PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_LOADSTRING, 0L); ! 374: return FALSE; ! 375: } ! 376: } ! 377: ! 378: // Retrieve an icon from the object ! 379: if (lpPS->fSrcAspectIconOD) ! 380: { ! 381: lpPS->hMetaPictOD = OleStdGetData( ! 382: lpOPS->lpSrcDataObj, ! 383: CF_METAFILEPICT, ! 384: NULL, ! 385: DVASPECT_ICON, ! 386: &medium ! 387: ); ! 388: ! 389: } ! 390: // If object does not offer icon, obtain it from the CLSID ! 391: if (NULL == lpPS->hMetaPictOD) ! 392: { ! 393: lpPS->hMetaPictOD = GetIconOfClass( ! 394: ghInst, ! 395: &lpPS->clsidOD, ! 396: NULL, ! 397: TRUE // Use the short user type name (auxusertype3) ! 398: ); ! 399: ! 400: ! 401: } ! 402: } ! 403: ! 404: // Does object offer CF_LINKSRCDESCRIPTOR? ! 405: if (lpPS->hLinkSrcDesc = OleStdGetData( ! 406: lpOPS->lpSrcDataObj, ! 407: cfLinkSrcDescriptor, ! 408: NULL, ! 409: DVASPECT_CONTENT, ! 410: &medium)) ! 411: { ! 412: // Get FullUserTypeName, SourceOfCopy and CLSID ! 413: lpLSD = GlobalLock(lpPS->hLinkSrcDesc); ! 414: if (lpLSD->dwFullUserTypeName) ! 415: lpPS->szFullUserTypeNameLSD = (LPSTR)lpLSD+lpLSD->dwFullUserTypeName; ! 416: else lpPS->szFullUserTypeNameLSD = lpPS->szUnknownType; ! 417: ! 418: if (lpLSD->dwSrcOfCopy) ! 419: lpPS->szSourceOfDataLSD = (LPSTR)lpLSD+lpLSD->dwSrcOfCopy; ! 420: else lpPS->szSourceOfDataLSD = lpPS->szUnknownSource; ! 421: ! 422: lpPS->clsidLSD = lpLSD->clsid; ! 423: ! 424: // Does source specify DVASPECT_ICON? ! 425: if (lpOD->dwDrawAspect & DVASPECT_ICON) ! 426: lpPS->fSrcAspectIconLSD = TRUE; ! 427: else lpPS->fSrcAspectIconLSD = FALSE; ! 428: ! 429: // Does source specify OLEMISC_ONLYICONIC? ! 430: if (lpLSD->dwStatus & OLEMISC_ONLYICONIC) ! 431: lpPS->fSrcOnlyIconicLSD = TRUE; ! 432: else lpPS->fSrcOnlyIconicLSD = FALSE; ! 433: ! 434: // Retrieve an icon from the object ! 435: if (lpPS->fSrcAspectIconLSD) ! 436: { ! 437: lpPS->hMetaPictLSD = OleStdGetData( ! 438: lpOPS->lpSrcDataObj, ! 439: CF_METAFILEPICT, ! 440: NULL, ! 441: DVASPECT_ICON, ! 442: &medium ! 443: ); ! 444: ! 445: } ! 446: // If object does not offer icon, obtain it from the CLSID ! 447: if (NULL == lpPS->hMetaPictLSD) ! 448: { ! 449: char szLabel[OLEUI_CCHLABELMAX]; ! 450: HWND hIconWnd; ! 451: RECT IconRect; ! 452: int nWidth; ! 453: LPSTR lpszLabel; ! 454: ! 455: hIconWnd = GetDlgItem(hDlg, ID_PS_ICONDISPLAY); ! 456: ! 457: GetClientRect(hIconWnd, &IconRect); ! 458: ! 459: nWidth = (IconRect.right * 3) / 2; // width is 1.5 times width of iconbox ! 460: ! 461: lstrcpyn(szLabel, lpPS->szSourceOfDataLSD, sizeof(szLabel)); ! 462: szLabel[sizeof(szLabel)-1] = '\0'; ! 463: ! 464: lpszLabel = ChopText(hIconWnd, nWidth, (LPSTR)szLabel); ! 465: ! 466: lpPS->hMetaPictLSD = GetIconOfClass( ! 467: ghInst, ! 468: &lpPS->clsidLSD, ! 469: lpszLabel, // use chopped source string as label ! 470: FALSE // not applicable ! 471: ); ! 472: } ! 473: } ! 474: else if (lpPS->hObjDesc) // Does not offer CF_LINKSRCDESCRIPTOR but offers CF_OBJECTDESCRIPTOR ! 475: { ! 476: // Copy the values of OBJECTDESCRIPTOR ! 477: lpPS->szFullUserTypeNameLSD = lpPS->szFullUserTypeNameOD; ! 478: lpPS->szSourceOfDataLSD = lpPS->szSourceOfDataOD; ! 479: lpPS->clsidLSD = lpPS->clsidOD; ! 480: lpPS->fSrcAspectIconLSD = lpPS->fSrcAspectIconOD; ! 481: lpPS->fSrcOnlyIconicLSD = lpPS->fSrcOnlyIconicOD; ! 482: ! 483: // Don't copy the hMetaPict; instead get a separate copy ! 484: if (lpPS->fSrcAspectIconLSD) ! 485: { ! 486: lpPS->hMetaPictLSD = OleStdGetData( ! 487: lpOPS->lpSrcDataObj, ! 488: CF_METAFILEPICT, ! 489: NULL, ! 490: DVASPECT_ICON, ! 491: &medium ! 492: ); ! 493: } ! 494: if (NULL == lpPS->hMetaPictLSD) ! 495: { ! 496: char szLabel[OLEUI_CCHLABELMAX]; ! 497: HWND hIconWnd; ! 498: RECT IconRect; ! 499: int nWidth; ! 500: LPSTR lpszLabel; ! 501: ! 502: hIconWnd = GetDlgItem(hDlg, ID_PS_ICONDISPLAY); ! 503: ! 504: GetClientRect(hIconWnd, &IconRect); ! 505: ! 506: nWidth = (IconRect.right * 3) / 2; // width is 1.5 times width of iconbox ! 507: ! 508: lstrcpyn(szLabel, lpPS->szSourceOfDataLSD, sizeof(szLabel)); ! 509: szLabel[sizeof(szLabel)-1] = '\0'; ! 510: ! 511: lpszLabel = ChopText(hIconWnd, nWidth, (LPSTR)szLabel); ! 512: ! 513: lpPS->hMetaPictLSD = GetIconOfClass( ! 514: ghInst, ! 515: &lpPS->clsidLSD, ! 516: lpszLabel, // Use chopped source string as label ! 517: FALSE // Not applicable ! 518: ); ! 519: } ! 520: } ! 521: ! 522: // Not an OLE object ! 523: if (lpPS->hObjDesc == NULL && lpPS->hLinkSrcDesc == NULL) ! 524: { ! 525: lpPS->szFullUserTypeNameLSD = lpPS->szFullUserTypeNameOD = lpPS->szUnknownType; ! 526: lpPS->szSourceOfDataLSD = lpPS->szSourceOfDataOD = lpPS->szUnknownSource; ! 527: lpPS->hMetaPictLSD = lpPS->hMetaPictOD = NULL; ! 528: } ! 529: ! 530: // Allocate scratch memory to construct item names in the paste and pastelink listboxes ! 531: lpPS->hBuff = AllocateScratchMem(lpPS); ! 532: if (lpPS->hBuff == NULL) ! 533: { ! 534: PostMessage(hDlg, uMsgEndDialog, OLEUI_ERR_GLOBALMEMALLOC, 0L); ! 535: return FALSE; ! 536: } ! 537: ! 538: // Select the Paste Link Button if specified. Otherwise select ! 539: // Paste Button by default ! 540: if (lpPS->dwFlags & PSF_SELECTPASTELINK) ! 541: lpPS->dwFlags = (lpPS->dwFlags & ~PSF_SELECTPASTE) | PSF_SELECTPASTELINK; ! 542: else ! 543: lpPS->dwFlags =(lpPS->dwFlags & ~PSF_SELECTPASTELINK) | PSF_SELECTPASTE; ! 544: ! 545: // Mark which PasteEntry formats are available from source data object ! 546: OleStdMarkPasteEntryList( ! 547: lpOPS->lpSrcDataObj,lpOPS->arrPasteEntries,lpOPS->cPasteEntries); ! 548: ! 549: // Check if items are available to be pasted ! 550: fPasteAvailable = FFillPasteList(hDlg, lpPS); ! 551: if (!fPasteAvailable) ! 552: { ! 553: lpPS->dwFlags &= ~PSF_SELECTPASTE; ! 554: EnableWindow(GetDlgItem(hDlg, ID_PS_PASTE), FALSE); ! 555: } ! 556: ! 557: // Check if items are available to be paste-linked ! 558: fPasteLinkAvailable = FFillPasteLinkList(hDlg, lpPS); ! 559: if (!fPasteLinkAvailable) ! 560: { ! 561: lpPS->dwFlags &= ~PSF_SELECTPASTELINK; ! 562: EnableWindow(GetDlgItem(hDlg, ID_PS_PASTELINK), FALSE); ! 563: } ! 564: ! 565: // If one of Paste or PasteLink is disabled, select the other one regardless of what ! 566: // the input flags say ! 567: if (fPasteAvailable && !fPasteLinkAvailable) ! 568: lpPS->dwFlags |= PSF_SELECTPASTE; ! 569: if (fPasteLinkAvailable && !fPasteAvailable) ! 570: lpPS->dwFlags |= PSF_SELECTPASTELINK; ! 571: ! 572: if (lpPS->dwFlags & PSF_SELECTPASTE) ! 573: { ! 574: // FTogglePaste will set the PSF_SELECTPASTE flag, so clear it. ! 575: lpPS->dwFlags &= ~PSF_SELECTPASTE; ! 576: CheckRadioButton(hDlg, ID_PS_PASTE, ID_PS_PASTELINK, ID_PS_PASTE); ! 577: FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTE); ! 578: } ! 579: else if (lpPS->dwFlags & PSF_SELECTPASTELINK) ! 580: { ! 581: // FTogglePaste will set the PSF_SELECTPASTELINK flag, so clear it. ! 582: lpPS->dwFlags &= ~PSF_SELECTPASTELINK; ! 583: CheckRadioButton(hDlg, ID_PS_PASTE, ID_PS_PASTELINK, ID_PS_PASTELINK); ! 584: FTogglePasteType(hDlg, lpPS, PSF_SELECTPASTELINK); ! 585: } ! 586: else // Items are not available to be be Pasted or Paste-Linked ! 587: { ! 588: // Enable or disable DisplayAsIcon and set the result text and image ! 589: EnableDisplayAsIcon(hDlg, lpPS); ! 590: SetPasteSpecialHelpResults(hDlg, lpPS); ! 591: } ! 592: ! 593: // Set property to handle clipboard change notifications ! 594: SetProp(hDlg, NEXTCBVIEWER, HWND_BROADCAST); ! 595: SetProp(hDlg, NEXTCBVIEWER, SetClipboardViewer(hDlg)); ! 596: ! 597: /* ! 598: * PERFORM OTHER INITIALIZATION HERE. ! 599: */ ! 600: ! 601: // Call the hook with lCustData in lParam ! 602: UStandardHook(lpPS, hDlg, WM_INITDIALOG, wParam, lpOPS->lCustData); ! 603: return TRUE; ! 604: } ! 605: ! 606: /* ! 607: * FTogglePasteType ! 608: * ! 609: * Purpose: ! 610: * Toggles between Paste and Paste Link. The Paste list and PasteLink ! 611: * list are always invisible. The Display List is filled from either ! 612: * the Paste list or the PasteLink list depending on which Paste radio ! 613: * button is selected. ! 614: * ! 615: * Parameters: ! 616: * hDlg HWND of the dialog ! 617: * lpPS Paste Special Dialog Structure ! 618: * dwOption Paste or PasteSpecial option ! 619: * ! 620: * Return Value: ! 621: * BOOL Returns TRUE if the option has already been selected. ! 622: * Otherwise the option is selected and FALSE is returned ! 623: */ ! 624: ! 625: BOOL FTogglePasteType(HWND hDlg, LPPASTESPECIAL lpPS, DWORD dwOption) ! 626: { ! 627: DWORD dwTemp; ! 628: HWND hList, hListDisplay; ! 629: DWORD dwData; ! 630: int i, nItems; ! 631: LPSTR lpsz; ! 632: ! 633: // Skip all this if the button is already selected ! 634: if (lpPS->dwFlags & dwOption) ! 635: return TRUE; ! 636: ! 637: dwTemp = PSF_SELECTPASTE | PSF_SELECTPASTELINK; ! 638: lpPS->dwFlags = (lpPS->dwFlags & ~dwTemp) | dwOption; ! 639: ! 640: // Hide IconDisplay. This prevents flashing if the icon display is changed ! 641: StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); ! 642: ! 643: hListDisplay = GetDlgItem(hDlg, ID_PS_DISPLAYLIST); ! 644: ! 645: // If Paste was selected ! 646: if (lpPS->dwFlags & PSF_SELECTPASTE) ! 647: { ! 648: // Set the Source of the object in the clipboard ! 649: SetDlgItemText(hDlg, ID_PS_SOURCETEXT, lpPS->szSourceOfDataOD); ! 650: ! 651: // If an icon is available ! 652: if (lpPS->hMetaPictOD) ! 653: // Set the icon display ! 654: SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGESET, ! 655: (WPARAM)lpPS->hMetaPictOD, 0L); ! 656: ! 657: ! 658: hList = GetDlgItem(hDlg, ID_PS_PASTELIST); ! 659: // We are switching from PasteLink to Paste. Remember current selection ! 660: // in PasteLink list so it can be restored. ! 661: lpPS->nPasteLinkListCurSel = (int)SendMessage(hListDisplay, LB_GETCURSEL, 0, 0L); ! 662: if (lpPS->nPasteLinkListCurSel == LB_ERR) ! 663: lpPS->nPasteLinkListCurSel = 0; ! 664: // Remember if user selected Paste or PasteLink ! 665: lpPS->fLink = FALSE; ! 666: } ! 667: else // If PasteLink was selected ! 668: { ! 669: // Set the Source of the object in the clipboard ! 670: SetDlgItemText(hDlg, ID_PS_SOURCETEXT, lpPS->szSourceOfDataLSD); ! 671: ! 672: // If an icon is available ! 673: if (lpPS->hMetaPictLSD) ! 674: // Set the icon display ! 675: SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGESET, ! 676: (WPARAM)lpPS->hMetaPictLSD, 0L); ! 677: ! 678: ! 679: hList = GetDlgItem(hDlg, ID_PS_PASTELINKLIST); ! 680: // We are switching from Paste to PasteLink. Remember current selection ! 681: // in Paste list so it can be restored. ! 682: lpPS->nPasteListCurSel = (int)SendMessage(hListDisplay, LB_GETCURSEL, 0, 0L); ! 683: if (lpPS->nPasteListCurSel == LB_ERR) ! 684: lpPS->nPasteListCurSel = 0; ! 685: // Remember if user selected Paste or PasteLink ! 686: lpPS->fLink = TRUE; ! 687: } ! 688: ! 689: // Turn drawing off while the Display List is being filled ! 690: SendMessage(hListDisplay, WM_SETREDRAW, (WPARAM)FALSE, 0L); ! 691: ! 692: // Move data to Display list box ! 693: SendMessage(hListDisplay, LB_RESETCONTENT, 0, 0L); ! 694: nItems = (int) SendMessage(hList, LB_GETCOUNT, 0, 0L); ! 695: lpsz = (LPSTR)GlobalLock(lpPS->hBuff); ! 696: for (i = 0; i < nItems; i++) ! 697: { ! 698: SendMessage(hList, LB_GETTEXT, (WPARAM)i, (LPARAM)lpsz); ! 699: dwData = SendMessage(hList, LB_GETITEMDATA, (WPARAM)i, 0L); ! 700: SendMessage(hListDisplay, LB_INSERTSTRING, (WPARAM)i, (LPARAM)lpsz); ! 701: SendMessage(hListDisplay, LB_SETITEMDATA, (WPARAM)i, dwData); ! 702: } ! 703: GlobalUnlock(lpPS->hBuff); ! 704: ! 705: // Restore the selection in the Display List from user's last selection ! 706: if (lpPS->dwFlags & PSF_SELECTPASTE) ! 707: SendMessage(hListDisplay, LB_SETCURSEL, lpPS->nPasteListCurSel, 0L); ! 708: else ! 709: SendMessage(hListDisplay, LB_SETCURSEL, lpPS->nPasteLinkListCurSel, 0L); ! 710: ! 711: // Paint Display List ! 712: SendMessage(hListDisplay, WM_SETREDRAW, (WPARAM)TRUE, 0L); ! 713: InvalidateRect(hListDisplay, NULL, TRUE); ! 714: UpdateWindow(hListDisplay); ! 715: ! 716: // Enable/Disable DisplayAsIcon and set the help result text and bitmap corresponding to ! 717: // the current selection ! 718: ChangeListSelection(hDlg, lpPS, hListDisplay); ! 719: ! 720: return FALSE; ! 721: } ! 722: ! 723: ! 724: /* ! 725: * ChangeListSelection ! 726: * ! 727: * Purpose: ! 728: * When the user changes the selection in the list, DisplayAsIcon is enabled or disabled, ! 729: * Result text and bitmap are updated and the index of the arrPasteEntries[] corresponding ! 730: * to the current format selection is saved. ! 731: * ! 732: * Parameters: ! 733: * hDlg HWND of the dialog ! 734: * lpPS Paste Special Dialog Structure ! 735: * hList HWND of the List ! 736: * ! 737: * Return Value: ! 738: * No return value ! 739: */ ! 740: ! 741: void ChangeListSelection(HWND hDlg, LPPASTESPECIAL lpPS, HWND hList) ! 742: { ! 743: LPPASTELISTITEMDATA lpItemData; ! 744: int nCurSel; ! 745: ! 746: EnableDisplayAsIcon(hDlg, lpPS); ! 747: SetPasteSpecialHelpResults(hDlg, lpPS); ! 748: ! 749: // Remember index of arrPasteEntries[] corresponding to the current selection ! 750: nCurSel = (int)SendMessage(hList, LB_GETCURSEL, 0, 0L); ! 751: if (nCurSel == LB_ERR) return; ! 752: lpItemData = (LPPASTELISTITEMDATA) SendMessage(hList, LB_GETITEMDATA, ! 753: (WPARAM)nCurSel, 0L); ! 754: if ((LRESULT)lpItemData == LB_ERR) return; ! 755: lpPS->nSelectedIndex = lpItemData->nPasteEntriesIndex; ! 756: } ! 757: ! 758: /* ! 759: * EnableDisplayAsIcon ! 760: * ! 761: * Purpose: ! 762: * Enable or disable the DisplayAsIcon button depending on whether ! 763: * the current selection can be displayed as an icon or not. The following table describes ! 764: * the state of DisplayAsIcon. The calling application is termed CONTAINER, the source ! 765: * of data on the clipboard is termed SOURCE. ! 766: * Y = Yes; N = No; Blank = State does not matter; ! 767: * ===================================================================== ! 768: * SOURCE SOURCE CONTAINER DisplayAsIcon ! 769: * specifies specifies specifies Initial State ! 770: * DVASPECT_ICON OLEMISC_ONLYICONIC OLEUIPASTE_ENABLEICON ! 771: * ! 772: * N Unchecked&Disabled ! 773: * Y Y Checked&Disabled ! 774: * Y N Y Checked&Enabled ! 775: * N N Y Unchecked&Enabled ! 776: * ===================================================================== ! 777: * ! 778: * Parameters: ! 779: * hDlg HWND of the dialog ! 780: * lpPS Paste Special Dialog Structure ! 781: * ! 782: * Return Value: ! 783: * No return value ! 784: */ ! 785: ! 786: void EnableDisplayAsIcon(HWND hDlg, LPPASTESPECIAL lpPS) ! 787: { ! 788: int nIndex; ! 789: BOOL fCntrEnableIcon; ! 790: BOOL fSrcOnlyIconic = (lpPS->fLink) ? lpPS->fSrcOnlyIconicLSD : lpPS->fSrcOnlyIconicOD; ! 791: BOOL fSrcAspectIcon = (lpPS->fLink) ? lpPS->fSrcAspectIconLSD : lpPS->fSrcAspectIconOD; ! 792: HWND hList; ! 793: LPPASTELISTITEMDATA lpItemData; ! 794: HGLOBAL hMetaPict = (lpPS->fLink) ? lpPS->hMetaPictLSD : lpPS->hMetaPictOD; ! 795: ! 796: hList = GetDlgItem(hDlg, ID_PS_DISPLAYLIST); ! 797: ! 798: // Get data corresponding to the current selection in the listbox ! 799: nIndex = (int)SendMessage(hList, LB_GETCURSEL, 0, 0); ! 800: if (nIndex != LB_ERR) ! 801: { ! 802: lpItemData = (LPPASTELISTITEMDATA) SendMessage(hList, LB_GETITEMDATA, (WPARAM)nIndex, 0L); ! 803: if ((LRESULT)lpItemData != LB_ERR) ! 804: fCntrEnableIcon = lpItemData->fCntrEnableIcon; ! 805: else fCntrEnableIcon = FALSE; ! 806: } ! 807: else fCntrEnableIcon = FALSE; ! 808: ! 809: // If there is an icon available ! 810: if (hMetaPict != NULL) ! 811: { ! 812: if (!fCntrEnableIcon) // Does CONTAINER specify OLEUIPASTE_ENABLEICON? ! 813: { ! 814: // Uncheck & Disable DisplayAsIcon ! 815: lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON; ! 816: CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, FALSE); ! 817: EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), FALSE); ! 818: ! 819: // Hide IconDisplay and ChangeIcon button ! 820: StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); ! 821: StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_HIDE); ! 822: } ! 823: else if (fSrcOnlyIconic) // Does SOURCE specify OLEMISC_ONLYICONIC? ! 824: { ! 825: // Check & Disable DisplayAsIcon ! 826: lpPS->dwFlags |= PSF_CHECKDISPLAYASICON; ! 827: CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, TRUE); ! 828: EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), FALSE); ! 829: ! 830: // Show IconDisplay and ChangeIcon button ! 831: StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_SHOWNORMAL); ! 832: StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_SHOWNORMAL); ! 833: } ! 834: else if (fSrcAspectIcon) // Does SOURCE specify DVASPECT_ICON? ! 835: { ! 836: // Check & Enable DisplayAsIcon ! 837: lpPS->dwFlags |= PSF_CHECKDISPLAYASICON; ! 838: CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, TRUE); ! 839: EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), TRUE); ! 840: ! 841: // Show IconDisplay and ChangeIcon button ! 842: StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_SHOWNORMAL); ! 843: StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_SHOWNORMAL); ! 844: } ! 845: else ! 846: { ! 847: //Uncheck and Enable DisplayAsIcon ! 848: lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON; ! 849: CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, FALSE); ! 850: EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), TRUE); ! 851: ! 852: // Hide IconDisplay and ChangeIcon button ! 853: StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); ! 854: StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_HIDE); ! 855: ! 856: } ! 857: } ! 858: else // No icon available ! 859: { ! 860: // Unchecked & Disabled ! 861: lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON; ! 862: CheckDlgButton(hDlg, ID_PS_DISPLAYASICON, FALSE); ! 863: EnableWindow(GetDlgItem(hDlg, ID_PS_DISPLAYASICON), FALSE); ! 864: ! 865: // Hide IconDisplay and ChangeIcon button ! 866: StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, SW_HIDE); ! 867: StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, SW_HIDE); ! 868: } ! 869: } ! 870: ! 871: /* ! 872: * ToggleDisplayAsIcon ! 873: * ! 874: * Purpose: ! 875: * Toggles the DisplayAsIcon button. Hides or shows the Icon Display and ! 876: * the ChangeIcon button and changes the help result text and bitmap. ! 877: * ! 878: * Parameters: ! 879: * hDlg HWND of the dialog ! 880: * lpPS Paste Special Dialog Structure ! 881: * ! 882: * Return Value: ! 883: * None ! 884: * ! 885: */ ! 886: ! 887: void ToggleDisplayAsIcon(HWND hDlg, LPPASTESPECIAL lpPS) ! 888: { ! 889: BOOL fCheck; ! 890: int i; ! 891: ! 892: fCheck = IsDlgButtonChecked(hDlg, ID_PS_DISPLAYASICON); ! 893: ! 894: if (fCheck) ! 895: lpPS->dwFlags |= PSF_CHECKDISPLAYASICON; ! 896: else lpPS->dwFlags &= ~PSF_CHECKDISPLAYASICON; ! 897: ! 898: // Set the help result text and bitmap ! 899: SetPasteSpecialHelpResults(hDlg, lpPS); ! 900: ! 901: // Show or hide the Icon Display and ChangeIcon button depending ! 902: // on the check state ! 903: i = (fCheck) ? SW_SHOWNORMAL : SW_HIDE; ! 904: StandardShowDlgItem(hDlg, ID_PS_ICONDISPLAY, i); ! 905: StandardShowDlgItem(hDlg, ID_PS_CHANGEICON, i); ! 906: } ! 907: ! 908: /* ! 909: * ChangeIcon ! 910: * ! 911: * Purpose: ! 912: * Brings up the ChangeIcon dialog which allows the user to change ! 913: * the icon and label. ! 914: * ! 915: * Parameters: ! 916: * hDlg HWND of the dialog ! 917: * lpPS Paste Special Dialog Structure ! 918: * ! 919: * Return Value: ! 920: * None ! 921: * ! 922: */ ! 923: ! 924: void ChangeIcon(HWND hDlg, LPPASTESPECIAL lpPS) ! 925: { ! 926: OLEUICHANGEICON ci; ! 927: UINT uRet; ! 928: CLSID clsid = (lpPS->fLink) ? lpPS->clsidLSD : lpPS->clsidOD; ! 929: ! 930: //Initialize the structure ! 931: _fmemset((LPOLEUICHANGEICON)&ci, 0, sizeof(ci)); ! 932: ! 933: ci.hMetaPict = (HGLOBAL)SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGEGET, 0, 0L); ! 934: ci.cbStruct = sizeof(ci); ! 935: ci.hWndOwner = hDlg; ! 936: ci.clsid = clsid; ! 937: ci.dwFlags = CIF_SELECTCURRENT; ! 938: ! 939: // Only show help in the ChangeIcon dialog if we're showing it in this dialog. ! 940: if (lpPS->dwFlags & PSF_SHOWHELP) ! 941: ci.dwFlags = CIF_SHOWHELP; ! 942: ! 943: // Let the hook in to customize Change Icon if desired. ! 944: uRet = UStandardHook(lpPS, hDlg, uMsgChangeIcon, 0, (LONG)(LPSTR)&ci); ! 945: ! 946: if (0 == uRet) ! 947: uRet=(UINT)(OLEUI_OK==OleUIChangeIcon(&ci)); ! 948: ! 949: // Update the display if necessary. ! 950: if (0!=uRet) ! 951: { ! 952: /* ! 953: * OleUIChangeIcon will have already freed our ! 954: * current hMetaPict that we passed in when OK is ! 955: * pressed in that dialog. So we use 0L as lParam ! 956: * here so the IconBox doesn't try to free the ! 957: * metafilepict again. ! 958: */ ! 959: SendDlgItemMessage(hDlg, ID_PS_ICONDISPLAY, IBXM_IMAGESET, (WPARAM)ci.hMetaPict, 0L); ! 960: // Remember the new icon chosen by the user. Note that Paste and PasteLink have separate ! 961: // icons - changing one does not change the other. ! 962: if (lpPS->fLink) ! 963: lpPS->hMetaPictLSD = ci.hMetaPict; ! 964: else lpPS->hMetaPictOD = ci.hMetaPict; ! 965: } ! 966: } ! 967: ! 968: /* ! 969: *SetPasteSpecialHelpResults ! 970: * ! 971: * Purpose: ! 972: * Sets the help result text and bitmap according to the current ! 973: * list selection. The following state table indicates which ResultText ! 974: * and ResultImage are selected. If %s in the lpstrFormatName is present, ! 975: * it is assumed that an object is being pasted/paste-linked, otherwise it ! 976: * is assumed that data is being pasted/paste-linked. ! 977: * Y = Yes; N = No; Blank = State does not matter; ! 978: * The numbers in the the ResultText and ResultImage columns refer to the table ! 979: * entries that follow. ! 980: * ===================================================================== ! 981: * Paste/ lpstrFormatName in DisplayAsIcon Result Result ! 982: * PasteLink arrPasteEntry[]contains %s checked Text Image ! 983: * (Is Object == Y, Is Data == N) ! 984: * Paste N 1 1 ! 985: * Paste Y N 2 2 ! 986: * Paste Y Y 3 3 ! 987: * PasteLink N 4 4 ! 988: * PasteLink Y N 5 4 ! 989: * PasteLink Y Y 6 5 ! 990: * ===================================================================== ! 991: * Result Text: ! 992: * ! 993: * 1. "Inserts the contents of the Clipboard into your document as <native type name, ! 994: * and optionally an additional help sentence>" ! 995: * 2. "Inserts the contents of the Clipboard into your document so that you may ! 996: * activate it using <object app name>" ! 997: * 3. "Inserts the contents of the Clipboard into your document so that you may ! 998: * activate it using <object app name>. It will be displayed as an icon." ! 999: * 4. "Inserts the contents of the Clipboard into your document as <native type name>. ! 1000: * Paste Link creates a link to the source file so that changes to the source file ! 1001: * will be reflected in your document." ! 1002: * 5. "Inserts a picture of the Clipboard contents into your document. Paste Link ! 1003: * creates a link to the source file so that changes to the source file will be ! 1004: * reflected in your document." ! 1005: * 6. "Inserts an icon into your document which represents the Clipboard contents. ! 1006: * Paste Link creates a link to the source file so that changes to the source file ! 1007: * will be reflected in your document." ! 1008: * ===================================================================== ! 1009: * Result Image: ! 1010: * ! 1011: * 1. Clipboard Image ! 1012: * 2. Paste image, non-iconic. ! 1013: * 3. Paste image, iconic. ! 1014: * 4. Paste Link image, non-iconic ! 1015: * 5. Paste Link image, iconic ! 1016: * ==================================================================== ! 1017: * ! 1018: * Parameters: ! 1019: * hDlg HWND of the dialog ! 1020: * lpPS Paste Special Dialog Structure ! 1021: * ! 1022: * Return Value: ! 1023: * No return value ! 1024: */ ! 1025: void SetPasteSpecialHelpResults(HWND hDlg, LPPASTESPECIAL lpPS) ! 1026: { ! 1027: LPSTR psz1, psz2, psz3, psz4; ! 1028: UINT i, iString, iImage, cch; ! 1029: int nPasteEntriesIndex; ! 1030: BOOL fDisplayAsIcon; ! 1031: BOOL fIsObject; ! 1032: HWND hList; ! 1033: LPPASTELISTITEMDATA lpItemData; ! 1034: LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS; ! 1035: LPSTR szFullUserTypeName = (lpPS->fLink) ? lpPS->szFullUserTypeNameLSD : lpPS->szFullUserTypeNameOD; ! 1036: LPSTR szInsert; ! 1037: ! 1038: hList = GetDlgItem(hDlg, ID_PS_DISPLAYLIST); ! 1039: ! 1040: i=(UINT)SendMessage(hList, LB_GETCURSEL, 0, 0L); ! 1041: if (i != LB_ERR) ! 1042: { ! 1043: lpItemData = (LPPASTELISTITEMDATA)SendMessage(hList, LB_GETITEMDATA, i, 0L); ! 1044: if ((LRESULT)lpItemData == LB_ERR) return; ! 1045: nPasteEntriesIndex = lpItemData->nPasteEntriesIndex; ! 1046: // Check if there is a '%s' in the lpstrFormatName, then an object is being ! 1047: // pasted/pastelinked. Otherwise Data is being pasted-pastelinked. ! 1048: fIsObject = FHasPercentS(lpOPS->arrPasteEntries[nPasteEntriesIndex].lpstrFormatName, ! 1049: lpPS); ! 1050: } ! 1051: else return; ! 1052: ! 1053: // Is DisplayAsIcon checked? ! 1054: fDisplayAsIcon=(0L!=(lpPS->dwFlags & PSF_CHECKDISPLAYASICON)); ! 1055: ! 1056: szInsert = szFullUserTypeName; ! 1057: ! 1058: if (lpPS->dwFlags & PSF_SELECTPASTE) // If user selected Paste ! 1059: { ! 1060: if (fIsObject) ! 1061: { ! 1062: iString = fDisplayAsIcon ? IDS_PSPASTEOBJECTASICON : IDS_PSPASTEOBJECT; ! 1063: iImage = fDisplayAsIcon ? RESULTIMAGE_EMBEDICON : RESULTIMAGE_EMBED; ! 1064: szInsert = lpPS->szAppName; ! 1065: } ! 1066: else ! 1067: { ! 1068: iString = IDS_PSPASTEDATA; ! 1069: iImage = RESULTIMAGE_PASTE; ! 1070: } ! 1071: } ! 1072: else if (lpPS->dwFlags & PSF_SELECTPASTELINK) // User selected PasteLink ! 1073: { ! 1074: if (fIsObject) ! 1075: { ! 1076: iString = fDisplayAsIcon ? IDS_PSPASTELINKOBJECTASICON : IDS_PSPASTELINKOBJECT; ! 1077: iImage = fDisplayAsIcon ? RESULTIMAGE_LINKICON : RESULTIMAGE_LINK; ! 1078: } ! 1079: else ! 1080: { ! 1081: iString = IDS_PSPASTELINKDATA; ! 1082: iImage = RESULTIMAGE_LINK; ! 1083: } ! 1084: ! 1085: } ! 1086: else // Should never occur. ! 1087: { ! 1088: iString = IDS_PSNONOLE; ! 1089: iImage = RESULTIMAGE_PASTE; ! 1090: } ! 1091: ! 1092: // hBuff contains enough space for the 4 buffers required to build up the help ! 1093: // result text. ! 1094: cch = (UINT)GlobalSize(lpPS->hBuff)/4; ! 1095: ! 1096: psz1=(LPSTR)GlobalLock(lpPS->hBuff); ! 1097: psz2=psz1+cch; ! 1098: psz3=psz2+cch; ! 1099: psz4=psz3+cch; ! 1100: ! 1101: // Default is an empty string. ! 1102: *psz1=0; ! 1103: ! 1104: if (0!=LoadString(ghInst, iString, psz1, cch)) ! 1105: { ! 1106: // Insert the FullUserTypeName of the source object into the partial result text ! 1107: // specified by the container. ! 1108: wsprintf(psz3, lpOPS->arrPasteEntries[nPasteEntriesIndex].lpstrResultText, ! 1109: (LPSTR)szInsert); ! 1110: // Insert the above partial result text into the standard result text. ! 1111: wsprintf(psz4, psz1, (LPSTR)psz3); ! 1112: psz1=psz4; ! 1113: } ! 1114: ! 1115: // If LoadString failed, we simply clear out the results (*psz1=0 above) ! 1116: SetDlgItemText(hDlg, ID_PS_RESULTTEXT, psz1); ! 1117: ! 1118: // Change the result bitmap ! 1119: SendDlgItemMessage(hDlg, ID_PS_RESULTIMAGE, RIM_IMAGESET, iImage, 0L); ! 1120: ! 1121: GlobalUnlock(lpPS->hBuff); ! 1122: } ! 1123: ! 1124: /* ! 1125: * FAddPasteListItem ! 1126: * ! 1127: * Purpose: ! 1128: * Adds an item to the list box ! 1129: * ! 1130: * Parameters: ! 1131: * hList HWND List into which item is to be added ! 1132: * fInsertFirst BOOL Insert in the beginning of the list? ! 1133: * nPasteEntriesIndex int Index of Paste Entry array this list item corresponsds to ! 1134: * lpPS Paste Special Dialog Structure ! 1135: * pIMalloc LPMALLOC Memory Allocator ! 1136: * lpszBuf LPSTR Scratch buffer to build up string for list entry ! 1137: * ! 1138: * Return Value: ! 1139: * BOOL TRUE if sucessful. ! 1140: * FALSE if unsucessful. ! 1141: */ ! 1142: BOOL FAddPasteListItem( ! 1143: HWND hList, BOOL fInsertFirst, int nPasteEntriesIndex, LPPASTESPECIAL lpPS, ! 1144: LPMALLOC pIMalloc, LPSTR lpszBuf) ! 1145: { ! 1146: LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS; ! 1147: LPPASTELISTITEMDATA lpItemData; ! 1148: int nIndex; ! 1149: LPSTR szFullUserTypeName = (lpPS->fLink) ? ! 1150: lpPS->szFullUserTypeNameLSD : lpPS->szFullUserTypeNameOD; ! 1151: ! 1152: // Allocate memory for each list box item ! 1153: lpItemData = (LPPASTELISTITEMDATA)pIMalloc->lpVtbl->Alloc( ! 1154: pIMalloc, (DWORD)sizeof(PASTELISTITEMDATA)); ! 1155: if (NULL == lpItemData) ! 1156: return FALSE; ! 1157: ! 1158: // Fill data associated with each list box item ! 1159: lpItemData->nPasteEntriesIndex = nPasteEntriesIndex; ! 1160: lpItemData->fCntrEnableIcon = ((lpOPS->arrPasteEntries[nPasteEntriesIndex].dwFlags & ! 1161: OLEUIPASTE_ENABLEICON) ? TRUE : FALSE); ! 1162: ! 1163: // Build list box entry string, insert the string and add the data the corresponds to it ! 1164: wsprintf( ! 1165: (LPSTR)lpszBuf, ! 1166: lpOPS->arrPasteEntries[nPasteEntriesIndex].lpstrFormatName, ! 1167: (LPSTR)szFullUserTypeName ! 1168: ); ! 1169: nIndex = (int)SendMessage( ! 1170: hList, ! 1171: (fInsertFirst ? LB_INSERTSTRING : LB_ADDSTRING), ! 1172: 0, ! 1173: (LPARAM)(LPSTR)lpszBuf ! 1174: ); ! 1175: SendMessage( ! 1176: hList, ! 1177: LB_SETITEMDATA, ! 1178: nIndex, ! 1179: (LPARAM)(LPPASTELISTITEMDATA)lpItemData ! 1180: ); ! 1181: return TRUE; ! 1182: } ! 1183: ! 1184: ! 1185: /* ! 1186: * FFillPasteList ! 1187: * ! 1188: * Purpose: ! 1189: * Fills the invisible paste list with the formats offered by the clipboard object and ! 1190: * asked for by the container. ! 1191: * ! 1192: * Parameters: ! 1193: * hDlg HWND of the dialog ! 1194: * lpPS Paste Special Dialog Structure ! 1195: * ! 1196: * Return Value: ! 1197: * BOOL TRUE if sucessful and if formats could be found. ! 1198: * FALSE if unsucessful or if no formats could be found. ! 1199: */ ! 1200: BOOL FFillPasteList(HWND hDlg, LPPASTESPECIAL lpPS) ! 1201: { ! 1202: LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS; ! 1203: LPMALLOC pIMalloc = NULL; ! 1204: LPSTR lpszBuf = (LPSTR)GlobalLock(lpPS->hBuff); ! 1205: HWND hList; ! 1206: int i; ! 1207: int nItems = 0; ! 1208: int nDefFormat = -1; ! 1209: BOOL fTryObjFmt = FALSE; ! 1210: BOOL fInsertFirst; ! 1211: HRESULT hrErr; ! 1212: ! 1213: hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); ! 1214: if (hrErr != NOERROR) ! 1215: goto error; ! 1216: ! 1217: hList = GetDlgItem(hDlg, ID_PS_PASTELIST); ! 1218: ! 1219: // Loop over the target's priority list of formats ! 1220: for (i = 0; i < lpOPS->cPasteEntries; i++) ! 1221: { ! 1222: if (lpOPS->arrPasteEntries[i].dwFlags != OLEUIPASTE_PASTEONLY && ! 1223: !(lpOPS->arrPasteEntries[i].dwFlags & OLEUIPASTE_PASTE)) ! 1224: continue; ! 1225: ! 1226: fInsertFirst = FALSE; ! 1227: ! 1228: if (lpOPS->arrPasteEntries[i].fmtetc.cfFormat==cfFileName ! 1229: || lpOPS->arrPasteEntries[i].fmtetc.cfFormat==cfEmbeddedObject ! 1230: || lpOPS->arrPasteEntries[i].fmtetc.cfFormat==cfEmbedSource) { ! 1231: if (! fTryObjFmt) { ! 1232: fTryObjFmt = TRUE; // only use 1st object format ! 1233: fInsertFirst = TRUE; // OLE obj format should always be 1st ! 1234: } else { ! 1235: continue; // already added an object format to list ! 1236: } ! 1237: } ! 1238: ! 1239: // add to list if entry is marked TRUE ! 1240: if (lpOPS->arrPasteEntries[i].dwScratchSpace) { ! 1241: if (nDefFormat < 0) ! 1242: nDefFormat = (fInsertFirst ? 0 : nItems); ! 1243: else if (fInsertFirst) ! 1244: nDefFormat++; // adjust for obj fmt inserted 1st in list ! 1245: ! 1246: if (!FAddPasteListItem(hList,fInsertFirst,i,lpPS,pIMalloc,lpszBuf)) ! 1247: goto error; ! 1248: nItems++; ! 1249: } ! 1250: } ! 1251: ! 1252: // initialize selection to first format matched in list ! 1253: if (nDefFormat >= 0) ! 1254: lpPS->nPasteListCurSel = nDefFormat; ! 1255: ! 1256: // Clean up ! 1257: if (pIMalloc) ! 1258: OleStdRelease((LPUNKNOWN)pIMalloc); ! 1259: if (lpszBuf) ! 1260: GlobalUnlock(lpPS->hBuff); ! 1261: ! 1262: // If no items have been added to the list box (none of the formats ! 1263: // offered by the source matched those acceptable to the container), ! 1264: // return FALSE ! 1265: if (nItems > 0) ! 1266: return TRUE; ! 1267: else ! 1268: return FALSE; ! 1269: ! 1270: error: ! 1271: if (pIMalloc) ! 1272: OleStdRelease((LPUNKNOWN)pIMalloc); ! 1273: if (lpszBuf) ! 1274: GlobalUnlock(lpPS->hBuff); ! 1275: FreeListData(hList); ! 1276: ! 1277: return FALSE; ! 1278: } ! 1279: ! 1280: ! 1281: /* ! 1282: * FFillPasteLinkList ! 1283: * ! 1284: * Purpose: ! 1285: * Fills the invisible paste link list with the formats offered by the clipboard object and ! 1286: * asked for by the container. ! 1287: * ! 1288: * Parameters: ! 1289: * hDlg HWND of the dialog ! 1290: * lpPS Paste Special Dialog Structure ! 1291: * ! 1292: * Return Value: ! 1293: * BOOL TRUE if sucessful and if formats could be found. ! 1294: * FALSE if unsucessful or if no formats could be found. ! 1295: */ ! 1296: BOOL FFillPasteLinkList(HWND hDlg, LPPASTESPECIAL lpPS) ! 1297: { ! 1298: LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS; ! 1299: LPDATAOBJECT lpSrcDataObj = lpOPS->lpSrcDataObj; ! 1300: LPENUMFORMATETC lpEnumFmtEtc = NULL; ! 1301: LPMALLOC pIMalloc = NULL; ! 1302: LPSTR lpszBuf = (LPSTR)GlobalLock(lpPS->hBuff); ! 1303: OLEUIPASTEFLAG pasteFlag; ! 1304: UINT arrLinkTypesSupported[PS_MAXLINKTYPES]; // Array of flags that ! 1305: // indicate which link types ! 1306: // are supported by source. ! 1307: FORMATETC fmtetc; ! 1308: int i, j; ! 1309: int nItems = 0; ! 1310: BOOL fLinkTypeSupported = FALSE; ! 1311: HWND hList; ! 1312: int nDefFormat = -1; ! 1313: BOOL fTryObjFmt = FALSE; ! 1314: BOOL fInsertFirst; ! 1315: HRESULT hrErr; ! 1316: ! 1317: hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); ! 1318: if (hrErr != NOERROR) ! 1319: goto error; ! 1320: ! 1321: // Remember which link type formats are offered by lpSrcDataObj. ! 1322: _fmemset(&fmtetc, 0, sizeof(FORMATETC)); ! 1323: for (i = 0; i < lpOPS->cLinkTypes; i++) ! 1324: { ! 1325: if (lpOPS->arrLinkTypes[i] = cfLinkSource) { ! 1326: OLEDBG_BEGIN2("OleQueryLinkFromData called\r\n") ! 1327: hrErr = OleQueryLinkFromData(lpSrcDataObj); ! 1328: OLEDBG_END2 ! 1329: if(NOERROR == hrErr) ! 1330: { ! 1331: arrLinkTypesSupported[i] = 1; ! 1332: fLinkTypeSupported = TRUE; ! 1333: } ! 1334: else arrLinkTypesSupported[i] = 0; ! 1335: } ! 1336: else { ! 1337: fmtetc.cfFormat = lpOPS->arrLinkTypes[i]; ! 1338: fmtetc.dwAspect = DVASPECT_CONTENT; ! 1339: fmtetc.tymed = 0xFFFFFFFF; // All tymed values ! 1340: fmtetc.lindex = -1; ! 1341: OLEDBG_BEGIN2("IDataObject::QueryGetData called\r\n") ! 1342: hrErr = lpSrcDataObj->lpVtbl->QueryGetData(lpSrcDataObj,&fmtetc); ! 1343: OLEDBG_END2 ! 1344: if(NOERROR == hrErr) ! 1345: { ! 1346: arrLinkTypesSupported[i] = 1; ! 1347: fLinkTypeSupported = TRUE; ! 1348: } ! 1349: else arrLinkTypesSupported[i] = 0; ! 1350: } ! 1351: } ! 1352: // No link types are offered by lpSrcDataObj ! 1353: if (! fLinkTypeSupported) { ! 1354: nItems = 0; ! 1355: goto cleanup; ! 1356: } ! 1357: ! 1358: hList = GetDlgItem(hDlg, ID_PS_PASTELINKLIST); ! 1359: ! 1360: // Enumerate the formats acceptable to container ! 1361: for (i = 0; i < lpOPS->cPasteEntries; i++) ! 1362: { ! 1363: fLinkTypeSupported = FALSE; ! 1364: ! 1365: // If container will accept any link type offered by source object ! 1366: if (lpOPS->arrPasteEntries[i].dwFlags & OLEUIPASTE_LINKANYTYPE) ! 1367: fLinkTypeSupported = TRUE; ! 1368: else ! 1369: { ! 1370: // Check if any of the link types offered by the source ! 1371: // object are acceptable to the container ! 1372: // This code depends on the LINKTYPE enum values being powers of 2 ! 1373: for (pasteFlag = OLEUIPASTE_LINKTYPE1, j = 0; ! 1374: j < lpOPS->cLinkTypes; ! 1375: pasteFlag*=2, j++) ! 1376: { ! 1377: if ((lpOPS->arrPasteEntries[i].dwFlags & pasteFlag) && ! 1378: arrLinkTypesSupported[j]) ! 1379: { ! 1380: fLinkTypeSupported = TRUE; ! 1381: break; ! 1382: } ! 1383: } ! 1384: } ! 1385: ! 1386: fInsertFirst = FALSE; ! 1387: ! 1388: if (lpOPS->arrPasteEntries[i].fmtetc.cfFormat==cfFileName ! 1389: || lpOPS->arrPasteEntries[i].fmtetc.cfFormat==cfLinkSource) { ! 1390: if (! fTryObjFmt) { ! 1391: fTryObjFmt = TRUE; // only use 1st object format ! 1392: fInsertFirst = TRUE; // OLE obj format should always be 1st ! 1393: } else { ! 1394: continue; // already added an object format to list ! 1395: } ! 1396: } ! 1397: ! 1398: // add to list if entry is marked TRUE ! 1399: if (fLinkTypeSupported && lpOPS->arrPasteEntries[i].dwScratchSpace) { ! 1400: if (nDefFormat < 0) ! 1401: nDefFormat = (fInsertFirst ? 0 : nItems); ! 1402: else if (fInsertFirst) ! 1403: nDefFormat++; // adjust for obj fmt inserted 1st in list ! 1404: ! 1405: if (!FAddPasteListItem(hList,fInsertFirst,i,lpPS,pIMalloc,lpszBuf)) ! 1406: goto error; ! 1407: nItems++; ! 1408: } ! 1409: } // end FOR ! 1410: ! 1411: nItems = (int)SendMessage(hList, LB_GETCOUNT, 0, 0L); ! 1412: ! 1413: // initialize selection to first format matched in list ! 1414: if (nDefFormat >= 0) ! 1415: lpPS->nPasteLinkListCurSel = nDefFormat; ! 1416: ! 1417: cleanup: ! 1418: // Clean up ! 1419: if (pIMalloc) ! 1420: OleStdRelease((LPUNKNOWN)pIMalloc); ! 1421: if (lpszBuf) ! 1422: GlobalUnlock(lpPS->hBuff); ! 1423: ! 1424: // If no items have been added to the list box (none of the formats ! 1425: // offered by the source matched those acceptable to the destination), ! 1426: // return FALSE ! 1427: if (nItems > 0) ! 1428: return TRUE; ! 1429: else ! 1430: return FALSE; ! 1431: ! 1432: error: ! 1433: if (pIMalloc) ! 1434: OleStdRelease((LPUNKNOWN)pIMalloc); ! 1435: if (lpszBuf) ! 1436: GlobalUnlock(lpPS->hBuff); ! 1437: FreeListData(hList); ! 1438: ! 1439: return FALSE; ! 1440: } ! 1441: ! 1442: ! 1443: /* ! 1444: * FreeListData ! 1445: * ! 1446: * Purpose: ! 1447: * Free the local memory associated with each list box item ! 1448: * ! 1449: * Parameters: ! 1450: * hList HWND of the list ! 1451: * ! 1452: * Return Value: ! 1453: * None ! 1454: */ ! 1455: void FreeListData(HWND hList) ! 1456: { ! 1457: int nItems, i; ! 1458: LPPASTELISTITEMDATA lpItemData; ! 1459: LPMALLOC pIMalloc; ! 1460: HRESULT hrErr; ! 1461: ! 1462: hrErr = CoGetMalloc(MEMCTX_TASK, &pIMalloc); ! 1463: if (hrErr != NOERROR) ! 1464: return; ! 1465: ! 1466: nItems = (int) SendMessage(hList, LB_GETCOUNT, 0, 0L); ! 1467: for (i = 0; i < nItems; i++) ! 1468: { ! 1469: lpItemData = (LPPASTELISTITEMDATA)SendMessage(hList, LB_GETITEMDATA, (WPARAM)i, 0L); ! 1470: if ((LRESULT)lpItemData != LB_ERR) ! 1471: pIMalloc->lpVtbl->Free(pIMalloc, (LPVOID)lpItemData); ! 1472: } ! 1473: OleStdRelease((LPUNKNOWN)pIMalloc); ! 1474: } ! 1475: ! 1476: /* ! 1477: * FHasPercentS ! 1478: * ! 1479: * Purpose: ! 1480: * Determines if string contains %s. ! 1481: * ! 1482: * Parameters: ! 1483: * lpsz LPCSTR string in which occurence of '%s' is looked for ! 1484: * ! 1485: * Return Value: ! 1486: * BOOL TRUE if %s is found, else FALSE. ! 1487: */ ! 1488: ! 1489: BOOL FHasPercentS(LPCSTR lpsz, LPPASTESPECIAL lpPS) ! 1490: { ! 1491: int n = 0; ! 1492: LPSTR lpszTmp; ! 1493: ! 1494: if (!lpsz) return FALSE; ! 1495: // Copy input string to buffer. This allows caller to pass a ! 1496: // code-based string. Code segments may be swapped out in low memory situations ! 1497: // and so code-based strings need to be copied before string elements can be accessed. ! 1498: lpszTmp = (LPSTR)GlobalLock(lpPS->hBuff); ! 1499: lstrcpy(lpszTmp, lpsz); ! 1500: ! 1501: while (*lpszTmp) ! 1502: { ! 1503: if (*lpszTmp == '%') ! 1504: { ! 1505: lpszTmp = AnsiNext(lpszTmp); ! 1506: if (*lpszTmp == 's') // If %s, return ! 1507: { ! 1508: GlobalUnlock(lpPS->hBuff); ! 1509: return TRUE; ! 1510: } ! 1511: else if (*lpszTmp == '%') // if %%, skip to next character ! 1512: lpszTmp = AnsiNext(lpszTmp); ! 1513: } ! 1514: else lpszTmp = AnsiNext(lpszTmp); ! 1515: } ! 1516: ! 1517: GlobalUnlock(lpPS->hBuff); ! 1518: return FALSE; ! 1519: } ! 1520: ! 1521: /* ! 1522: * AllocateScratchMem ! 1523: * ! 1524: * Purpose: ! 1525: * Allocates scratch memory for use by the PasteSpecial dialog. The memory is ! 1526: * is used as the buffer for building up strings using wsprintf. Strings are built up ! 1527: * using the buffer while inserting items into the Paste & PasteLink lists and while ! 1528: * setting the help result text. It must be big enough to handle the string that results after ! 1529: * replacing the %s in the lpstrFormatName and lpstrResultText in arrPasteEntries[] ! 1530: * by the FullUserTypeName. It must also be big enough to build the dialog's result text ! 1531: * after %s substitutions by the FullUserTypeName or the ApplicationName. ! 1532: * ! 1533: * Parameters: ! 1534: * lpPS Paste Special Dialog Structure ! 1535: * ! 1536: * Return Value: ! 1537: * HGLOBAL Handle to allocated global memory ! 1538: */ ! 1539: ! 1540: HGLOBAL AllocateScratchMem(LPPASTESPECIAL lpPS) ! 1541: { ! 1542: LPOLEUIPASTESPECIAL lpOPS = lpPS->lpOPS; ! 1543: int nLen, i; ! 1544: int nSubstitutedText = 0; ! 1545: int nAlloc = 0; ! 1546: ! 1547: // Get the maximum length of the FullUserTypeNames specified by OBJECTDESCRIPTOR ! 1548: // and the LINKSRCDESCRIPTOR and the Application Name. Any of these may be substituted ! 1549: // for %s in the result-text/list entries. ! 1550: if (lpPS->szFullUserTypeNameOD) ! 1551: nSubstitutedText = lstrlen(lpPS->szFullUserTypeNameOD); ! 1552: if (lpPS->szFullUserTypeNameLSD) ! 1553: nSubstitutedText = __max(nSubstitutedText, lstrlen(lpPS->szFullUserTypeNameLSD)); ! 1554: if (lpPS->szAppName) ! 1555: nSubstitutedText = __max(nSubstitutedText, lstrlen(lpPS->szAppName)); ! 1556: ! 1557: // Get the maximum length of lpstrFormatNames & lpstrResultText in arrPasteEntries ! 1558: nLen = 0; ! 1559: for (i = 0; i < lpOPS->cPasteEntries; i++) ! 1560: { ! 1561: nLen = __max(nLen, lstrlen(lpOPS->arrPasteEntries[i].lpstrFormatName)); ! 1562: nLen = __max(nLen, lstrlen(lpOPS->arrPasteEntries[i].lpstrResultText)); ! 1563: } ! 1564: ! 1565: // Get the maximum length of lpstrFormatNames and lpstrResultText after %s has ! 1566: // been substituted (At most one %s can appear in each string). ! 1567: // Add 1 to hold NULL terminator. ! 1568: nAlloc = nLen+nSubstitutedText+1; ! 1569: ! 1570: // Allocate scratch memory to be used to build strings ! 1571: // nAlloc is big enough to hold any of the lpstrResultText or lpstrFormatName in arrPasteEntries[] ! 1572: // after %s substitution. ! 1573: // We also need space to build up the help result text. 512 is the maximum length of the ! 1574: // standard dialog help text before substitutions. 512+nAlloc is the maximum length ! 1575: // after %s substition. ! 1576: // SetPasteSpecialHelpResults() requires 4 such buffers to build up the result text ! 1577: return GlobalAlloc(GHND, (DWORD)4*(512+nAlloc)); ! 1578: } ! 1579:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.