Annotation of mstools/ole20/samples/ole2ui/pastespl.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.