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

1.1     ! root        1: /*
        !             2:  *  GETICON.C
        !             3:  *
        !             4:  *  Functions to create DVASPECT_ICON metafile from filename or classname.
        !             5:  *
        !             6:  *  GetIconOfFile
        !             7:  *  GetIconOfClass
        !             8:  *  HIconAndSourceFromClass Extracts the first icon in a class's server path
        !             9:  *                          and returns the path and icon index to caller.
        !            10:  *  FIconFileFromClass      Retrieves the path to the exe/dll containing the
        !            11:  *                           default icon, and the index of the icon.
        !            12:  *  OleUIMetafilePictFromIconAndLabel
        !            13:  *  OleStdIconLabelTextOut
        !            14:  *  PointerToNthField
        !            15:  *  XformWidthInPixelsToHimetric  Converts an int width into HiMetric units
        !            16:  *  XformWidthInHimetricToPixels  Converts an int width from HiMetric units
        !            17:  *  XformHeightInPixelsToHimetric Converts an int height into HiMetric units
        !            18:  *  XformHeightInHimetricToPixels Converts an int height from HiMetric units
        !            19:  *
        !            20:  *    (c) Copyright Microsoft Corp. 1992-1993 All Rights Reserved
        !            21:  */
        !            22: 
        !            23: #ifdef STANDALONE
        !            24: #include <windows.h>   
        !            25: #include <shellapi.h>  
        !            26: #include <ole2.h>      
        !            27: #else
        !            28: #define STRICT  1
        !            29: #include "ole2ui.h"   
        !            30: #endif
        !            31: 
        !            32: #include <stdlib.h>
        !            33: #include <string.h>
        !            34: #include <ctype.h>
        !            35: #include <commdlg.h>
        !            36: #include <memory.h>
        !            37: #include <cderr.h>
        !            38: 
        !            39: #include "geticon.h"
        !            40: 
        !            41: static HINSTANCE  s_hInst;
        !            42: 
        !            43: static char szMaxWidth[] ="WWWWWWWWWW";
        !            44: 
        !            45: //Strings for metafile comments.
        !            46: static char szIconOnly[]="IconOnly";        //Where to stop to exclude label.
        !            47: 
        !            48: 
        !            49: #ifdef STANDALONE
        !            50: // these three values should be the same as in ole2ui.h
        !            51: #define OLEUI_CCHKEYMAX      256 
        !            52: #define OLEUI_CCHPATHMAX     256 
        !            53: #define OLEUI_CCHLABELMAX     40
        !            54: #else
        !            55: static char szOLE2DLL[] = "ole2.dll";   // name of OLE 2.0 library
        !            56: #endif
        !            57: 
        !            58: #define ICONINDEX              0
        !            59: 
        !            60: #define AUXUSERTYPE_SHORTNAME  USERCLASSTYPE_SHORT  // short name
        !            61: #define HIMETRIC_PER_INCH   2540      // number HIMETRIC units per inch
        !            62: #define PTS_PER_INCH          72      // number points (font size) per inch
        !            63: 
        !            64: #define MAP_PIX_TO_LOGHIM(x,ppli)   MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
        !            65: #define MAP_LOGHIM_TO_PIX(x,ppli)   MulDiv((ppli), (x), HIMETRIC_PER_INCH)
        !            66: 
        !            67: static char szVanillaDocIcon[] = "DefIcon";
        !            68: 
        !            69: static char szDocument[40] = "";    
        !            70: static char szSeparators[] = " \t\\/!:";
        !            71: 
        !            72: #define IS_SEPARATOR(c)         ( (c) == ' ' || (c) == '\\' || (c) == '/' || (c) == '\t' || (c) == '!' || (c) == ':' )
        !            73: #define IS_FILENAME_DELIM(c)    ( (c) == '\\' || (c) == '/' || (c) == ':' )
        !            74: 
        !            75: 
        !            76: STDAPI_(HGLOBAL) OleUIMetafilePictFromIconAndLabel(HICON, LPSTR, LPSTR, UINT);
        !            77: 
        !            78: 
        !            79: /*******
        !            80:  *
        !            81:  * ICON METAFILE FORMAT:
        !            82:  *
        !            83:  * The metafile generated with OleUIMetafilePictFromIconAndLabel contains
        !            84:  * the following records which are used by the functions in DRAWICON.C
        !            85:  * to draw the icon with and without the label and to extract the icon,
        !            86:  * label, and icon source/index.
        !            87:  *
        !            88:  *  SetWindowOrg
        !            89:  *  SetWindowExt
        !            90:  *  DrawIcon:
        !            91:  *      Inserts records of DIBBITBLT or DIBSTRETCHBLT, once for the
        !            92:  *      AND mask, one for the image bits.
        !            93:  *  Escape with the comment "IconOnly"
        !            94:  *      This indicates where to stop record enumeration to draw only
        !            95:  *      the icon.
        !            96:  *  SetTextColor
        !            97:  *  SetBkColor
        !            98:  *  CreateFont
        !            99:  *  SelectObject on the font.
        !           100:  *  ExtTextOut
        !           101:  *      One or more ExtTextOuts occur if the label is wrapped.  The
        !           102:  *      text in these records is used to extract the label.
        !           103:  *  SelectObject on the old font.
        !           104:  *  DeleteObject on the font.
        !           105:  *  Escape with a comment that contains the path to the icon source.
        !           106:  *  Escape with a comment that is the ASCII of the icon index.
        !           107:  *
        !           108:  *******/
        !           109: 
        !           110: 
        !           111: 
        !           112: 
        !           113: /*
        !           114:  * GetIconOfFile(HINSTANCE hInst, LPSTR lpszPath, BOOL fUseFileAsLabel)
        !           115:  *
        !           116:  * Purpose:
        !           117:  *  Returns a hMetaPict containing an icon and label (filename) for the 
        !           118:  *  specified filename.
        !           119:  *
        !           120:  * Parameters:
        !           121:  *  hinst
        !           122:  *  lpszPath        LPSTR path including filename to use
        !           123:  *  fUseFileAsLabel BOOL TRUE if the icon's label is the filename, FALSE if
        !           124:  *                  there should be no label.
        !           125:  *
        !           126:  * Return Value:
        !           127:  *  HGLOBAL         hMetaPict containing the icon and label - if there's no
        !           128:  *                  class in reg db for the file in lpszPath, then we use 
        !           129:  *                  Document.  If lpszPath is NULL, then we return NULL.
        !           130:  */
        !           131: 
        !           132: STDAPI_(HGLOBAL) GetIconOfFile(HINSTANCE hInst, LPSTR lpszPath, BOOL fUseFileAsLabel)
        !           133: {
        !           134: 
        !           135: 
        !           136:   char     szIconFile[OLEUI_CCHPATHMAX];
        !           137:   char     szLabel[OLEUI_CCHLABELMAX];
        !           138:   LPSTR    lpszClsid = NULL;
        !           139:   CLSID    clsid;
        !           140:   HICON    hDefIcon = NULL;
        !           141:   UINT     IconIndex = 0;
        !           142:   HGLOBAL  hMetaPict;
        !           143:   HRESULT  hResult;
        !           144: 
        !           145: 
        !           146: 
        !           147:   if (NULL == lpszPath)  // even if fUseFileAsLabel is FALSE, we still
        !           148:     return NULL;             // need a valid filename to get the class.
        !           149: 
        !           150:   s_hInst = hInst;
        !           151: 
        !           152:   hResult = GetClassFile(lpszPath, &clsid);
        !           153: 
        !           154:   if (NOERROR == hResult)  // use the clsid we got to get to the icon
        !           155:   {
        !           156:       hDefIcon = HIconAndSourceFromClass(&clsid,
        !           157:                                          (LPSTR)szIconFile,
        !           158:                                          &IconIndex);
        !           159:   }
        !           160: 
        !           161:   if ( (NOERROR != hResult) || (NULL == hDefIcon) )
        !           162:   {
        !           163:      // Here, either GetClassFile failed or HIconAndSourceFromClass failed.
        !           164: 
        !           165:      LPSTR lpszTemp;
        !           166: 
        !           167:      lpszTemp = lpszPath;
        !           168: 
        !           169:      while ((*lpszTemp != '.') && (*lpszTemp != '\0'))
        !           170:         lpszTemp++;
        !           171: 
        !           172: 
        !           173:      if ('.' != *lpszTemp)  
        !           174:        goto UseVanillaDocument;
        !           175: 
        !           176: 
        !           177:      if (FALSE == GetAssociatedExecutable(lpszTemp, (LPSTR)szIconFile))
        !           178:        goto UseVanillaDocument;
        !           179: 
        !           180:      hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex);
        !           181:   }
        !           182: 
        !           183:   if (hDefIcon <= (HICON)1) // ExtractIcon returns 1 if szExecutable is not exe,
        !           184:   {                         // 0 if there are no icons.
        !           185: UseVanillaDocument:       
        !           186: 
        !           187: #ifdef STANDALONE
        !           188:     GetModuleFileName(s_hInst, (LPSTR)szIconFile, OLEUI_CCHPATHMAX);
        !           189:     IconIndex = ICONINDEX;
        !           190:     hDefIcon = LoadIcon(s_hInst, (LPSTR)szVanillaDocIcon);
        !           191: #else
        !           192:     lstrcpy((LPSTR)szIconFile, (LPSTR)szOLE2DLL);
        !           193:     IconIndex = ICONINDEX;
        !           194:     hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex);
        !           195: #endif
        !           196: 
        !           197:   }
        !           198: 
        !           199:   // Now let's get the label we want to use.
        !           200: 
        !           201:   if (fUseFileAsLabel)   // strip off path, so we just have the filename.
        !           202:   {
        !           203:      int istrlen;
        !           204:      LPSTR lpszBeginFile;
        !           205: 
        !           206:      istrlen = lstrlen(lpszPath);
        !           207: 
        !           208:      // set pointer to END of path, so we can walk backwards through it.
        !           209:      lpszBeginFile = lpszPath + istrlen -1;
        !           210: 
        !           211:      while ( (lpszBeginFile >= lpszPath) 
        !           212:              && (!IS_FILENAME_DELIM(*lpszBeginFile)) )
        !           213:       lpszBeginFile--;
        !           214: 
        !           215: 
        !           216:      lpszBeginFile++;  // step back over the delimiter
        !           217: 
        !           218: 
        !           219:      lstrcpyn(szLabel, lpszBeginFile, sizeof(szLabel));
        !           220:   }
        !           221: 
        !           222:   else   // use the short user type (AuxUserType2) for the label
        !           223:   {
        !           224: 
        !           225:       if (0 == OleStdGetAuxUserType(&clsid, AUXUSERTYPE_SHORTNAME,  
        !           226:                                    (LPSTR)szLabel, OLEUI_CCHLABELMAX, NULL)) {
        !           227:          
        !           228: #if !defined( STANDALONE )
        !           229:          if ('\0'==szDocument[0]) {
        !           230:              LoadString(
        !           231:                  s_hInst,IDS_DEFICONLABEL,szDocument,sizeof(szDocument));
        !           232:          }
        !           233: #endif
        !           234:          lstrcpy(szLabel, szDocument);
        !           235:       }
        !           236:   }
        !           237: 
        !           238: 
        !           239:   hMetaPict = OleUIMetafilePictFromIconAndLabel(hDefIcon, 
        !           240:                                                 szLabel,
        !           241:                                                 (LPSTR)szIconFile,
        !           242:                                                 IconIndex);
        !           243: 
        !           244:   DestroyIcon(hDefIcon);
        !           245: 
        !           246:   return hMetaPict;
        !           247: 
        !           248: }
        !           249: 
        !           250: /*
        !           251:  * GetAssociatedExecutable
        !           252:  *
        !           253:  * Purpose:  Finds the executable associated with the provided extension
        !           254:  *
        !           255:  * Parameters:
        !           256:  *   lpszExtension   LPSTR points to the extension we're trying to find an exe 
        !           257:  *                   for. Does **NO** validation.
        !           258:  *
        !           259:  *   lpszExecutable  LPSTR points to where the exe name will be returned.
        !           260:  *                   No validation here either - pass in 128 char buffer.
        !           261:  *
        !           262:  * Return:
        !           263:  *   BOOL            TRUE if we found an exe, FALSE if we didn't.
        !           264:  *
        !           265:  */
        !           266: 
        !           267: BOOL FAR PASCAL GetAssociatedExecutable(LPSTR lpszExtension, LPSTR lpszExecutable)
        !           268: 
        !           269: {
        !           270:    HKEY    hKey;
        !           271:    DWORD   dw;
        !           272:    LRESULT lRet;
        !           273:    char    szValue[OLEUI_CCHKEYMAX];
        !           274:    char    szKey[OLEUI_CCHKEYMAX];
        !           275:    LPSTR   lpszTemp, lpszExe;
        !           276: 
        !           277: 
        !           278:    lRet = RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey);
        !           279: 
        !           280:    if (ERROR_SUCCESS != lRet)
        !           281:       return FALSE;
        !           282: 
        !           283:    dw = OLEUI_CCHPATHMAX;
        !           284:    lRet = RegQueryValue(hKey, lpszExtension, (LPSTR)szValue, &dw);  //ProgId
        !           285: 
        !           286:    if (ERROR_SUCCESS != lRet)
        !           287:    {
        !           288:       RegCloseKey(hKey);
        !           289:       return FALSE;
        !           290:    }
        !           291:    
        !           292: 
        !           293:    // szValue now has ProgID
        !           294:    lstrcpy(szKey, szValue);
        !           295:    lstrcat(szKey, "\\Shell\\Open\\Command");
        !           296: 
        !           297: 
        !           298:    dw = OLEUI_CCHPATHMAX;
        !           299:    lRet = RegQueryValue(hKey, (LPSTR)szKey, (LPSTR)szValue, &dw);
        !           300: 
        !           301:    if (ERROR_SUCCESS != lRet)
        !           302:    {
        !           303:       RegCloseKey(hKey);
        !           304:       return FALSE;
        !           305:    }
        !           306: 
        !           307:    // szValue now has an executable name in it.  Let's null-terminate
        !           308:    // at the first post-executable space (so we don't have cmd line
        !           309:    // args.
        !           310: 
        !           311:    lpszTemp = (LPSTR)szValue;
        !           312: 
        !           313:    while (('\0' != *lpszTemp) && (isspace(*lpszTemp)))
        !           314:       lpszTemp++;     // Strip off leading spaces
        !           315: 
        !           316:    lpszExe = lpszTemp;
        !           317: 
        !           318:    while (('\0' != lpszTemp) && (!isspace(*lpszTemp)))
        !           319:       lpszTemp++;     // Set through exe name
        !           320: 
        !           321:    *lpszTemp = '\0';  // null terminate at first space (or at end).
        !           322: 
        !           323: 
        !           324:    lstrcpy(lpszExecutable, lpszExe);
        !           325: 
        !           326:    return TRUE;
        !           327: 
        !           328: }
        !           329: 
        !           330: 
        !           331: 
        !           332: 
        !           333: 
        !           334: 
        !           335: 
        !           336: 
        !           337: 
        !           338: 
        !           339: /*
        !           340:  * GetIconOfClass(HINSTANCE hInst, REFCLSID rclsid, LPSTR lpszLabel, BOOL fUseTypeAsLabel)
        !           341:  *
        !           342:  * Purpose:
        !           343:  *  Returns a hMetaPict containing an icon and label (human-readable form
        !           344:  *  of class) for the specified clsid.
        !           345:  *
        !           346:  * Parameters:
        !           347:  *  hinst
        !           348:  *  rclsid          REFCLSID pointing to clsid to use.
        !           349:  *  lpszLabel       label to use for icon.
        !           350:  *  fUseTypeAsLabel Use the clsid's user type name as the icon's label.
        !           351:  *
        !           352:  * Return Value:
        !           353:  *  HGLOBAL         hMetaPict containing the icon and label - if we
        !           354:  *                  don't find the clsid in the reg db then we
        !           355:  *                  return NULL.
        !           356:  */
        !           357: 
        !           358: STDAPI_(HGLOBAL)    GetIconOfClass(HINSTANCE hInst, REFCLSID rclsid, LPSTR lpszLabel, BOOL fUseTypeAsLabel)
        !           359: {
        !           360: 
        !           361:   char    szLabel[OLEUI_CCHLABELMAX];
        !           362:   char    szIconFile[OLEUI_CCHPATHMAX];
        !           363:   HICON   hDefIcon;
        !           364:   UINT    IconIndex;
        !           365:   HGLOBAL hMetaPict;
        !           366: 
        !           367: 
        !           368:   s_hInst = hInst;
        !           369: 
        !           370:   if (!fUseTypeAsLabel)  // Use string passed in as label
        !           371:   {   
        !           372:     if (NULL != lpszLabel)
        !           373:        lstrcpyn(szLabel, lpszLabel, sizeof(szLabel));
        !           374:     else
        !           375:        *szLabel = '\0';
        !           376:   } 
        !           377:   else   // Use AuxUserType2 (short name) as label
        !           378:   { 
        !           379: 
        !           380:       if (0 == OleStdGetAuxUserType(rclsid,
        !           381:                                     AUXUSERTYPE_SHORTNAME,  
        !           382:                                     (LPSTR)szLabel,         
        !           383:                                     OLEUI_CCHLABELMAX,
        !           384:                                     NULL))
        !           385: 
        !           386:        // If we can't get the AuxUserType2, then try the long name
        !           387:        if (0 == OleStdGetUserTypeOfClass(rclsid, szLabel, OLEUI_CCHKEYMAX, NULL)) {
        !           388: #if !defined( STANDALONE )
        !           389:          if ('\0'==szDocument[0]) {
        !           390:              LoadString(
        !           391:                  s_hInst,IDS_DEFICONLABEL,szDocument,sizeof(szDocument));
        !           392:          }
        !           393: #endif
        !           394:          lstrcpy(szLabel, szDocument);  // last resort
        !           395:        }
        !           396:   }
        !           397: 
        !           398:   // Get the icon, icon index, and path to icon file
        !           399:   hDefIcon = HIconAndSourceFromClass(rclsid,
        !           400:                   (LPSTR)szIconFile,
        !           401:                   &IconIndex);
        !           402: 
        !           403:   if (NULL == hDefIcon)  // Use Vanilla Document
        !           404:   {
        !           405: #ifdef STANDALONE
        !           406:     GetModuleFileName(s_hInst, (LPSTR)szIconFile, OLEUI_CCHPATHMAX);
        !           407:     IconIndex = ICONINDEX;
        !           408:     hDefIcon = LoadIcon(s_hInst, (LPSTR)szVanillaDocIcon);
        !           409: #else
        !           410:     lstrcpy((LPSTR)szIconFile, (LPSTR)szOLE2DLL);
        !           411:     IconIndex = ICONINDEX;
        !           412:     hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex);
        !           413: #endif
        !           414: 
        !           415:   }
        !           416: 
        !           417:   // Create the metafile
        !           418:   hMetaPict = OleUIMetafilePictFromIconAndLabel(hDefIcon, szLabel,
        !           419:                                                 (LPSTR)szIconFile, IconIndex);
        !           420: 
        !           421:   DestroyIcon(hDefIcon);
        !           422: 
        !           423:   return hMetaPict;
        !           424: 
        !           425: }
        !           426: 
        !           427: 
        !           428: 
        !           429: 
        !           430: 
        !           431: /*
        !           432:  * HIconAndSourceFromClass
        !           433:  *
        !           434:  * Purpose:
        !           435:  *  Given an object class name, finds an associated executable in the
        !           436:  *  registration database and extracts the first icon from that
        !           437:  *  executable.  If none is available or the class has no associated
        !           438:  *  executable, this function returns NULL.
        !           439:  *
        !           440:  * Parameters:
        !           441:  *  rclsid          pointer to clsid to look up.
        !           442:  *  pszSource       LPSTR in which to place the source of the icon.
        !           443:  *                  This is assumed to be OLEUI_CCHPATHMAX
        !           444:  *  puIcon          UINT FAR * in which to store the index of the
        !           445:  *                  icon in pszSource.
        !           446:  *
        !           447:  * Return Value:
        !           448:  *  HICON           Handle to the extracted icon if there is a module
        !           449:  *                  associated to pszClass.  NULL on failure to either
        !           450:  *                  find the executable or extract and icon.
        !           451:  */
        !           452: 
        !           453: HICON FAR PASCAL HIconAndSourceFromClass(REFCLSID rclsid, LPSTR pszSource, UINT FAR *puIcon)
        !           454:     {
        !           455:     HICON           hIcon;
        !           456:     int             IconIndex;
        !           457: 
        !           458:     if (NULL==rclsid || NULL==pszSource)
        !           459:         return NULL;
        !           460: 
        !           461:     if (!FIconFileFromClass(rclsid, pszSource, OLEUI_CCHPATHMAX, &IconIndex)) 
        !           462:         return NULL;
        !           463: 
        !           464:     hIcon=ExtractIcon(s_hInst, pszSource, IconIndex);
        !           465: 
        !           466:     if ((HICON)32 > hIcon)
        !           467:         hIcon=NULL;
        !           468:     else
        !           469:         *puIcon= IconIndex;
        !           470: 
        !           471:     return hIcon;
        !           472:     }
        !           473: 
        !           474: 
        !           475: 
        !           476: /*
        !           477:  * FIconFileFromClass
        !           478:  *
        !           479:  * Purpose:
        !           480:  *  Looks up the path to executable that contains the class default icon.
        !           481:  *
        !           482:  * Parameters:
        !           483:  *  rclsid          pointer to CLSID to look up.
        !           484:  *  pszEXE          LPSTR at which to store the server name
        !           485:  *  cch             UINT size of pszEXE
        !           486:  *  lpIndex         LPUINT to index of icon within executable
        !           487:  *
        !           488:  * Return Value:
        !           489:  *  BOOL            TRUE if one or more characters were loaded into pszEXE.
        !           490:  *                  FALSE otherwise.
        !           491:  */
        !           492: 
        !           493: BOOL FAR PASCAL FIconFileFromClass(REFCLSID rclsid, LPSTR pszEXE, UINT cch, UINT FAR *lpIndex)
        !           494: {
        !           495: 
        !           496:     DWORD         dw;
        !           497:     LONG          lRet;
        !           498:     HKEY          hKey;
        !           499:     LPMALLOC      lpIMalloc;
        !           500:     HRESULT       hrErr;
        !           501:     LPSTR         lpBuffer;
        !           502:     LPSTR         lpIndexString;
        !           503:     UINT          cBufferSize = 136;  // room for 128 char path and icon's index
        !           504:     char          szKey[64];
        !           505:     LPSTR         pszClass;
        !           506: 
        !           507: 
        !           508:     if (NULL==rclsid || NULL==pszEXE || 0==cch || IsEqualCLSID(rclsid,&CLSID_NULL))
        !           509:         return FALSE;
        !           510: 
        !           511:     //Here, we use CoGetMalloc and alloc a buffer (maxpathlen + 8) to
        !           512:     //pass to RegQueryValue.  Then, we copy the exe to pszEXE and the
        !           513:     //index to *lpIndex.
        !           514: 
        !           515:     hrErr = CoGetMalloc(MEMCTX_TASK, &lpIMalloc);
        !           516: 
        !           517:     if (NOERROR != hrErr)
        !           518:       return FALSE;
        !           519: 
        !           520:     lpBuffer = (LPSTR)lpIMalloc->lpVtbl->Alloc(lpIMalloc, cBufferSize);
        !           521: 
        !           522:     if (NULL == lpBuffer)
        !           523:     {
        !           524:       lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           525:       return FALSE;
        !           526:     }
        !           527: 
        !           528: 
        !           529:     if (CoIsOle1Class(rclsid))
        !           530:     {
        !           531: 
        !           532:       LPSTR lpszProgID;
        !           533: 
        !           534:       // we've got an ole 1.0 class on our hands, so we look at 
        !           535:       // progID\protocol\stdfileedting\server to get the 
        !           536:       // name of the executable.
        !           537: 
        !           538:       ProgIDFromCLSID(rclsid, &lpszProgID);
        !           539: 
        !           540:       //Open up the class key
        !           541:       lRet=RegOpenKey(HKEY_CLASSES_ROOT, lpszProgID, &hKey);
        !           542: 
        !           543:       if (ERROR_SUCCESS != lRet)
        !           544:       {
        !           545:          lpIMalloc->lpVtbl->Free(lpIMalloc, lpszProgID);
        !           546:          lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           547:          lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           548:          return FALSE;
        !           549:       }
        !           550: 
        !           551:       dw=(DWORD)cBufferSize;
        !           552:       lRet = RegQueryValue(hKey, "Protocol\\StdFileEditing\\Server", lpBuffer, &dw);
        !           553: 
        !           554:       if (ERROR_SUCCESS != lRet)
        !           555:       {
        !           556: 
        !           557:          RegCloseKey(hKey);
        !           558:          lpIMalloc->lpVtbl->Free(lpIMalloc, lpszProgID);
        !           559:          lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           560:          lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           561:          return FALSE;
        !           562:       }
        !           563: 
        !           564: 
        !           565:       // Use server and 0 as the icon index
        !           566:       lstrcpyn(pszEXE, lpBuffer, cch);
        !           567: 
        !           568:       *lpIndex = 0;
        !           569: 
        !           570:       RegCloseKey(hKey);
        !           571:       lpIMalloc->lpVtbl->Free(lpIMalloc, lpszProgID);
        !           572:       lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           573:       lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           574:       return TRUE;
        !           575: 
        !           576:     }
        !           577: 
        !           578: 
        !           579: 
        !           580:     /*
        !           581:      * We have to go walking in the registration database under the
        !           582:      * classname, so we first open the classname key and then check
        !           583:      * under "\\DefaultIcon" to get the file that contains the icon.
        !           584:      */
        !           585: 
        !           586:     StringFromCLSID(rclsid, &pszClass);
        !           587: 
        !           588:     lstrcpy(szKey, "CLSID\\");
        !           589:     lstrcat(szKey, pszClass);
        !           590: 
        !           591:     //Open up the class key
        !           592:     lRet=RegOpenKey(HKEY_CLASSES_ROOT, szKey, &hKey);
        !           593: 
        !           594:     if (ERROR_SUCCESS != lRet) 
        !           595:     {
        !           596:         lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           597:         lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass);
        !           598:         lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           599:         return FALSE;
        !           600:     }
        !           601: 
        !           602:     //Get the executable path and icon index.
        !           603: 
        !           604:     dw=(DWORD)cBufferSize;
        !           605:     lRet=RegQueryValue(hKey, "DefaultIcon", lpBuffer, &dw);
        !           606: 
        !           607:     if (ERROR_SUCCESS != lRet)
        !           608:     {
        !           609:       // no DefaultIcon  key...try LocalServer
        !           610: 
        !           611:       dw=(DWORD)cBufferSize;
        !           612:       lRet=RegQueryValue(hKey, "LocalServer", lpBuffer, &dw);
        !           613: 
        !           614:       if (ERROR_SUCCESS != lRet)
        !           615:       {
        !           616:          // no LocalServer entry either...they're outta luck.
        !           617: 
        !           618:          RegCloseKey(hKey);
        !           619:          lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           620:          lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass);
        !           621:          lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           622:          return FALSE;
        !           623:       }
        !           624: 
        !           625: 
        !           626:       // Use server from LocalServer or Server and 0 as the icon index
        !           627:       lstrcpyn(pszEXE, lpBuffer, cch);
        !           628: 
        !           629:       *lpIndex = 0;
        !           630: 
        !           631:       RegCloseKey(hKey);
        !           632:       lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           633:       lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass);
        !           634:       lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           635:       return TRUE;
        !           636:     }
        !           637: 
        !           638:     RegCloseKey(hKey);
        !           639: 
        !           640:     // lpBuffer contains a string that looks like "<pathtoexe>,<iconindex>",
        !           641:     // so we need to separate the path and the icon index.
        !           642: 
        !           643:     lpIndexString = PointerToNthField(lpBuffer, 2, ',');
        !           644: 
        !           645:     if ('\0' == *lpIndexString)  // no icon index specified - use 0 as default.
        !           646:     {
        !           647:        *lpIndex = 0;
        !           648: 
        !           649:     }
        !           650:     else
        !           651:     {
        !           652:        LPSTR lpTemp;
        !           653:        static char  szTemp[16];
        !           654: 
        !           655:        lstrcpy((LPSTR)szTemp, lpIndexString);
        !           656: 
        !           657:        // Put the icon index part into *pIconIndex
        !           658:        *lpIndex = atoi((const char *)szTemp);
        !           659: 
        !           660:        // Null-terminate the exe part.
        !           661:        lpTemp = AnsiPrev(lpBuffer, lpIndexString);
        !           662:        *lpTemp = '\0';
        !           663:     }
        !           664: 
        !           665:     if (!lstrcpyn(pszEXE, lpBuffer, cch))
        !           666:     {
        !           667:        lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           668:        lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass);
        !           669:        lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           670:        return FALSE;
        !           671:     }
        !           672: 
        !           673:     // Free the memory we alloc'd and leave.
        !           674:     lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
        !           675:     lpIMalloc->lpVtbl->Free(lpIMalloc, pszClass);
        !           676:     lpIMalloc->lpVtbl->Release(lpIMalloc);
        !           677:     return TRUE;
        !           678: }
        !           679: 
        !           680: 
        !           681: 
        !           682: 
        !           683: /*
        !           684:  * OleUIMetafilePictFromIconAndLabel
        !           685:  *
        !           686:  * Purpose:
        !           687:  *  Creates a METAFILEPICT structure that container a metafile in which
        !           688:  *  the icon and label are drawn.  A comment record is inserted between
        !           689:  *  the icon and the label code so our special draw function can stop
        !           690:  *  playing before the label.
        !           691:  *
        !           692:  * Parameters:
        !           693:  *  hIcon           HICON to draw into the metafile
        !           694:  *  pszLabel        LPSTR to the label string.
        !           695:  *  pszSourceFile   LPSTR containing the local pathname of the icon
        !           696:  *                  as we either get from the user or from the reg DB.
        !           697:  *  iIcon           UINT providing the index into pszSourceFile where
        !           698:  *                  the icon came from.
        !           699:  *
        !           700:  * Return Value:
        !           701:  *  HGLOBAL         Global memory handle containing a METAFILEPICT where
        !           702:  *                  the metafile uses the MM_ANISOTROPIC mapping mode.  The
        !           703:  *                  extents reflect both icon and label.
        !           704:  */
        !           705: 
        !           706: STDAPI_(HGLOBAL) OleUIMetafilePictFromIconAndLabel(HICON hIcon, LPSTR pszLabel
        !           707:     , LPSTR pszSourceFile, UINT iIcon)
        !           708:     {
        !           709:     HDC             hDC, hDCScreen;
        !           710:     HMETAFILE       hMF;
        !           711:     HGLOBAL         hMem;
        !           712:     LPMETAFILEPICT  pMF;
        !           713:     UINT            cxIcon, cyIcon;
        !           714:     UINT            cxText, cyText;
        !           715:     UINT            cx, cy;
        !           716:     UINT            cchLabel = 0;
        !           717:     HFONT           hFont, hFontT;
        !           718:     int             cyFont;
        !           719:     char            szIndex[10];
        !           720:     RECT            TextRect;
        !           721:     SIZE            size;
        !           722:     POINT           point;
        !           723: 
        !           724:     if (NULL==hIcon)  // null label is valid
        !           725:         return NULL;
        !           726: 
        !           727:     //Create a memory metafile
        !           728:     hDC=(HDC)CreateMetaFile(NULL);
        !           729: 
        !           730:     if (NULL==hDC)
        !           731:         return NULL;
        !           732: 
        !           733:     //Allocate the metafilepict
        !           734:     hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(METAFILEPICT));
        !           735: 
        !           736:     if (NULL==hMem)
        !           737:         {
        !           738:         hMF=CloseMetaFile(hDC);
        !           739:         DeleteMetaFile(hMF);
        !           740:         return NULL;
        !           741:         }
        !           742: 
        !           743: 
        !           744:     if (NULL!=pszLabel)
        !           745:         {
        !           746:         cchLabel=lstrlen(pszLabel);
        !           747: 
        !           748:         if (cchLabel >= OLEUI_CCHLABELMAX)
        !           749:            pszLabel[cchLabel] = '\0';   // truncate string
        !           750:         }
        !           751: 
        !           752:     //Need to use the screen DC for these operations
        !           753:     hDCScreen=GetDC(NULL);
        !           754:     cyFont=-(8*GetDeviceCaps(hDCScreen, LOGPIXELSY))/72;
        !           755: 
        !           756:     //cyFont was calculated to give us 8 point.
        !           757:     hFont=CreateFont(cyFont, 5, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET
        !           758:         , OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY
        !           759:         , FF_SWISS, "MS Sans Serif");
        !           760: 
        !           761:     hFontT=SelectObject(hDCScreen, hFont);
        !           762: 
        !           763:     GetTextExtentPoint(hDCScreen,szMaxWidth,lstrlen(szMaxWidth),&size);
        !           764:     SelectObject(hDCScreen, hFontT);
        !           765: 
        !           766:     ReleaseDC(NULL, hDCScreen);
        !           767: 
        !           768:     cxText = size.cx;
        !           769:     cyText = size.cy * 2;
        !           770:     
        !           771:     cxIcon = GetSystemMetrics(SM_CXICON);
        !           772:     cyIcon = GetSystemMetrics(SM_CYICON);
        !           773: 
        !           774: 
        !           775:     // If we have no label, then we want the metafile to be the width of 
        !           776:     // the icon (plus margin), not the width of the fattest string.
        !           777:     if ( (NULL == pszLabel) || ('\0' == *pszLabel) )
        !           778:         cx = cxIcon + cxIcon / 4;
        !           779:     else
        !           780:         cx = max(cxText, cxIcon);
        !           781: 
        !           782:     cy=cyIcon+cyText+4;
        !           783: 
        !           784:     //Set the metafile size to fit the icon and label
        !           785:     SetWindowOrgEx(hDC, 0, 0, &point);
        !           786:     SetWindowExtEx(hDC, cx, cy, &size);
        !           787: 
        !           788:     //Set up rectangle to pass to OleStdIconLabelTextOut
        !           789:     SetRectEmpty(&TextRect);
        !           790: 
        !           791:     TextRect.right = cx;
        !           792:     TextRect.bottom = cy;
        !           793: 
        !           794:     //Draw the icon and the text, centered with respect to each other.
        !           795:     DrawIcon(hDC, (cx-cxIcon)/2, 0, hIcon);
        !           796: 
        !           797:     //String that indicates where to stop if we're only doing icons
        !           798:     Escape(hDC, MFCOMMENT, lstrlen(szIconOnly)+1, szIconOnly, NULL);
        !           799: 
        !           800:     SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
        !           801:     SetBkMode(hDC, TRANSPARENT);
        !           802: 
        !           803:     OleStdIconLabelTextOut(hDC,
        !           804:                            hFont, 
        !           805:                            0,
        !           806:                            cy - cyText,
        !           807:                            ETO_CLIPPED, 
        !           808:                            &TextRect,
        !           809:                            pszLabel,
        !           810:                            cchLabel,
        !           811:                            NULL);
        !           812:   
        !           813:     //Write comments containing the icon source file and index.
        !           814:     if (NULL!=pszSourceFile)
        !           815:         {
        !           816:         //+1 on string lengths insures the null terminator is embedded.
        !           817:         Escape(hDC, MFCOMMENT, lstrlen(pszSourceFile)+1, pszSourceFile, NULL);
        !           818: 
        !           819:         cchLabel=wsprintf(szIndex, "%u", iIcon);
        !           820:         Escape(hDC, MFCOMMENT, cchLabel+1, szIndex, NULL);
        !           821:         }
        !           822: 
        !           823:     //All done with the metafile, now stuff it all into a METAFILEPICT.
        !           824:     hMF=CloseMetaFile(hDC);
        !           825: 
        !           826:     if (NULL==hMF)
        !           827:         {
        !           828:         GlobalFree(hMem);
        !           829:         return NULL;
        !           830:         }
        !           831: 
        !           832:     //Fill out the structure
        !           833:     pMF=(LPMETAFILEPICT)GlobalLock(hMem);
        !           834: 
        !           835:     //Transform to HIMETRICS
        !           836:     cx=XformWidthInPixelsToHimetric(hDCScreen, cx);
        !           837:     cy=XformHeightInPixelsToHimetric(hDCScreen, cy);
        !           838: 
        !           839:     pMF->mm=MM_ANISOTROPIC;
        !           840:     pMF->xExt=cx;
        !           841:     pMF->yExt=cy;
        !           842:     pMF->hMF=hMF;
        !           843: 
        !           844:     GlobalUnlock(hMem);
        !           845: 
        !           846:     DeleteObject(hFont);
        !           847: 
        !           848:     return hMem;
        !           849:     }
        !           850: 
        !           851: 
        !           852: 
        !           853: /*
        !           854:  * OleStdIconLabelTextOut
        !           855:  *
        !           856:  * Purpose:
        !           857:  *  Replacement for DrawText to be used in the "Display as Icon" metafile.  
        !           858:  *  Uses ExtTextOut to output a string center on (at most) two lines.  
        !           859:  *  Uses a very simple word wrap algorithm to split the lines.
        !           860:  *
        !           861:  * Parameters:  (same as for ExtTextOut, except for hFont)
        !           862:  *  hDC           device context to draw into; if this is NULL, then we don't
        !           863:  *                ETO the text, we just return the index of the beginning 
        !           864:  *                of the second line
        !           865:  *  hFont         font to use
        !           866:  *  nXStart       x-coordinate of starting position
        !           867:  *  nYStart       y-coordinate of starting position
        !           868:  *  fuOptions     rectangle type
        !           869:  *  lpRect        rect far * containing rectangle to draw text in.
        !           870:  *  lpszString    string to draw
        !           871:  *  cchString     length of string (truncated if over OLEUI_CCHLABELMAX)
        !           872:  *  lpDX          spacing between character cells
        !           873:  *
        !           874:  * Return Value:
        !           875:  *  UINT          Index of beginning of last line (0 if there's only one
        !           876:  *                line of text).
        !           877:  *
        !           878:  */
        !           879: 
        !           880: STDAPI_(UINT) OleStdIconLabelTextOut(HDC        hDC, 
        !           881:                                      HFONT      hFont,
        !           882:                                      int        nXStart, 
        !           883:                                      int        nYStart, 
        !           884:                                      UINT       fuOptions, 
        !           885:                                      RECT FAR * lpRect, 
        !           886:                                      LPSTR      lpszString, 
        !           887:                                      UINT       cchString, 
        !           888:                                      int FAR *  lpDX)
        !           889: {
        !           890: 
        !           891:   HDC          hDCScreen;
        !           892:   static char  szTempBuff[OLEUI_CCHLABELMAX];
        !           893:   int          cxString, cyString, cxMaxString;
        !           894:   int          cxFirstLine, cyFirstLine, cxSecondLine;
        !           895:   int          index;
        !           896:   int          cch = cchString;
        !           897:   char         chKeep;
        !           898:   LPSTR        lpszSecondLine;
        !           899:   HFONT        hFontT;
        !           900:   BOOL         fPrintText = TRUE;
        !           901:   UINT         iLastLineStart = 0;
        !           902:   SIZE         size;
        !           903: 
        !           904:   // Initialization stuff...
        !           905: 
        !           906:   if (NULL == hDC)  // If we got NULL as the hDC, then we don't actually call ETO
        !           907:     fPrintText = FALSE;
        !           908: 
        !           909: 
        !           910:   // Make a copy of the string (NULL or non-NULL) that we're using
        !           911:   if (NULL == lpszString)
        !           912:     *szTempBuff = '\0';
        !           913: 
        !           914:   else 
        !           915:     lstrcpyn(szTempBuff, lpszString, sizeof(szTempBuff));
        !           916: 
        !           917:   // set maximum width
        !           918:   cxMaxString = lpRect->right - lpRect->left;
        !           919: 
        !           920:   // get screen DC to do text size calculations
        !           921:   hDCScreen = GetDC(NULL);
        !           922: 
        !           923:   hFontT=SelectObject(hDCScreen, hFont);
        !           924: 
        !           925:   // get the extent of our label
        !           926:   GetTextExtentPoint(hDCScreen, szTempBuff, cch, &size);
        !           927: 
        !           928:   cxString = size.cx;
        !           929:   cyString = size.cy;
        !           930: 
        !           931:   // Select in the font we want to use
        !           932:   if (fPrintText)
        !           933:      SelectObject(hDC, hFont);
        !           934: 
        !           935:   // String is smaller than max string - just center, ETO, and return.
        !           936:   if (cxString <= cxMaxString)
        !           937:   {
        !           938: 
        !           939:     if (fPrintText)
        !           940:        ExtTextOut(hDC, 
        !           941:                   nXStart + (lpRect->right - cxString) / 2, 
        !           942:                   nYStart, 
        !           943:                   fuOptions, 
        !           944:                   lpRect, 
        !           945:                   szTempBuff, 
        !           946:                   cch, 
        !           947:                   NULL);
        !           948: 
        !           949:     iLastLineStart = 0;  // only 1 line of text
        !           950:     goto CleanupAndLeave;
        !           951:   }
        !           952: 
        !           953:   // String is too long...we've got to word-wrap it.
        !           954: 
        !           955: 
        !           956:   // Are there any spaces, slashes, tabs, or bangs in string?
        !           957: 
        !           958:   if (lstrlen(szTempBuff) != (int)strcspn(szTempBuff, szSeparators))
        !           959:   {
        !           960:      // Yep, we've got spaces, so we'll try to find the largest 
        !           961:      // space-terminated string that will fit on the first line.
        !           962: 
        !           963:      index = cch;
        !           964:   
        !           965: 
        !           966:      while (index >= 0)
        !           967:      {
        !           968: 
        !           969:        char cchKeep;
        !           970: 
        !           971:        // scan the string backwards for spaces, slashes, tabs, or bangs
        !           972: 
        !           973:        while (!IS_SEPARATOR(szTempBuff[index]) )
        !           974:          index--;
        !           975: 
        !           976:     
        !           977:        if (index <= 0)
        !           978:          break;
        !           979: 
        !           980:        cchKeep = szTempBuff[index];  // remember what char was there
        !           981: 
        !           982:        szTempBuff[index] = '\0';  // just for now
        !           983:     
        !           984:        GetTextExtentPoint(
        !           985:                hDCScreen, (LPSTR)szTempBuff,lstrlen((LPSTR)szTempBuff),&size);
        !           986: 
        !           987:        cxFirstLine = size.cx;
        !           988:        cyFirstLine = size.cy;
        !           989: 
        !           990:        szTempBuff[index] = cchKeep;   // put the right char back
        !           991: 
        !           992:        if (cxFirstLine <= cxMaxString)
        !           993:        {
        !           994: 
        !           995:            iLastLineStart = index + 1;
        !           996: 
        !           997:            if (!fPrintText)
        !           998:              goto CleanupAndLeave;
        !           999: 
        !          1000:            ExtTextOut(hDC, 
        !          1001:                       nXStart +  (lpRect->right - cxFirstLine) / 2,
        !          1002:                       nYStart,
        !          1003:                       fuOptions,
        !          1004:                       lpRect,
        !          1005:                       (LPSTR)szTempBuff, 
        !          1006:                       index + 1, 
        !          1007:                       lpDX);
        !          1008: 
        !          1009:            lpszSecondLine = (LPSTR)szTempBuff;
        !          1010: 
        !          1011:            lpszSecondLine += index + 1;
        !          1012: 
        !          1013:            GetTextExtentPoint(hDCScreen, 
        !          1014:                                     lpszSecondLine,
        !          1015:                                     lstrlen(lpszSecondLine),
        !          1016:                                     &size);
        !          1017: 
        !          1018:            // If the second line is wider than the rectangle, we
        !          1019:            // just want to clip the text.
        !          1020:            cxSecondLine = min(size.cx, cxMaxString);
        !          1021: 
        !          1022:            ExtTextOut(hDC, 
        !          1023:                       nXStart + (lpRect->right - cxSecondLine) / 2,
        !          1024:                       nYStart + cyFirstLine, 
        !          1025:                       fuOptions,
        !          1026:                       lpRect,
        !          1027:                       lpszSecondLine,
        !          1028:                       lstrlen(lpszSecondLine),
        !          1029:                       lpDX);
        !          1030: 
        !          1031:            goto CleanupAndLeave;
        !          1032: 
        !          1033:        }  // end if
        !          1034: 
        !          1035:        index--;
        !          1036: 
        !          1037:      }  // end while
        !          1038: 
        !          1039:   }  // end if
        !          1040: 
        !          1041:   // Here, there are either no spaces in the string (strchr(szTempBuff, ' ')
        !          1042:   // returned NULL), or there spaces in the string, but they are 
        !          1043:   // positioned so that the first space terminated string is still 
        !          1044:   // longer than one line. So, we walk backwards from the end of the
        !          1045:   // string until we find the largest string that will fit on the first
        !          1046:   // line , and then we just clip the second line.
        !          1047: 
        !          1048:   cch = lstrlen((LPSTR)szTempBuff);
        !          1049: 
        !          1050:   chKeep = szTempBuff[cch];
        !          1051:   szTempBuff[cch] = '\0';
        !          1052: 
        !          1053:   GetTextExtentPoint(hDCScreen, szTempBuff, lstrlen(szTempBuff),&size);
        !          1054: 
        !          1055:   cxFirstLine = size.cx;
        !          1056:   cyFirstLine = size.cy;
        !          1057: 
        !          1058:   while (cxFirstLine > cxMaxString)
        !          1059:   {
        !          1060:      // We allow 40 characters in the label, but the metafile is 
        !          1061:      // only as wide as 10 W's (for aesthetics - 20 W's wide looked 
        !          1062:      // dumb.  This means that if we split a long string in half (in
        !          1063:      // terms of characters), then we could still be wider than the
        !          1064:      // metafile.  So, if this is the case, we just step backwards
        !          1065:      // from the halfway point until we get something that will fit.
        !          1066:      // Since we just let ETO clip the second line 
        !          1067: 
        !          1068:      szTempBuff[cch--] = chKeep;
        !          1069:      if (0 == cch) 
        !          1070:        goto CleanupAndLeave;
        !          1071: 
        !          1072:      chKeep = szTempBuff[cch];
        !          1073:      szTempBuff[cch] = '\0';
        !          1074: 
        !          1075:      GetTextExtentPoint(
        !          1076:              hDCScreen, szTempBuff, lstrlen(szTempBuff), &size);
        !          1077:      cxFirstLine = size.cx;
        !          1078:   }
        !          1079: 
        !          1080:   iLastLineStart = cch;
        !          1081: 
        !          1082:   if (!fPrintText)
        !          1083:     goto CleanupAndLeave;
        !          1084: 
        !          1085:   ExtTextOut(hDC, 
        !          1086:              nXStart + (lpRect->right - cxFirstLine) / 2,
        !          1087:              nYStart,
        !          1088:              fuOptions,
        !          1089:              lpRect,
        !          1090:              (LPSTR)szTempBuff, 
        !          1091:              lstrlen((LPSTR)szTempBuff), 
        !          1092:              lpDX);
        !          1093: 
        !          1094:   szTempBuff[cch] = chKeep;
        !          1095:   lpszSecondLine = szTempBuff;
        !          1096:   lpszSecondLine += cch;
        !          1097: 
        !          1098:   GetTextExtentPoint(
        !          1099:           hDCScreen, (LPSTR)lpszSecondLine, lstrlen(lpszSecondLine), &size);
        !          1100: 
        !          1101:   // If the second line is wider than the rectangle, we
        !          1102:   // just want to clip the text.
        !          1103:   cxSecondLine = min(size.cx, cxMaxString);
        !          1104: 
        !          1105:   ExtTextOut(hDC, 
        !          1106:              nXStart + (lpRect->right - cxSecondLine) / 2,
        !          1107:              nYStart + cyFirstLine,
        !          1108:              fuOptions,
        !          1109:              lpRect,
        !          1110:              lpszSecondLine,
        !          1111:              lstrlen(lpszSecondLine),
        !          1112:              lpDX);
        !          1113: 
        !          1114: CleanupAndLeave:
        !          1115:   SelectObject(hDCScreen, hFontT);
        !          1116:   ReleaseDC(NULL, hDCScreen);
        !          1117:   return iLastLineStart;
        !          1118: 
        !          1119: }
        !          1120: 
        !          1121: 
        !          1122: /*
        !          1123:  * OleStdGetUserTypeOfClass(REFCLSID, LPSTR, UINT, HKEY)
        !          1124:  *
        !          1125:  * Purpose:
        !          1126:  *  Returns the user type (human readable class name) of the specified class.
        !          1127:  *
        !          1128:  * Parameters:
        !          1129:  *  rclsid          pointer to the clsid to retrieve user type of.
        !          1130:  *  lpszUserType    pointer to buffer to return user type in.
        !          1131:  *  cch             length of buffer pointed to by lpszUserType
        !          1132:  *  hKey            hKey for reg db - if this is NULL, then we
        !          1133:  *                   open and close the reg db within this function.  If it 
        !          1134:  *                   is non-NULL, then we assume it's a valid key to the 
        !          1135:  *                   \ root and use it without closing it. (useful 
        !          1136:  *                   if you're doing lots of reg db stuff).
        !          1137:  *
        !          1138:  * Return Value:
        !          1139:  *  UINT            Number of characters in returned string.  0 on error.
        !          1140:  *
        !          1141:  */
        !          1142: STDAPI_(UINT) OleStdGetUserTypeOfClass(REFCLSID rclsid, LPSTR lpszUserType, UINT cch, HKEY hKey)
        !          1143: {
        !          1144: 
        !          1145:    DWORD    dw;
        !          1146:    LONG     lRet;
        !          1147:    LPSTR    lpszCLSID, lpszProgID;
        !          1148:    BOOL     fFreeProgID = FALSE;
        !          1149:    BOOL     bCloseRegDB = FALSE;
        !          1150:    char     szKey[128];
        !          1151:    LPMALLOC lpIMalloc;
        !          1152: 
        !          1153:    if (hKey == NULL)
        !          1154:    {
        !          1155: 
        !          1156:      //Open up the root key.
        !          1157:      lRet=RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey);
        !          1158: 
        !          1159:      if ((LONG)ERROR_SUCCESS!=lRet)
        !          1160:        return (UINT)FALSE;
        !          1161: 
        !          1162:      bCloseRegDB = TRUE;
        !          1163:    }
        !          1164: 
        !          1165:    // Get a string containing the class name 
        !          1166:    StringFromCLSID(rclsid, &lpszCLSID);
        !          1167: 
        !          1168:    wsprintf(szKey, "CLSID\\%s", lpszCLSID);
        !          1169: 
        !          1170: 
        !          1171:    dw=cch;
        !          1172:    lRet = RegQueryValue(hKey, szKey, lpszUserType, &dw);
        !          1173: 
        !          1174:    if ((LONG)ERROR_SUCCESS!=lRet) 
        !          1175:        dw = 0;
        !          1176: 
        !          1177:    if ( ((LONG)ERROR_SUCCESS!=lRet) && (CoIsOle1Class(rclsid)) )
        !          1178:    {
        !          1179:       // We've got an OLE 1.0 class, so let's try to get the user type
        !          1180:       // name from the ProgID entry.
        !          1181: 
        !          1182:       ProgIDFromCLSID(rclsid, &lpszProgID);
        !          1183:       fFreeProgID = TRUE;
        !          1184: 
        !          1185:       dw = cch;
        !          1186:       lRet = RegQueryValue(hKey, lpszProgID, lpszUserType, &dw);
        !          1187: 
        !          1188:       if ((LONG)ERROR_SUCCESS != lRet)
        !          1189:         dw = 0;
        !          1190:    }
        !          1191: 
        !          1192: 
        !          1193:    if (NOERROR == CoGetMalloc(MEMCTX_TASK, &lpIMalloc))
        !          1194:    {
        !          1195:        if (fFreeProgID)
        !          1196:          lpIMalloc->lpVtbl->Free(lpIMalloc, (LPVOID)lpszProgID);
        !          1197: 
        !          1198:        lpIMalloc->lpVtbl->Free(lpIMalloc, (LPVOID)lpszCLSID);
        !          1199:        lpIMalloc->lpVtbl->Release(lpIMalloc);
        !          1200:    }
        !          1201: 
        !          1202:    if (bCloseRegDB)
        !          1203:       RegCloseKey(hKey);
        !          1204: 
        !          1205:    return (UINT)dw;
        !          1206: 
        !          1207: }
        !          1208: 
        !          1209: 
        !          1210: 
        !          1211: /*
        !          1212:  * OleStdGetAuxUserType(RCLSID, WORD, LPSTR, int, HKEY)
        !          1213:  *
        !          1214:  * Purpose:
        !          1215:  *  Returns the specified AuxUserType from the reg db.
        !          1216:  *
        !          1217:  * Parameters:
        !          1218:  *  rclsid          pointer to the clsid to retrieve aux user type of.
        !          1219:  *  hKey            hKey for reg db - if this is NULL, then we
        !          1220:  *                   open and close the reg db within this function.  If it 
        !          1221:  *                   is non-NULL, then we assume it's a valid key to the 
        !          1222:  *                   \ root and use it without closing it. (useful 
        !          1223:  *                   if you're doing lots of reg db stuff).
        !          1224:  *  wAuxUserType    which aux user type field to look for.  In 4/93 release
        !          1225:  *                  2 is short name and 3 is exe name.
        !          1226:  *  lpszUserType    pointer to buffer to return user type in.
        !          1227:  *  cch             length of buffer pointed to by lpszUserType
        !          1228:  *
        !          1229:  * Return Value:
        !          1230:  *  UINT            Number of characters in returned string.  0 on error.
        !          1231:  *
        !          1232:  */
        !          1233: STDAPI_(UINT) OleStdGetAuxUserType(REFCLSID rclsid,
        !          1234:                                    WORD     wAuxUserType, 
        !          1235:                                    LPSTR    lpszAuxUserType, 
        !          1236:                                    int      cch,
        !          1237:                                    HKEY     hKey)
        !          1238: {
        !          1239:    HKEY     hThisKey;
        !          1240:    BOOL     fCloseRegDB = FALSE;
        !          1241:    DWORD    dw;
        !          1242:    LRESULT  lRet;
        !          1243:    LPSTR    lpszCLSID;
        !          1244:    LPMALLOC lpIMalloc;
        !          1245:    char     szKey[OLEUI_CCHKEYMAX];
        !          1246:    char     szTemp[32];
        !          1247: 
        !          1248:    lpszAuxUserType[0] = '\0';
        !          1249: 
        !          1250:    if (NULL == hKey)
        !          1251:    {
        !          1252:       lRet = RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hThisKey);
        !          1253: 
        !          1254:       if (ERROR_SUCCESS != lRet)
        !          1255:           return 0;
        !          1256:    }
        !          1257:    else
        !          1258:       hThisKey = hKey;
        !          1259: 
        !          1260:    StringFromCLSID(rclsid, &lpszCLSID);
        !          1261: 
        !          1262:    lstrcpy(szKey, "CLSID\\");
        !          1263:    lstrcat(szKey, lpszCLSID);
        !          1264:    wsprintf(szTemp, "\\AuxUserType\\%d", wAuxUserType);
        !          1265:    lstrcat(szKey, szTemp);
        !          1266: 
        !          1267:    dw = cch;
        !          1268: 
        !          1269:    lRet = RegQueryValue(hThisKey, szKey, lpszAuxUserType, &dw);
        !          1270: 
        !          1271:    if (ERROR_SUCCESS != lRet) {
        !          1272:      dw = 0;
        !          1273:      lpszAuxUserType[0] = '\0';
        !          1274:    }
        !          1275: 
        !          1276: 
        !          1277:    if (fCloseRegDB)
        !          1278:       RegCloseKey(hThisKey);
        !          1279: 
        !          1280:    if (NOERROR == CoGetMalloc(MEMCTX_TASK, &lpIMalloc))
        !          1281:    {
        !          1282:        lpIMalloc->lpVtbl->Free(lpIMalloc, (LPVOID)lpszCLSID);
        !          1283:        lpIMalloc->lpVtbl->Release(lpIMalloc);
        !          1284:    }
        !          1285: 
        !          1286:    return (UINT)dw;
        !          1287: }
        !          1288: 
        !          1289: 
        !          1290: 
        !          1291: /*
        !          1292:  * PointerToNthField
        !          1293:  *
        !          1294:  * Purpose:
        !          1295:  *  Returns a pointer to the beginning of the nth field.
        !          1296:  *  Assumes null-terminated string.
        !          1297:  *
        !          1298:  * Parameters:
        !          1299:  *  lpszString        string to parse
        !          1300:  *  nField            field to return starting index of.
        !          1301:  *  chDelimiter       char that delimits fields
        !          1302:  *
        !          1303:  * Return Value:
        !          1304:  *  LPSTR             pointer to beginning of nField field.
        !          1305:  *                    NOTE: If the null terminator is found
        !          1306:  *                          Before we find the Nth field, then
        !          1307:  *                          we return a pointer to the null terminator -
        !          1308:  *                          calling app should be sure to check for
        !          1309:  *                          this case.
        !          1310:  *
        !          1311:  */
        !          1312: LPSTR FAR PASCAL PointerToNthField(LPSTR lpszString, int nField, char chDelimiter)
        !          1313: {
        !          1314:    LPSTR lpField = lpszString;
        !          1315:    int   cFieldFound = 1;
        !          1316: 
        !          1317:    if (1 ==nField)
        !          1318:       return lpszString;
        !          1319: 
        !          1320:    while (*lpField != '\0')
        !          1321:    {
        !          1322: 
        !          1323:       if (*lpField++ == chDelimiter)
        !          1324:       {
        !          1325: 
        !          1326:          cFieldFound++;
        !          1327: 
        !          1328:          if (nField == cFieldFound)
        !          1329:             return lpField;
        !          1330:       }
        !          1331:    }
        !          1332: 
        !          1333:    return lpField;
        !          1334: 
        !          1335: }
        !          1336: 
        !          1337: 
        !          1338: 
        !          1339: 
        !          1340: 
        !          1341: /*
        !          1342:  * XformWidthInPixelsToHimetric
        !          1343:  * XformWidthInHimetricToPixels
        !          1344:  * XformHeightInPixelsToHimetric
        !          1345:  * XformHeightInHimetricToPixels
        !          1346:  *
        !          1347:  * Functions to convert an int between a device coordinate system and
        !          1348:  * logical HiMetric units.
        !          1349:  *
        !          1350:  * Parameters:
        !          1351:  *  hDC             HDC providing reference to the pixel mapping.  If
        !          1352:  *                  NULL, a screen DC is used.
        !          1353:  *
        !          1354:  *  Size Functions:
        !          1355:  *  lpSizeSrc       LPSIZEL providing the structure to convert.  This
        !          1356:  *                  contains pixels in XformSizeInPixelsToHimetric and
        !          1357:  *                  logical HiMetric units in the complement function.
        !          1358:  *  lpSizeDst       LPSIZEL providing the structure to receive converted
        !          1359:  *                  units.  This contains pixels in 
        !          1360:  *                  XformSizeInPixelsToHimetric and logical HiMetric
        !          1361:  *                  units in the complement function.
        !          1362:  *
        !          1363:  *  Width Functions:
        !          1364:  *  iWidth          int containing the value to convert.
        !          1365:  *
        !          1366:  * Return Value:
        !          1367:  *  Size Functions:     None
        !          1368:  *  Width Functions:    Converted value of the input parameters.
        !          1369:  *
        !          1370:  * NOTE:
        !          1371:  *  When displaying on the screen, Window apps display everything enlarged
        !          1372:  *  from its actual size so that it is easier to read. For example, if an
        !          1373:  *  app wants to display a 1in. horizontal line, that when printed is
        !          1374:  *  actually a 1in. line on the printed page, then it will display the line
        !          1375:  *  on the screen physically larger than 1in. This is described as a line
        !          1376:  *  that is "logically" 1in. along the display width. Windows maintains as
        !          1377:  *  part of the device-specific information about a given display device:
        !          1378:  *      LOGPIXELSX -- no. of pixels per logical in along the display width
        !          1379:  *      LOGPIXELSY -- no. of pixels per logical in along the display height
        !          1380:  *
        !          1381:  *  The following formula converts a distance in pixels into its equivalent
        !          1382:  *  logical HIMETRIC units:
        !          1383:  *
        !          1384:  *      DistInHiMetric = (HIMETRIC_PER_INCH * DistInPix)
        !          1385:  *                       -------------------------------
        !          1386:  *                           PIXELS_PER_LOGICAL_IN
        !          1387:  *
        !          1388:  */
        !          1389: STDAPI_(int) XformWidthInPixelsToHimetric(HDC hDC, int iWidthInPix)
        !          1390:     {
        !          1391:     int     iXppli;     //Pixels per logical inch along width
        !          1392:     int     iWidthInHiMetric;
        !          1393:     BOOL    fSystemDC=FALSE;
        !          1394: 
        !          1395:     if (NULL==hDC)
        !          1396:         {
        !          1397:         hDC=GetDC(NULL);
        !          1398:         fSystemDC=TRUE;
        !          1399:         }
        !          1400: 
        !          1401:     iXppli = GetDeviceCaps (hDC, LOGPIXELSX);
        !          1402: 
        !          1403:     //We got pixel units, convert them to logical HIMETRIC along the display
        !          1404:     iWidthInHiMetric = MAP_PIX_TO_LOGHIM(iWidthInPix, iXppli);
        !          1405: 
        !          1406:     if (fSystemDC)
        !          1407:         ReleaseDC(NULL, hDC);
        !          1408: 
        !          1409:     return iWidthInHiMetric;
        !          1410:     }
        !          1411: 
        !          1412: 
        !          1413: STDAPI_(int) XformWidthInHimetricToPixels(HDC hDC, int iWidthInHiMetric)
        !          1414:     {
        !          1415:     int     iXppli;     //Pixels per logical inch along width
        !          1416:     int     iWidthInPix;
        !          1417:     BOOL    fSystemDC=FALSE;
        !          1418: 
        !          1419:     if (NULL==hDC)
        !          1420:         {
        !          1421:         hDC=GetDC(NULL);
        !          1422:         fSystemDC=TRUE;
        !          1423:         }
        !          1424: 
        !          1425:     iXppli = GetDeviceCaps (hDC, LOGPIXELSX);
        !          1426: 
        !          1427:     //We got logical HIMETRIC along the display, convert them to pixel units
        !          1428:     iWidthInPix = MAP_LOGHIM_TO_PIX(iWidthInHiMetric, iXppli);
        !          1429: 
        !          1430:     if (fSystemDC)
        !          1431:         ReleaseDC(NULL, hDC);
        !          1432: 
        !          1433:     return iWidthInPix;
        !          1434:     }
        !          1435: 
        !          1436: 
        !          1437: STDAPI_(int) XformHeightInPixelsToHimetric(HDC hDC, int iHeightInPix)
        !          1438:     {
        !          1439:     int     iYppli;     //Pixels per logical inch along height
        !          1440:     int     iHeightInHiMetric;
        !          1441:     BOOL    fSystemDC=FALSE;
        !          1442: 
        !          1443:     if (NULL==hDC)
        !          1444:         {
        !          1445:         hDC=GetDC(NULL);
        !          1446:         fSystemDC=TRUE;
        !          1447:         }
        !          1448: 
        !          1449:     iYppli = GetDeviceCaps (hDC, LOGPIXELSY);
        !          1450: 
        !          1451:     //* We got pixel units, convert them to logical HIMETRIC along the display
        !          1452:     iHeightInHiMetric = MAP_PIX_TO_LOGHIM(iHeightInPix, iYppli);
        !          1453: 
        !          1454:     if (fSystemDC)
        !          1455:         ReleaseDC(NULL, hDC);
        !          1456: 
        !          1457:     return iHeightInHiMetric;
        !          1458:     }
        !          1459: 
        !          1460: 
        !          1461: STDAPI_(int) XformHeightInHimetricToPixels(HDC hDC, int iHeightInHiMetric)
        !          1462:     {
        !          1463:     int     iYppli;     //Pixels per logical inch along height
        !          1464:     int     iHeightInPix;
        !          1465:     BOOL    fSystemDC=FALSE;
        !          1466: 
        !          1467:     if (NULL==hDC)
        !          1468:         {
        !          1469:         hDC=GetDC(NULL);
        !          1470:         fSystemDC=TRUE;
        !          1471:         }
        !          1472: 
        !          1473:     iYppli = GetDeviceCaps (hDC, LOGPIXELSY);
        !          1474: 
        !          1475:     //* We got logical HIMETRIC along the display, convert them to pixel units
        !          1476:     iHeightInPix = MAP_LOGHIM_TO_PIX(iHeightInHiMetric, iYppli);
        !          1477: 
        !          1478:     if (fSystemDC)
        !          1479:         ReleaseDC(NULL, hDC);
        !          1480: 
        !          1481:     return iHeightInPix;
        !          1482:     }

unix.superglobalmegacorp.com

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