|
|
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.