Annotation of mstools/ole20/samples/ole2ui/geticon.c, revision 1.1.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.