GETICON.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:31k
源码类别:
Windows编程
开发平台:
Visual C++
- /*************************************************************************
- **
- ** The following API's are now OBSOLETE because equivalent API's have been
- ** added to the OLE2.DLL library
- ** GetIconOfFile superceeded by OleGetIconOfFile
- ** GetIconOfClass superceeded by OleGetIconOfClass
- ** OleUIMetafilePictFromIconAndLabel
- ** superceeded by OleMetafilePictFromIconAndLabel
- *************************************************************************/
- /*
- * GETICON.C
- *
- * Functions to create DVASPECT_ICON metafile from filename or classname.
- *
- * GetIconOfFile
- * GetIconOfClass
- * OleUIMetafilePictFromIconAndLabel
- * HIconAndSourceFromClass Extracts the first icon in a class's server path
- * and returns the path and icon index to caller.
- * FIconFileFromClass Retrieves the path to the exe/dll containing the
- * default icon, and the index of the icon.
- * OleStdIconLabelTextOut Draw icon label text (line break if necessary)
- *
- * (c) Copyright Microsoft Corp. 1992-1996 All Rights Reserved
- */
- /*******
- *
- * ICON (DVASPECT_ICON) METAFILE FORMAT:
- *
- * The metafile generated with OleUIMetafilePictFromIconAndLabel contains
- * the following records which are used by the functions in DRAWICON.C
- * to draw the icon with and without the label and to extract the icon,
- * label, and icon source/index.
- *
- * SetWindowOrg
- * SetWindowExt
- * DrawIcon:
- * Inserts records of DIBBITBLT or DIBSTRETCHBLT, once for the
- * AND mask, one for the image bits.
- * Escape with the comment "IconOnly"
- * This indicates where to stop record enumeration to draw only
- * the icon.
- * SetTextColor
- * SetTextAlign
- * SetBkColor
- * CreateFont
- * SelectObject on the font.
- * ExtTextOut
- * One or more ExtTextOuts occur if the label is wrapped. The
- * text in these records is used to extract the label.
- * SelectObject on the old font.
- * DeleteObject on the font.
- * Escape with a comment that contains the path to the icon source.
- * Escape with a comment that is the ASCII of the icon index.
- *
- *******/
- #define STRICT 1
- #include "olestd.h"
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <commdlg.h>
- #include <memory.h>
- #include <cderr.h>
- #include "common.h"
- #include "utility.h"
- static char szSeparators[] = " t\/!:";
- #define IS_SEPARATOR(c) ( (c) == ' ' || (c) == '\' || (c) == '/' || (c) == 't' || (c) == '!' || (c) == ':' )
- #define IS_FILENAME_DELIM(c) ( (c) == '\' || (c) == '/' || (c) == ':' )
- #if defined( OBSOLETE )
- static HINSTANCE s_hInst;
- static char szMaxWidth[] ="WWWWWWWWWW";
- //Strings for metafile comments.
- static OLECHAR szIconOnly[]= OLESTR("IconOnly"); //Where to stop to exclude label.
- static char szOLE2DLL[] = "ole2.dll"; // name of OLE 2.0 library
- #define ICONINDEX 0
- #define AUXUSERTYPE_SHORTNAME USERCLASSTYPE_SHORT // short name
- #define HIMETRIC_PER_INCH 2540 // number HIMETRIC units per inch
- #define PTS_PER_INCH 72 // number points (font size) per inch
- #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
- #define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH)
- static char szVanillaDocIcon[] = "DefIcon";
- static char szDocument[40] = "";
- /*
- * GetIconOfFile(HINSTANCE hInst, LPSTR lpszPath, BOOL fUseFileAsLabel)
- *
- * Purpose:
- * Returns a hMetaPict containing an icon and label (filename) for the
- * specified filename.
- *
- * Parameters:
- * hinst
- * lpszPath LPSTR path including filename to use
- * fUseFileAsLabel BOOL TRUE if the icon's label is the filename, FALSE if
- * there should be no label.
- *
- * Return Value:
- * HGLOBAL hMetaPict containing the icon and label - if there's no
- * class in reg db for the file in lpszPath, then we use
- * Document. If lpszPath is NULL, then we return NULL.
- */
- STDAPI_(HGLOBAL) GetIconOfFile(HINSTANCE hInst, LPSTR lpszPath, BOOL fUseFileAsLabel)
- {
- char szIconFile[OLEUI_CCHPATHMAX];
- char szLabel[OLEUI_CCHLABELMAX];
- LPSTR lpszClsid = NULL;
- CLSID clsid;
- HICON hDefIcon = NULL;
- UINT IconIndex = 0;
- HGLOBAL hMetaPict;
- HRESULT hResult;
- if (NULL == lpszPath) // even if fUseFileAsLabel is FALSE, we still
- return NULL; // need a valid filename to get the class.
- s_hInst = hInst;
- hResult = GetClassFile(lpszPath, &clsid);
- if (NOERROR == hResult) // use the clsid we got to get to the icon
- {
- hDefIcon = HIconAndSourceFromClass(&clsid,
- szIconFile,
- &IconIndex);
- }
- if ( (NOERROR != hResult) || (NULL == hDefIcon) )
- {
- // Here, either GetClassFile failed or HIconAndSourceFromClass failed.
- LPSTR lpszTemp;
- lpszTemp = lpszPath;
- while ((*lpszTemp != '.') && (*lpszTemp != ' '))
- lpszTemp++;
- if ('.' != *lpszTemp)
- goto UseVanillaDocument;
- if (FALSE == GetAssociatedExecutable(lpszTemp, szIconFile))
- goto UseVanillaDocument;
- hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex);
- }
- if (hDefIcon <= (HICON)1) // ExtractIcon returns 1 if szExecutable is not exe,
- { // 0 if there are no icons.
- UseVanillaDocument:
- OLESTRCPY(szIconFile, szOLE2DLL);
- IconIndex = ICONINDEX;
- hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex);
- }
- // Now let's get the label we want to use.
- if (fUseFileAsLabel) // strip off path, so we just have the filename.
- {
- int istrlen;
- LPSTR lpszBeginFile;
- istrlen = lstrlen(lpszPath);
- // set pointer to END of path, so we can walk backwards through it.
- lpszBeginFile = lpszPath + istrlen -1;
- while ( (lpszBeginFile >= lpszPath)
- && (!IS_FILENAME_DELIM(*lpszBeginFile)) )
- lpszBeginFile--;
- lpszBeginFile++; // step back over the delimiter
- LSTRCPYN(szLabel, lpszBeginFile, OLEUI_CCHLABELMAX);
- }
- else // use the short user type (AuxUserType2) for the label
- {
- if (0 == OleStdGetAuxUserType(&clsid, AUXUSERTYPE_SHORTNAME,
- szLabel, OLEUI_CCHLABELMAX, NULL)) {
- if (' '==szDocument[0]) {
- LoadString(
- s_hInst,IDS_DEFICONLABEL,szDocument,sizeof(szDocument));
- }
- lstrcpy(szLabel, szDocument);
- }
- }
- hMetaPict = OleUIMetafilePictFromIconAndLabel(hDefIcon,
- szLabel,
- szIconFile,
- IconIndex);
- DestroyIcon(hDefIcon);
- return hMetaPict;
- }
- /*
- * GetIconOfClass(HINSTANCE hInst, REFCLSID rclsid, LPSTR lpszLabel, BOOL fUseTypeAsLabel)
- *
- * Purpose:
- * Returns a hMetaPict containing an icon and label (human-readable form
- * of class) for the specified clsid.
- *
- * Parameters:
- * hinst
- * rclsid REFCLSID pointing to clsid to use.
- * lpszLabel label to use for icon.
- * fUseTypeAsLabel Use the clsid's user type name as the icon's label.
- *
- * Return Value:
- * HGLOBAL hMetaPict containing the icon and label - if we
- * don't find the clsid in the reg db then we
- * return NULL.
- */
- STDAPI_(HGLOBAL) GetIconOfClass(HINSTANCE hInst, REFCLSID rclsid, LPSTR lpszLabel, BOOL fUseTypeAsLabel)
- {
- char szLabel[OLEUI_CCHLABELMAX];
- char szIconFile[OLEUI_CCHPATHMAX];
- HICON hDefIcon;
- UINT IconIndex;
- HGLOBAL hMetaPict;
- s_hInst = hInst;
- if (!fUseTypeAsLabel) // Use string passed in as label
- {
- if (NULL != lpszLabel)
- LSTRCPYN(szLabel, lpszLabel, sizeof(szLabel));
- else
- *szLabel = ' ';
- }
- else // Use AuxUserType2 (short name) as label
- {
- if (0 == OleStdGetAuxUserType(rclsid,
- AUXUSERTYPE_SHORTNAME,
- szLabel,
- OLEUI_CCHLABELMAX,
- NULL))
- // If we can't get the AuxUserType2, then try the long name
- if (0 == OleStdGetUserTypeOfClass(rclsid, szLabel, OLEUI_CCHKEYMAX, NULL)) {
- if (' '==szDocument[0]) {
- LoadString(
- s_hInst,IDS_DEFICONLABEL,szDocument,sizeof(szDocument));
- }
- lstrcpy(szLabel, szDocument); // last resort
- }
- }
- // Get the icon, icon index, and path to icon file
- hDefIcon = HIconAndSourceFromClass(rclsid,
- szIconFile,
- &IconIndex);
- if (NULL == hDefIcon) // Use Vanilla Document
- {
- OLESTRCPY(szIconFile, szOLE2DLL);
- IconIndex = ICONINDEX;
- hDefIcon = ExtractIcon(s_hInst, szIconFile, IconIndex);
- }
- // Create the metafile
- hMetaPict = OleUIMetafilePictFromIconAndLabel(hDefIcon, szLabel,
- szIconFile, IconIndex);
- DestroyIcon(hDefIcon);
- return hMetaPict;
- }
- /*
- * OleUIMetafilePictFromIconAndLabel
- *
- * Purpose:
- * Creates a METAFILEPICT structure that container a metafile in which
- * the icon and label are drawn. A comment record is inserted between
- * the icon and the label code so our special draw function can stop
- * playing before the label.
- *
- * Parameters:
- * hIcon HICON to draw into the metafile
- * pszLabel LPSTR to the label string.
- * pszSourceFile LPSTR containing the local pathname of the icon
- * as we either get from the user or from the reg DB.
- * iIcon UINT providing the index into pszSourceFile where
- * the icon came from.
- *
- * Return Value:
- * HGLOBAL Global memory handle containing a METAFILEPICT where
- * the metafile uses the MM_ANISOTROPIC mapping mode. The
- * extents reflect both icon and label.
- */
- STDAPI_(HGLOBAL) OleUIMetafilePictFromIconAndLabel(HICON hIcon, LPSTR pszLabel
- , LPSTR pszSourceFile, UINT iIcon)
- {
- HDC hDC, hDCScreen;
- HMETAFILE hMF;
- HGLOBAL hMem;
- LPMETAFILEPICT pMF;
- UINT cxIcon, cyIcon;
- UINT cxText, cyText;
- UINT cx, cy;
- UINT cchLabel = 0;
- HFONT hFont, hFontT;
- int cyFont;
- char szIndex[10];
- RECT TextRect;
- SIZE size;
- POINT point;
- UINT fuAlign;
- if (NULL==hIcon) // null label is valid but NOT a null icon
- return NULL;
- //Create a memory metafile
- hDC=(HDC)CreateMetaFile(NULL);
- if (NULL==hDC)
- return NULL;
- //Allocate the metafilepict
- hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(METAFILEPICT));
- if (NULL==hMem)
- {
- hMF=CloseMetaFile(hDC);
- DeleteMetaFile(hMF);
- return NULL;
- }
- if (NULL!=pszLabel)
- {
- cchLabel=lstrlen(pszLabel);
- if (cchLabel >= OLEUI_CCHLABELMAX)
- pszLabel[cchLabel] = ' '; // truncate string
- }
- //Need to use the screen DC for these operations
- hDCScreen=GetDC(NULL);
- cyFont=-(8*GetDeviceCaps(hDCScreen, LOGPIXELSY))/72;
- //cyFont was calculated to give us 8 point.
- hFont=CreateFont(cyFont, 5, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET
- , OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY
- , FF_SWISS, "MS Sans Serif");
- hFontT=SelectObject(hDCScreen, hFont);
- GetTextExtentPoint(hDCScreen,szMaxWidth,lstrlen(szMaxWidth),&size);
- SelectObject(hDCScreen, hFontT);
- cxText = size.cx;
- cyText = size.cy * 2;
- cxIcon = GetSystemMetrics(SM_CXICON);
- cyIcon = GetSystemMetrics(SM_CYICON);
- // If we have no label, then we want the metafile to be the width of
- // the icon (plus margin), not the width of the fattest string.
- if ( (NULL == pszLabel) || (' ' == *pszLabel) )
- cx = cxIcon + cxIcon / 4;
- else
- cx = max(cxText, cxIcon);
- cy=cyIcon+cyText+4;
- //Set the metafile size to fit the icon and label
- SetWindowOrgEx(hDC, 0, 0, &point);
- SetWindowExtEx(hDC, cx, cy, &size);
- //Set up rectangle to pass to OleStdIconLabelTextOut
- SetRectEmpty(&TextRect);
- TextRect.right = cx;
- TextRect.bottom = cy;
- //Draw the icon and the text, centered with respect to each other.
- DrawIcon(hDC, (cx-cxIcon)/2, 0, hIcon);
- //String that indicates where to stop if we're only doing icons
- Escape(hDC, MFCOMMENT, lstrlen(szIconOnly)+1, szIconOnly, NULL);
- SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
- SetBkMode(hDC, TRANSPARENT);
- fuAlign = SetTextAlign(hDC, TA_LEFT | TA_TOP | TA_NOUPDATECP);
- OleStdIconLabelTextOut(hDC,
- hFont,
- 0,
- cy - cyText,
- ETO_CLIPPED,
- &TextRect,
- pszLabel,
- cchLabel,
- NULL);
- //Write comments containing the icon source file and index.
- if (NULL!=pszSourceFile)
- {
- //+1 on string lengths insures the null terminator is embedded.
- Escape(hDC, MFCOMMENT, lstrlen(pszSourceFile)+1, pszSourceFile, NULL);
- cchLabel=wsprintf(szIndex, "%u", iIcon);
- Escape(hDC, MFCOMMENT, cchLabel+1, szIndex, NULL);
- }
- SetTextAlign(hDC, fuAlign);
- //All done with the metafile, now stuff it all into a METAFILEPICT.
- hMF=CloseMetaFile(hDC);
- if (NULL==hMF)
- {
- GlobalFree(hMem);
- ReleaseDC(NULL, hDCScreen);
- return NULL;
- }
- //Fill out the structure
- pMF=(LPMETAFILEPICT)GlobalLock(hMem);
- //Transform to HIMETRICS
- cx=XformWidthInPixelsToHimetric(hDCScreen, cx);
- cy=XformHeightInPixelsToHimetric(hDCScreen, cy);
- ReleaseDC(NULL, hDCScreen);
- pMF->mm=MM_ANISOTROPIC;
- pMF->xExt=cx;
- pMF->yExt=cy;
- pMF->hMF=hMF;
- GlobalUnlock(hMem);
- DeleteObject(hFont);
- return hMem;
- }
- #endif // OBSOLETE
- /*
- * GetAssociatedExecutable
- *
- * Purpose: Finds the executable associated with the provided extension
- *
- * Parameters:
- * lpszExtension LPSTR points to the extension we're trying to find
- * an exe for. Does **NO** validation.
- *
- * lpszExecutable LPSTR points to where the exe name will be returned.
- * No validation here either - pass in 128 char buffer.
- *
- * Return:
- * BOOL TRUE if we found an exe, FALSE if we didn't.
- *
- */
- BOOL FAR PASCAL GetAssociatedExecutable(LPSTR lpszExtension, LPSTR lpszExecutable)
- {
- HKEY hKey;
- LONG dw;
- LRESULT lRet;
- char szValue[OLEUI_CCHKEYMAX];
- char szKey[OLEUI_CCHKEYMAX];
- LPSTR lpszTemp, lpszExe;
- lRet = RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hKey);
- if (ERROR_SUCCESS != lRet)
- return FALSE;
- dw = OLEUI_CCHPATHMAX;
- lRet = RegQueryValue(hKey, lpszExtension, szValue, &dw); //ProgId
- if (ERROR_SUCCESS != lRet)
- {
- RegCloseKey(hKey);
- return FALSE;
- }
- // szValue now has ProgID
- lstrcpy(szKey, szValue);
- lstrcat(szKey, "\Shell\Open\Command");
- dw = OLEUI_CCHPATHMAX;
- lRet = RegQueryValue(hKey, szKey, szValue, &dw);
- if (ERROR_SUCCESS != lRet)
- {
- RegCloseKey(hKey);
- return FALSE;
- }
- // szValue now has an executable name in it. Let's null-terminate
- // at the first post-executable space (so we don't have cmd line
- // args.
- lpszTemp = szValue;
- while ((' ' != *lpszTemp) && (isspace(*lpszTemp)))
- lpszTemp++; // Strip off leading spaces
- lpszExe = lpszTemp;
- while ((' ' != *lpszTemp) && (!isspace(*lpszTemp)))
- lpszTemp++; // Step through exe name
- *lpszTemp = ' '; // null terminate at first space (or at end).
- lstrcpy(lpszExecutable, lpszExe);
- return TRUE;
- }
- /*
- * HIconAndSourceFromClass
- *
- * Purpose:
- * Given an object class name, finds an associated executable in the
- * registration database and extracts the first icon from that
- * executable. If none is available or the class has no associated
- * executable, this function returns NULL.
- *
- * Parameters:
- * rclsid pointer to clsid to look up.
- * pszSource LPSTR in which to place the source of the icon.
- * This is assumed to be OLEUI_CCHPATHMAX
- * puIcon UINT FAR * in which to store the index of the
- * icon in pszSource.
- *
- * Return Value:
- * HICON Handle to the extracted icon if there is a module
- * associated to pszClass. NULL on failure to either
- * find the executable or extract and icon.
- */
- HICON FAR PASCAL HIconAndSourceFromClass(REFCLSID rclsid, LPSTR pszSource, UINT FAR *puIcon)
- {
- HICON hIcon;
- UINT IconIndex;
- if (NULL==rclsid || NULL==pszSource || IsEqualCLSID(rclsid,&CLSID_NULL))
- return NULL;
- if (!FIconFileFromClass(rclsid, pszSource, OLEUI_CCHPATHMAX, &IconIndex))
- return NULL;
- hIcon=ExtractIcon(ghInst, pszSource, IconIndex);
- if ((HICON)32 > hIcon)
- hIcon=NULL;
- else
- *puIcon= IconIndex;
- return hIcon;
- }
- /*
- * PointerToNthField
- *
- * Purpose:
- * Returns a pointer to the beginning of the nth field.
- * Assumes null-terminated string.
- *
- * Parameters:
- * lpszString string to parse
- * nField field to return starting index of.
- * chDelimiter char that delimits fields
- *
- * Return Value:
- * LPSTR pointer to beginning of nField field.
- * NOTsE: If the null terminator is found
- * Before we find the Nth field, then
- * we return a pointer to the null terminator -
- * calling app should be sure to check for
- * this case.
- *
- */
- LPSTR FAR PASCAL PointerToNthField(LPSTR lpszString, int nField, char chDelimiter)
- {
- LPSTR lpField = lpszString;
- int cFieldFound = 1;
- if (1 ==nField)
- return lpszString;
- while (*lpField != ' ')
- {
- if (*lpField++ == chDelimiter)
- {
- cFieldFound++;
- if (nField == cFieldFound)
- return lpField;
- }
- }
- return lpField;
- }
- /*
- * FIconFileFromClass
- *
- * Purpose:
- * Looks up the path to executable that contains the class default icon.
- *
- * Parameters:
- * rclsid pointer to CLSID to look up.
- * pszEXE LPSTR at which to store the server name
- * cch UINT size of pszEXE
- * lpIndex LPUINT to index of icon within executable
- *
- * Return Value:
- * BOOL TRUE if one or more characters were loaded into pszEXE.
- * FALSE otherwise.
- */
- BOOL FAR PASCAL FIconFileFromClass(REFCLSID rclsid, LPSTR pszEXE, UINT cch, UINT FAR *lpIndex)
- {
- LONG dw;
- LONG lRet;
- HKEY hKey;
- LPMALLOC lpIMalloc;
- HRESULT hrErr;
- LPSTR lpBuffer;
- LPSTR lpIndexString;
- UINT cBufferSize = 136;// room for 128 char path and icon's index
- char szKey[64];
- char pszClass[256];
- LPOLESTR pszUniClass;
- if (NULL==rclsid || NULL==pszEXE || 0==cch || IsEqualCLSID(rclsid,&CLSID_NULL))
- return FALSE;
- //Here, we use CoGetMalloc and alloc a buffer (maxpathlen + 8) to
- //pass to RegQueryValue. Then, we copy the exe to pszEXE and the
- //index to *lpIndex.
- hrErr = CoGetMalloc(MEMCTX_TASK, &lpIMalloc);
- if (NOERROR != hrErr)
- return FALSE;
- lpBuffer = /*(LPSTR)*/lpIMalloc->lpVtbl->Alloc(lpIMalloc, cBufferSize);
- if (NULL == lpBuffer)
- {
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return FALSE;
- }
- if (CoIsOle1Class(rclsid))
- {
- LPOLESTR lpszUniProgID;
- char lpszProgID[256];
- // we've got an ole 1.0 class on our hands, so we look at
- // progIDprotocolstdfileedtingserver to get the
- // name of the executable.
- ProgIDFromCLSID(rclsid, &lpszUniProgID);
- W2A (lpszUniProgID, lpszProgID, 256);
- //Open up the class key
- lRet=RegOpenKey(HKEY_CLASSES_ROOT, lpszProgID, &hKey);
- if (ERROR_SUCCESS != lRet)
- {
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpszUniProgID);
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return FALSE;
- }
- dw=(LONG)cBufferSize;
- lRet = RegQueryValue(hKey, "Protocol\StdFileEditing\Server", lpBuffer, &dw);
- if (ERROR_SUCCESS != lRet)
- {
- RegCloseKey(hKey);
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpszUniProgID);
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return FALSE;
- }
- // Use server and 0 as the icon index
- LSTRCPYN(pszEXE, lpBuffer, cch);
- *lpIndex = 0;
- RegCloseKey(hKey);
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpszUniProgID);
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return TRUE;
- }
- /*
- * We have to go walking in the registration database under the
- * classname, so we first open the classname key and then check
- * under "\DefaultIcon" to get the file that contains the icon.
- */
- StringFromCLSID(rclsid, &pszUniClass);
- W2A (pszUniClass, pszClass, 256);
- lstrcpy(szKey, "CLSID\");
- lstrcat(szKey, pszClass);
- //Open up the class key
- lRet=RegOpenKey(HKEY_CLASSES_ROOT, szKey, &hKey);
- if (ERROR_SUCCESS != lRet)
- {
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Free(lpIMalloc, pszUniClass);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return FALSE;
- }
- //Get the executable path and icon index.
- dw=(LONG)cBufferSize;
- lRet=RegQueryValue(hKey, "DefaultIcon", lpBuffer, &dw);
- if (ERROR_SUCCESS != lRet)
- {
- // no DefaultIcon key...try LocalServer
- dw=(LONG)cBufferSize;
- #ifdef WIN32
- lRet=RegQueryValue(hKey, "LocalServer32", lpBuffer, &dw);
- #else
- lRet=RegQueryValue(hKey, "LocalServer", lpBuffer, &dw);
- #endif
- if (ERROR_SUCCESS != lRet)
- {
- // no LocalServer entry either...they're outta luck.
- RegCloseKey(hKey);
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Free(lpIMalloc, pszUniClass);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return FALSE;
- }
- // Use server from LocalServer or Server and 0 as the icon index
- LSTRCPYN(pszEXE, lpBuffer, cch);
- *lpIndex = 0;
- RegCloseKey(hKey);
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Free(lpIMalloc, pszUniClass);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return TRUE;
- }
- RegCloseKey(hKey);
- // lpBuffer contains a string that looks like "<pathtoexe>,<iconindex>",
- // so we need to separate the path and the icon index.
- lpIndexString = PointerToNthField(lpBuffer, 2, ',');
- if (' ' == *lpIndexString) // no icon index specified - use 0 as default.
- {
- *lpIndex = 0;
- }
- else
- {
- LPSTR lpTemp;
- static char szTemp[16];
- lstrcpy(szTemp, lpIndexString);
- // Put the icon index part into *pIconIndex
- *lpIndex = atoi((const char *)szTemp);
- // Null-terminate the exe part.
- lpTemp = AnsiPrev(lpBuffer, lpIndexString);
- *lpTemp = ' ';
- }
- if (!LSTRCPYN(pszEXE, lpBuffer, cch))
- {
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Free(lpIMalloc, pszUniClass);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return FALSE;
- }
- // Free the memory we alloc'd and leave.
- lpIMalloc->lpVtbl->Free(lpIMalloc, lpBuffer);
- lpIMalloc->lpVtbl->Free(lpIMalloc, pszUniClass);
- lpIMalloc->lpVtbl->Release(lpIMalloc);
- return TRUE;
- }
- /*
- * OleStdIconLabelTextOut
- *
- * Purpose:
- * Replacement for DrawText to be used in the "Display as Icon" metafile.
- * Uses ExtTextOut to output a string center on (at most) two lines.
- * Uses a very simple word wrap algorithm to split the lines.
- *
- * Parameters: (same as for ExtTextOut, except for hFont)
- * hDC device context to draw into; if this is NULL, then we don't
- * ETO the text, we just return the index of the beginning
- * of the second line
- * hFont font to use
- * nXStart x-coordinate of starting position
- * nYStart y-coordinate of starting position
- * fuOptions rectangle type
- * lpRect rect far * containing rectangle to draw text in.
- * lpszString string to draw
- * cchString length of string (truncated if over OLEUI_CCHLABELMAX)
- * lpDX spacing between character cells
- *
- * Return Value:
- * UINT Index of beginning of last line (0 if there's only one
- * line of text).
- *
- */
- STDAPI_(UINT) OleStdIconLabelTextOut(HDC hDC,
- HFONT hFont,
- int nXStart,
- int nYStart,
- UINT fuOptions,
- RECT FAR * lpRect,
- LPOLESTR lpszString,
- UINT cchString,
- int FAR * lpDX)
- {
- HDC hDCScreen;
- static char szTempBuff[OLEUI_CCHLABELMAX];
- int cxString, cyString, cxMaxString;
- int cxFirstLine, cyFirstLine, cxSecondLine;
- int index;
- int cch = cchString;
- char chKeep;
- LPSTR lpszSecondLine;
- HFONT hFontT;
- BOOL fPrintText = TRUE;
- UINT iLastLineStart = 0;
- SIZE size;
- // Initialization stuff...
- if (NULL == hDC) // If we got NULL as the hDC, then we don't actually call ETO
- fPrintText = FALSE;
- // Make a copy of the string (NULL or non-NULL) that we're using
- if (NULL == lpszString)
- *szTempBuff = ' ';
- else
- {
- W2A (lpszString, szTempBuff, OLEUI_CCHLABELMAX);
- }
- // set maximum width
- cxMaxString = lpRect->right - lpRect->left;
- // get screen DC to do text size calculations
- hDCScreen = GetDC(NULL);
- hFontT=SelectObject(hDCScreen, hFont);
- // get the extent of our label
- GetTextExtentPoint(hDCScreen, szTempBuff, cch, &size);
- cxString = size.cx;
- cyString = size.cy;
- // Select in the font we want to use
- if (fPrintText)
- SelectObject(hDC, hFont);
- // String is smaller than max string - just center, ETO, and return.
- if (cxString <= cxMaxString)
- {
- if (fPrintText)
- ExtTextOut(hDC,
- nXStart + (lpRect->right - cxString) / 2,
- nYStart,
- fuOptions,
- lpRect,
- szTempBuff,
- cch,
- NULL);
- iLastLineStart = 0; // only 1 line of text
- goto CleanupAndLeave;
- }
- // String is too long...we've got to word-wrap it.
- // Are there any spaces, slashes, tabs, or bangs in string?
- if (lstrlen(szTempBuff) != (int)strcspn(szTempBuff, szSeparators))
- {
- // Yep, we've got spaces, so we'll try to find the largest
- // space-terminated string that will fit on the first line.
- index = cch;
- while (index >= 0)
- {
- char cchKeep;
- // scan the string backwards for spaces, slashes, tabs, or bangs
- while (!IS_SEPARATOR(szTempBuff[index]) )
- index--;
- if (index <= 0)
- break;
- cchKeep = szTempBuff[index]; // remember what char was there
- szTempBuff[index] = ' '; // just for now
- GetTextExtentPoint(
- hDCScreen, szTempBuff,lstrlen(szTempBuff),&size);
- cxFirstLine = size.cx;
- cyFirstLine = size.cy;
- szTempBuff[index] = cchKeep; // put the right char back
- if (cxFirstLine <= cxMaxString)
- {
- iLastLineStart = index + 1;
- if (!fPrintText)
- goto CleanupAndLeave;
- ExtTextOut(hDC,
- nXStart + (lpRect->right - cxFirstLine) / 2,
- nYStart,
- fuOptions,
- lpRect,
- szTempBuff,
- index + 1,
- lpDX);
- lpszSecondLine = szTempBuff;
- lpszSecondLine += index + 1;
- GetTextExtentPoint(hDCScreen,
- lpszSecondLine,
- lstrlen(lpszSecondLine),
- &size);
- // If the second line is wider than the rectangle, we
- // just want to clip the text.
- cxSecondLine = min(size.cx, cxMaxString);
- ExtTextOut(hDC,
- nXStart + (lpRect->right - cxSecondLine) / 2,
- nYStart + cyFirstLine,
- fuOptions,
- lpRect,
- lpszSecondLine,
- lstrlen(lpszSecondLine),
- lpDX);
- goto CleanupAndLeave;
- } // end if
- index--;
- } // end while
- } // end if
- // Here, there are either no spaces in the string (strchr(szTempBuff, ' ')
- // returned NULL), or there spaces in the string, but they are
- // positioned so that the first space terminated string is still
- // longer than one line. So, we walk backwards from the end of the
- // string until we find the largest string that will fit on the first
- // line , and then we just clip the second line.
- cch = lstrlen(szTempBuff);
- chKeep = szTempBuff[cch];
- szTempBuff[cch] = ' ';
- GetTextExtentPoint(hDCScreen, szTempBuff, lstrlen(szTempBuff),&size);
- cxFirstLine = size.cx;
- cyFirstLine = size.cy;
- while (cxFirstLine > cxMaxString)
- {
- // We allow 40 characters in the label, but the metafile is
- // only as wide as 10 W's (for aesthetics - 20 W's wide looked
- // dumb. This means that if we split a long string in half (in
- // terms of characters), then we could still be wider than the
- // metafile. So, if this is the case, we just step backwards
- // from the halfway point until we get something that will fit.
- // Since we just let ETO clip the second line
- szTempBuff[cch--] = chKeep;
- if (0 == cch)
- goto CleanupAndLeave;
- chKeep = szTempBuff[cch];
- szTempBuff[cch] = ' ';
- GetTextExtentPoint(
- hDCScreen, szTempBuff, lstrlen(szTempBuff), &size);
- cxFirstLine = size.cx;
- }
- iLastLineStart = cch;
- if (!fPrintText)
- goto CleanupAndLeave;
- ExtTextOut(hDC,
- nXStart + (lpRect->right - cxFirstLine) / 2,
- nYStart,
- fuOptions,
- lpRect,
- szTempBuff,
- lstrlen(szTempBuff),
- lpDX);
- szTempBuff[cch] = chKeep;
- lpszSecondLine = szTempBuff;
- lpszSecondLine += cch;
- GetTextExtentPoint(
- hDCScreen, lpszSecondLine, lstrlen(lpszSecondLine), &size);
- // If the second line is wider than the rectangle, we
- // just want to clip the text.
- cxSecondLine = min(size.cx, cxMaxString);
- ExtTextOut(hDC,
- nXStart + (lpRect->right - cxSecondLine) / 2,
- nYStart + cyFirstLine,
- fuOptions,
- lpRect,
- lpszSecondLine,
- lstrlen(lpszSecondLine),
- lpDX);
- CleanupAndLeave:
- SelectObject(hDCScreen, hFontT);
- ReleaseDC(NULL, hDCScreen);
- return iLastLineStart;
- }