- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
682 lines
17 KiB
C++
682 lines
17 KiB
C++
//----------------------------------------------------------------------------
|
|
// ObjectWindows
|
|
// (C) Copyright 1994 by Borland International, All Rights Reserved
|
|
//
|
|
// Implementation of TOleMetaPict, manipulates Ole2 MetafilePict/Icon
|
|
//----------------------------------------------------------------------------
|
|
#define INC_OLE2
|
|
#include <owl/owlpch.h>
|
|
#include <owl/oledlg.h>
|
|
|
|
//
|
|
// OWL OLE Dialog diagnostic group.
|
|
//
|
|
DIAG_DECLARE_GROUP(OwlOleDlg);
|
|
|
|
//
|
|
// Class used for label and source extraction from a metafile
|
|
//
|
|
class _OWLCLASS TLabelExtract {
|
|
public:
|
|
//
|
|
// Use memset to initialize PODS
|
|
//
|
|
TLabelExtract() {memset(this, 0, sizeof(TLabelExtract));}
|
|
|
|
LPSTR lpsz;
|
|
UINT Index; // index in lpsz (so we can retrieve 2+ lines)
|
|
DWORD PrevIndex; // index of last line (so we can mimic word wrap)
|
|
|
|
union {
|
|
UINT cch; //Length of label for label extraction
|
|
UINT iIcon; //Index of icon in source extraction.
|
|
} u;
|
|
|
|
//
|
|
//For internal use in enum procs
|
|
//
|
|
BOOL fFoundIconOnly;
|
|
BOOL fFoundSource;
|
|
BOOL fFoundIndex;
|
|
};
|
|
|
|
//
|
|
// Class used for extracting icons from a metafile (CreateIcon parameters)
|
|
//
|
|
class _OWLCLASS TIconExtract {
|
|
public:
|
|
//
|
|
// Use memset to initialize PODS
|
|
//
|
|
TIconExtract() {memset(this, 0, sizeof(TIconExtract));}
|
|
|
|
HICON hIcon; // Icon created in the enumeration proc.
|
|
BOOL fAND;
|
|
HGLOBAL hMemAND; // Enumeration proc allocates and copies
|
|
HINSTANCE hInst; // Module instance handle
|
|
};
|
|
|
|
//
|
|
// Class used to pass info to EnumMetafileDraw
|
|
//
|
|
class _OWLCLASS TDrawInfo {
|
|
public:
|
|
//
|
|
// Use memset to initialize PODS
|
|
//
|
|
TDrawInfo() {memset(this, 0, sizeof(TDrawInfo));}
|
|
|
|
RECT Rect;
|
|
BOOL fIconOnly;
|
|
};
|
|
|
|
//
|
|
// String [comment] in Metafile which flags that the label follows
|
|
//
|
|
static char szIconOnly[] = "IconOnly";
|
|
|
|
int CALLBACK __export EnumMetafileIconDraw(HDC, HANDLETABLE FAR*, METARECORD FAR*, int, LPARAM);
|
|
int CALLBACK __export EnumMetafileExtractLabel(HDC, HANDLETABLE FAR*, METARECORD FAR*, int, TLabelExtract far*);
|
|
int CALLBACK __export EnumMetafileExtractIcon(HDC, HANDLETABLE FAR*, METARECORD FAR*, int, TIconExtract far*);
|
|
int CALLBACK __export EnumMetafileExtractIconSource(HDC, HANDLETABLE FAR*, METARECORD FAR*, int, TLabelExtract far*);
|
|
|
|
//
|
|
//
|
|
//
|
|
static uint
|
|
MapLogHimToPix(int hiMetric, int pelsPerInch)
|
|
{
|
|
return (uint)(((double)hiMetric * pelsPerInch)/HiMetricPerInch);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
static int
|
|
XformWidthInHimetricToPixels(TDC& dc, int widthInHiMetric)
|
|
{
|
|
int logPix = dc.GetDeviceCaps(LOGPIXELSX);
|
|
int pixWidth = MapLogHimToPix(widthInHiMetric, logPix);
|
|
return pixWidth;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
static int
|
|
XformHeightInHimetricToPixels(TDC& dc, int heightInHiMetric)
|
|
{
|
|
int logPix = dc.GetDeviceCaps(LOGPIXELSY);
|
|
int pixHeight = MapLogHimToPix(heightInHiMetric, logPix);
|
|
return pixHeight;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
BOOL
|
|
OleUIMetafilePictIconDraw(HDC hDC, LPRECT pRect,
|
|
HGLOBAL hMetaPict, BOOL fIconOnly)
|
|
{
|
|
LPMETAFILEPICT pMF;
|
|
TDrawInfo di;
|
|
int cx, cy;
|
|
SIZE size;
|
|
POINT point;
|
|
|
|
if (!hMetaPict)
|
|
return FALSE;
|
|
|
|
pMF = (LPMETAFILEPICT)GlobalLock(hMetaPict);
|
|
|
|
if (NULL==pMF) {
|
|
TRACEX(OwlOleDlg, 1, "Unable to lock MetaPict Handle");
|
|
return FALSE;
|
|
}
|
|
|
|
di.Rect = *pRect;
|
|
di.fIconOnly = fIconOnly;
|
|
|
|
//
|
|
// Transform to back to pixels
|
|
//
|
|
cx = XformWidthInHimetricToPixels(TDC(hDC), pMF->xExt);
|
|
cy = XformHeightInHimetricToPixels(TDC(hDC), pMF->yExt);
|
|
|
|
SaveDC(hDC);
|
|
|
|
SetMapMode(hDC, pMF->mm);
|
|
SetViewportOrgEx(hDC, (pRect->right - cx) / 2, 0, &point);
|
|
|
|
SetViewportExtEx(hDC, min ((pRect->right - cx) / 2 + cx, cx), cy, &size);
|
|
|
|
if (fIconOnly) {
|
|
EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileIconDraw,
|
|
(LPARAM)(TDrawInfo far*)&di);
|
|
}
|
|
else {
|
|
PlayMetaFile(hDC, pMF->hMF);
|
|
}
|
|
|
|
RestoreDC(hDC, -1);
|
|
GlobalUnlock(hMetaPict);
|
|
return TRUE;
|
|
}
|
|
|
|
int CALLBACK __export
|
|
EnumMetafileIconDraw(HDC hDC, HANDLETABLE FAR *phTable,
|
|
METARECORD FAR *pMFR,
|
|
int cObj, LPARAM lParam)
|
|
{
|
|
TDrawInfo far* lpdi = (TDrawInfo far*)lParam;
|
|
|
|
//
|
|
// We play everything blindly except for DIBBITBLT (or DIBSTRETCHBLT)
|
|
// and ESCAPE with MFCOMMENT. For the BitBlts we change the x,y to
|
|
// draw at (0,0) instead of wherever it was written to draw. The
|
|
// comment tells us there to stop if we don't want to draw the label.
|
|
//
|
|
|
|
//
|
|
//If we're playing icon only, stop enumeration at the comment.
|
|
//
|
|
if (lpdi->fIconOnly) {
|
|
if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0]) {
|
|
if (0==lstrcmpi(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Check for the records in which we want to munge the coordinates.
|
|
// destX is offset 6 for BitBlt, offset 9 for StretchBlt, either of
|
|
// which may appear in the metafile.
|
|
//
|
|
if (META_DIBBITBLT==pMFR->rdFunction)
|
|
pMFR->rdParm[6]=0;
|
|
|
|
if (META_DIBSTRETCHBLT==pMFR->rdFunction)
|
|
pMFR->rdParm[9] = 0;
|
|
}
|
|
|
|
PlayMetaFileRecord(hDC, phTable, pMFR, cObj);
|
|
return 1;
|
|
}
|
|
|
|
UINT
|
|
OleUIMetafilePictExtractLabel(HGLOBAL hMetaPict, LPSTR lpszLabel,
|
|
UINT cchLabel, LPDWORD lpWrapIndex)
|
|
{
|
|
LPMETAFILEPICT pMF;
|
|
TLabelExtract le;
|
|
HDC hDC;
|
|
|
|
//
|
|
// We extract the label by getting a screen DC and walking the metafile
|
|
// records until we see the ExtTextOut record we put there. That
|
|
// record will have the string embedded in it which we then copy out.
|
|
//
|
|
if (!hMetaPict || !lpszLabel || !cchLabel)
|
|
return FALSE;
|
|
|
|
pMF= (LPMETAFILEPICT)GlobalLock(hMetaPict);
|
|
|
|
if (NULL==pMF)
|
|
return FALSE;
|
|
|
|
le.lpsz=lpszLabel;
|
|
le.u.cch=cchLabel;
|
|
le.Index=0;
|
|
le.fFoundIconOnly=FALSE;
|
|
le.fFoundSource=FALSE;
|
|
le.fFoundIndex=FALSE;
|
|
le.PrevIndex = 0;
|
|
|
|
//
|
|
// Use a screen DC so we have something valid to pass in.
|
|
//
|
|
hDC=GetDC(NULL);
|
|
EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractLabel,
|
|
(LONG)(TLabelExtract far*)&le);
|
|
ReleaseDC(NULL, hDC);
|
|
|
|
GlobalUnlock(hMetaPict);
|
|
|
|
//
|
|
// Tell where we wrapped (if calling function cares)
|
|
//
|
|
if (lpWrapIndex)
|
|
*lpWrapIndex = le.PrevIndex;
|
|
|
|
//
|
|
// Return amount of text copied
|
|
//
|
|
return le.u.cch;
|
|
}
|
|
|
|
int CALLBACK __export
|
|
EnumMetafileExtractLabel(HDC /*hDC*/,
|
|
HANDLETABLE FAR* /*phTable*/,
|
|
METARECORD FAR *pMFR,
|
|
int /*cObj*/,
|
|
TLabelExtract far* pLE)
|
|
{
|
|
//
|
|
// We don't allow anything to happen until we see "IconOnly"
|
|
// in an MFCOMMENT that is used to enable everything else.
|
|
//
|
|
if (!pLE->fFoundIconOnly) {
|
|
if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0]) {
|
|
if (0==lstrcmpi(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
|
|
pLE->fFoundIconOnly=TRUE;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Enumerate all records looking for META_EXTTEXTOUT - there can be more
|
|
// than one.
|
|
//
|
|
if (META_EXTTEXTOUT==pMFR->rdFunction) {
|
|
UINT cchMax;
|
|
LPSTR lpszTemp;
|
|
|
|
//
|
|
// If ExtTextOut has NULL fuOptions, then the rectangle is omitted
|
|
// from the record, and the string starts at rdParm[4]. If
|
|
// fuOptions is non-NULL, then the string starts at rdParm[8]
|
|
// (since the rectange takes up four WORDs in the array). In
|
|
// both cases, the string continues for (rdParm[2]+1) >> 1
|
|
// words. We just cast a pointer to rdParm[8] to an LPSTR and
|
|
// lstrcpyn into the buffer we were given.
|
|
//
|
|
// Note that we use element 8 in rdParm instead of 4 because we
|
|
// passed ETO_CLIPPED in for the options on ExtTextOut--docs say
|
|
// [4] which is rect doesn't exist if we passed zero there.
|
|
//
|
|
//
|
|
cchMax=min(pLE->u.cch - pLE->Index, (UINT)pMFR->rdParm[2]);
|
|
lpszTemp = pLE->lpsz + pLE->Index;
|
|
|
|
lstrcpyn(lpszTemp, (LPSTR)&(pMFR->rdParm[8]), cchMax + 1);
|
|
|
|
pLE->PrevIndex = pLE->Index;
|
|
pLE->Index += cchMax;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
HICON
|
|
OleUIMetafilePictExtractIcon(HGLOBAL hMetaPict, HINSTANCE hinst)
|
|
{
|
|
LPMETAFILEPICT pMF;
|
|
HDC hDC;
|
|
TIconExtract ie;
|
|
|
|
//
|
|
// We extract the label by getting a screen DC and walking the metafile
|
|
// records until we see the ExtTextOut record we put there. That
|
|
// record will have the string embedded in it which we then copy out.
|
|
//
|
|
|
|
if (NULL==hMetaPict)
|
|
return NULL;
|
|
|
|
pMF= (LPMETAFILEPICT)GlobalLock(hMetaPict);
|
|
|
|
if (NULL==pMF)
|
|
return FALSE;
|
|
|
|
ie.fAND=TRUE;
|
|
ie.hInst = hinst;
|
|
|
|
hDC=GetDC(NULL);
|
|
EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractIcon,
|
|
(LONG)(TIconExtract far*)&ie);
|
|
ReleaseDC(NULL, hDC);
|
|
GlobalUnlock(hMetaPict);
|
|
|
|
return ie.hIcon;
|
|
}
|
|
|
|
int CALLBACK __export
|
|
EnumMetafileExtractIcon(HDC hDC, HANDLETABLE FAR* /*phTable*/,
|
|
METARECORD FAR *pMFR, int /*cObj*/,
|
|
TIconExtract far* pIE)
|
|
{
|
|
LPBITMAPINFO lpBI;
|
|
LPBITMAPINFOHEADER lpBH;
|
|
LPBYTE lpbSrc;
|
|
LPBYTE lpbDst;
|
|
UINT uWidth, uHeight;
|
|
DWORD cb;
|
|
HGLOBAL hMem;
|
|
BITMAP bm;
|
|
HBITMAP hBmp;
|
|
|
|
//
|
|
// Continue enumeration if we don't see the records we want.
|
|
//
|
|
if (META_DIBBITBLT != pMFR->rdFunction &&
|
|
META_DIBSTRETCHBLT != pMFR->rdFunction)
|
|
return 1;
|
|
|
|
//
|
|
// Windows 3.0 DrawIcon uses META_DIBBITBLT in whereas 3.1 uses
|
|
// META_DIBSTRETCHBLT so we have to handle each case separately.
|
|
//
|
|
|
|
if (META_DIBBITBLT==pMFR->rdFunction) {
|
|
//
|
|
// Get dimensions and the BITMAPINFO struct.
|
|
//
|
|
uHeight=pMFR->rdParm[1];
|
|
uWidth =pMFR->rdParm[2];
|
|
lpBI=(LPBITMAPINFO)&(pMFR->rdParm[8]);
|
|
}
|
|
if (META_DIBSTRETCHBLT==pMFR->rdFunction) {
|
|
//
|
|
// Get dimensions and the BITMAPINFO struct.
|
|
//
|
|
uHeight=pMFR->rdParm[2];
|
|
uWidth =pMFR->rdParm[3];
|
|
lpBI=(LPBITMAPINFO)&(pMFR->rdParm[10]);
|
|
}
|
|
|
|
lpBH=(LPBITMAPINFOHEADER)&(lpBI->bmiHeader);
|
|
|
|
//
|
|
// Pointer to the bits which follows the BITMAPINFO structure.
|
|
//
|
|
lpbSrc=(LPBYTE)lpBI+sizeof(BITMAPINFOHEADER);
|
|
|
|
//
|
|
// Add the length of the color table.
|
|
//
|
|
if (0!=lpBH->biClrUsed)
|
|
lpbSrc+=(int)(DWORD)(lpBH->biClrUsed*sizeof(RGBQUAD));
|
|
else {
|
|
//
|
|
// 1 << bc gives 2, 16, 256 for 1, 4, or 256 colors
|
|
lpbSrc+=(int)(DWORD)((1 << (lpBH->biBitCount))*sizeof(RGBQUAD));
|
|
}
|
|
|
|
//
|
|
// All the bits we have in lpbSrc are device-independent, so we
|
|
// need to change them over to be device-dependent using SetDIBits.
|
|
// Once we have a bitmap with the device-dependent bits, we can
|
|
// GetBitmapBits to have buffers with the real data.
|
|
//
|
|
// For each pass we have to allocate memory for the bits. We save
|
|
// the memory for the mask between passes.
|
|
//
|
|
|
|
//
|
|
// Use CreateBitmap for ANY monochrome bitmaps
|
|
//
|
|
if (pIE->fAND || 1==lpBH->biBitCount || lpBH->biBitCount > 8)
|
|
hBmp=CreateBitmap((UINT)lpBH->biWidth, (UINT)lpBH->biHeight, 1, 1, NULL);
|
|
else if (lpBH->biBitCount <= 8)
|
|
hBmp=CreateCompatibleBitmap(hDC, (UINT)lpBH->biWidth, (UINT)lpBH->biHeight);
|
|
|
|
if (!hBmp || !SetDIBits(hDC, hBmp, 0, (UINT)lpBH->biHeight,
|
|
(LPVOID)lpbSrc, lpBI, DIB_RGB_COLORS)) {
|
|
if (!pIE->fAND)
|
|
GlobalFree(pIE->hMemAND);
|
|
|
|
DeleteObject(hBmp);
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Allocate memory and get the DDBits into it.
|
|
//
|
|
GetObject(hBmp, sizeof(bm), &bm);
|
|
|
|
cb=bm.bmHeight*bm.bmWidthBytes * bm.bmPlanes;
|
|
|
|
hMem=GlobalAlloc(GHND, cb);
|
|
|
|
if (NULL==hMem) {
|
|
if (NULL!=pIE->hMemAND)
|
|
GlobalFree(pIE->hMemAND);
|
|
|
|
DeleteObject(hBmp);
|
|
return 0;
|
|
}
|
|
|
|
lpbDst=(LPBYTE)GlobalLock(hMem);
|
|
GetBitmapBits(hBmp, cb, (LPVOID)lpbDst);
|
|
|
|
DeleteObject(hBmp);
|
|
GlobalUnlock(hMem);
|
|
|
|
//
|
|
// If this is the first pass (pIE->fAND==TRUE) then save the memory
|
|
// of the AND bits for the next pass.
|
|
//
|
|
if (pIE->fAND) {
|
|
pIE->fAND=FALSE;
|
|
pIE->hMemAND=hMem;
|
|
|
|
//
|
|
// Continue enumeration looking for the next blt record.
|
|
//
|
|
return 1;
|
|
}
|
|
else {
|
|
//
|
|
// Get the AND pointer again.
|
|
//
|
|
lpbSrc=(LPBYTE)GlobalLock(pIE->hMemAND);
|
|
|
|
//
|
|
// Create the icon now that we have all the data. lpbDst already
|
|
// points to the XOR bits.
|
|
//
|
|
pIE->hIcon=CreateIcon(pIE->hInst, uWidth, uHeight, (BYTE)bm.bmPlanes,
|
|
(BYTE)bm.bmBitsPixel, (LPVOID)lpbSrc,
|
|
(LPVOID)lpbDst);
|
|
|
|
GlobalUnlock(pIE->hMemAND);
|
|
GlobalFree(pIE->hMemAND);
|
|
GlobalFree(hMem);
|
|
|
|
//
|
|
// We're done so we can stop.
|
|
//
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
BOOL OleUIMetafilePictExtractIconSource(HGLOBAL hMetaPict,
|
|
LPSTR lpszSource,
|
|
UINT FAR *piIcon)
|
|
{
|
|
LPMETAFILEPICT pMF;
|
|
TLabelExtract le;
|
|
HDC hDC;
|
|
|
|
//
|
|
// We will walk the metafile looking for the two comment records
|
|
// following the IconOnly comment. The flags fFoundIconOnly and
|
|
// fFoundSource indicate if we have found IconOnly and if we have
|
|
// found the source comment already.
|
|
//
|
|
if (NULL==hMetaPict || NULL==lpszSource || NULL==piIcon)
|
|
return FALSE;
|
|
|
|
pMF=(LPMETAFILEPICT)GlobalLock(hMetaPict);
|
|
|
|
if (NULL==pMF)
|
|
return FALSE;
|
|
|
|
le.lpsz=lpszSource;
|
|
le.fFoundIconOnly=FALSE;
|
|
le.fFoundSource=FALSE;
|
|
le.fFoundIndex=FALSE;
|
|
|
|
//
|
|
// Use a screen DC so we have something valid to pass in.
|
|
//
|
|
hDC=GetDC(NULL);
|
|
EnumMetaFile(hDC, pMF->hMF, (MFENUMPROC)EnumMetafileExtractIconSource,
|
|
(LONG)(TLabelExtract far*)&le);
|
|
ReleaseDC(NULL, hDC);
|
|
|
|
GlobalUnlock(hMetaPict);
|
|
|
|
//
|
|
// Copy the icon index to the caller's variable.
|
|
//
|
|
*piIcon=le.u.iIcon;
|
|
|
|
//
|
|
// Check that we found everything.
|
|
//
|
|
return (le.fFoundIconOnly && le.fFoundSource && le.fFoundIndex);
|
|
}
|
|
|
|
int CALLBACK __export
|
|
EnumMetafileExtractIconSource(HDC /*hDC*/,
|
|
HANDLETABLE FAR* /*phTable*/,
|
|
METARECORD FAR *pMFR,
|
|
int /*cObj*/,
|
|
TLabelExtract far* pLE)
|
|
{
|
|
LPSTR psz;
|
|
|
|
//
|
|
// We don't allow anything to happen until we see "IconOnly"
|
|
// in an MFCOMMENT that is used to enable everything else.
|
|
//
|
|
if (!pLE->fFoundIconOnly) {
|
|
if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0]) {
|
|
if (0==lstrcmpi(szIconOnly, (LPSTR)&pMFR->rdParm[2]))
|
|
pLE->fFoundIconOnly=TRUE;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Now see if we find the source string.
|
|
//
|
|
if (!pLE->fFoundSource) {
|
|
if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0]) {
|
|
strcpyn(pLE->lpsz, (LPSTR)&pMFR->rdParm[2], MaxPathLen);
|
|
pLE->lpsz[MaxPathLen-1] = '\0';
|
|
pLE->fFoundSource=TRUE;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Next comment will be the icon index.
|
|
//
|
|
if (META_ESCAPE==pMFR->rdFunction && MFCOMMENT==pMFR->rdParm[0]) {
|
|
//
|
|
// This string contains the icon index in string form,
|
|
// so we need to convert back to a UINT. After we see this
|
|
// we can stop the enumeration. The comment will have
|
|
// a null terminator because we made sure to save it.
|
|
//
|
|
psz=(LPSTR)&pMFR->rdParm[2];
|
|
pLE->u.iIcon=0;
|
|
|
|
//
|
|
// Do Ye Olde atoi
|
|
//
|
|
while (*psz)
|
|
pLE->u.iIcon=(10*pLE->u.iIcon)+((*psz++)-'0');
|
|
|
|
pLE->fFoundIndex=TRUE;
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Aliases an OLE MetafilePictIcon
|
|
//
|
|
TOleMetaPict::TOleMetaPict(HGLOBAL metaPict, TAutoDelete autoDelete):
|
|
MetaPict(metaPict), ShouldDelete(autoDelete==AutoDelete)
|
|
{}
|
|
|
|
//
|
|
// Frees Metafile and Memory handle (if ShouldDelete)
|
|
//
|
|
TOleMetaPict::~TOleMetaPict()
|
|
{
|
|
if (ShouldDelete)
|
|
Free(MetaPict);
|
|
}
|
|
|
|
//
|
|
// Frees the Metafile Handle and Global Memory Handle
|
|
//
|
|
bool
|
|
TOleMetaPict::Free(HGLOBAL& metaPict)
|
|
{
|
|
if (!metaPict)
|
|
return false;
|
|
|
|
LPMETAFILEPICT pMF = (LPMETAFILEPICT)GlobalLock(metaPict);
|
|
if (!pMF) {
|
|
TRACEX(OwlOleDlg, 1, "Unable to lock MetaPict Handle");
|
|
return false;
|
|
}
|
|
|
|
if (pMF->hMF)
|
|
DeleteMetaFile(pMF->hMF);
|
|
|
|
GlobalUnlock(metaPict);
|
|
GlobalFree(metaPict);
|
|
metaPict = 0;
|
|
return true;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
bool
|
|
TOleMetaPict::Draw(TDC& dc, TRect& rect, bool iconOnly) const
|
|
{
|
|
PRECONDITION(MetaPict);
|
|
return OleUIMetafilePictIconDraw(dc, &rect, MetaPict, iconOnly) ?
|
|
true : false;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
int
|
|
TOleMetaPict::ExtractLabel(char far* label, uint32 *wrap) const
|
|
{
|
|
PRECONDITION(MetaPict);
|
|
return OleUIMetafilePictExtractLabel(MetaPict, label, MaxLabelLen, wrap);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
HICON
|
|
TOleMetaPict::ExtractIcon(HINSTANCE hinst) const
|
|
{
|
|
PRECONDITION(MetaPict);
|
|
return OleUIMetafilePictExtractIcon(MetaPict, hinst);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
bool
|
|
TOleMetaPict::ExtractIconSource(char far* source, uint& index) const
|
|
{
|
|
PRECONDITION(MetaPict);
|
|
return OleUIMetafilePictExtractIconSource(MetaPict, source, &index);
|
|
}
|