|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.