BOOL CWndImage::CreateFromStatic(CWnd * sc) { // _ASSERTE(!::IsWindow(m_hWnd)); // image control already created if (!sc || !::IsWindow(sc->m_hWnd)) return false; CWnd * dlg = sc->GetParent(); if (!dlg || !::IsWindow(dlg->m_hWnd)) return false; CRect r; sc->GetWindowRect(&r); dlg->ScreenToClient(&r); CString s; DWORD style = sc->GetStyle(); DWORD exstyle = sc->GetExStyle(); sc->GetWindowText(s); UINT dlgID = sc->GetDlgCtrlID(); HBITMAP bmp = (HBITMAP) sc->SendMessage(STM_GETIMAGE, IMAGE_BITMAP, 0); if (bmp) sc->SendMessage(STM_SETIMAGE, IMAGE_BITMAP, 0); sc->DestroyWindow(); CreateEx(exstyle, NULL, s, style, r, dlg, dlgID); if (bmp) { SetImg(bmp, false); SetBltMode(bltFitXY); } return true; }
// Parse the next command. BOOL WMFUpdateState::parse_next_command(BOOL *primitive) { BOOL fPrimitive = FALSE; // Remember the start of the record. ST_DEV_POSITION lRecordOffset; file.tell(&lRecordOffset); // Read the next record. METARECORD Record; if ((error = file.read(&Record, sizeof(Record)-sizeof(Record.rdParm))) != ERRORCODE_None) { return FALSE; } // TRACE("Record %d function: %04x, size: %08lx\n", m_nRecord, Record.rdFunction, Record.rdSize); // Process the record. switch (Record.rdFunction) { case 0: { // End of records. All done. return FALSE; } case META_ESCAPE: { // short n; // file.read(&n, sizeof(n)); // TRACE("Escape: %x\n", n); break; } case META_SETROP2: case META_SETRELABS: case META_SETMAPMODE: { // TRACE("IGNORED Record %d function: %04x, size: %08lx\n", m_nRecord, Record.rdFunction, Record.rdSize); break; } case META_SETTEXTALIGN: { short nAlign; file.read(&nAlign, sizeof(nAlign)); SetTextAlign(nAlign); break; } case META_SETBKCOLOR: { COLORREF Color; file.read(&Color, sizeof(Color)); SetBkColor(Color); break; } case META_SETBKMODE: { short nMode; file.read(&nMode, sizeof(nMode)); SetBkMode(nMode); break; } case META_SETTEXTCOLOR: { COLORREF Color; file.read(&Color, sizeof(Color)); SetTextColor(Color); break; } case META_SETWINDOWORG: { // Read the parameter. short Parms[2]; ASSERT(Record.rdSize == 5); file.read(Parms, sizeof(Parms)); m_DCState.m_cpWindowOrg.y = Parms[0]; m_DCState.m_cpWindowOrg.x = Parms[1]; NewSourceVars(); break; } case META_SETWINDOWEXT: { // Read the parameter. short Parms[2]; ASSERT(Record.rdSize == 5); file.read(Parms, sizeof(Parms)); m_DCState.m_cpWindowExt.y = Parms[0]; m_DCState.m_cpWindowExt.x = Parms[1]; NewSourceVars(); break; } case META_CREATEBRUSHINDIRECT: { CWMFBrushObject* pNewBrush = new CWMFBrushObject; file.read(&pNewBrush->m_LogBrush, sizeof(LOGBRUSH16)); NewObject(pNewBrush); break; } case META_DIBCREATEPATTERNBRUSH: { CWMFBrushObject* pNewBrush = new CWMFBrushObject; pNewBrush->m_LogBrush.lbStyle = BS_SOLID; pNewBrush->m_LogBrush.lbColor = RGB(128, 0, 0); NewObject(pNewBrush); break; } case META_CREATEPENINDIRECT: { CWMFPenObject* pNewPen = new CWMFPenObject; file.read(&pNewPen->m_LogPen, sizeof(LOGPEN16)); NewObject(pNewPen); // TRACE("New pen - s: %d; w: %d, %d; c: %08lx\n", // pNewPen->m_LogPen.lopnStyle, // pNewPen->m_LogPen.lopnWidth.x, // pNewPen->m_LogPen.lopnWidth.y, // pNewPen->m_LogPen.lopnColor); break; } case META_CREATEFONTINDIRECT: { CWMFFontObject* pNewFont = new CWMFFontObject; // Read the data. LOGFONT16 lf; file.read(&lf, sizeof(LOGFONT16)); // Translate it over. pNewFont->m_LogFont.lfHeight = lf.lfHeight; pNewFont->m_LogFont.lfWidth = lf.lfWidth; pNewFont->m_LogFont.lfEscapement = lf.lfEscapement; pNewFont->m_LogFont.lfOrientation = lf.lfOrientation; pNewFont->m_LogFont.lfWeight = lf.lfWeight; // Warning: hard-coded size ahead. memcpy(&pNewFont->m_LogFont.lfItalic, &lf.lfItalic, 8 + LF_FACESIZE); NewObject(pNewFont); break; } case META_CREATEPALETTE: { // This is mostly here to make sure the object array stays in sync. CWMFPaletteObject* pNewPalette = new CWMFPaletteObject; struct { WORD palVersion; WORD palNumEntries; } Header; file.read(&Header, sizeof(Header)); // Now we have the header. See how many entries we want. if (Header.palVersion == 0x0300) { int nPaletteSize = sizeof(PALETTEENTRY)*Header.palNumEntries; pNewPalette->m_pPalette = (LOGPALETTE*)new BYTE[sizeof(LOGPALETTE) + nPaletteSize - sizeof(PALETTEENTRY)]; pNewPalette->m_pPalette->palVersion = Header.palVersion; pNewPalette->m_pPalette->palNumEntries = Header.palNumEntries; file.read(pNewPalette->m_pPalette->palPalEntry, nPaletteSize); } NewObject(pNewPalette); break; } case META_CREATEREGION: { // This is mostly here to make sure the object array stays in sync. // I don't think there's hope of determining the parms format for // this record. CWMFRegionObject* pNewRegion = new CWMFRegionObject; NewObject(pNewRegion); break; } case META_SELECTPALETTE: case META_SELECTOBJECT: { short nIndex; file.read(&nIndex, sizeof(nIndex)); SelectObject(nIndex); // TRACE("SelectObject: %d\n", nIndex); break; } case META_DELETEOBJECT: { short nIndex; file.read(&nIndex, sizeof(nIndex)); DeleteObject(nIndex); // TRACE("DeleteObject: %d\n", nIndex); break; } case META_SETPOLYFILLMODE: { short nFillMode; file.read(&nFillMode, sizeof(nFillMode)); m_nFillMode = nFillMode; break; } case META_SETSTRETCHBLTMODE: { short nMode; file.read(&nMode, sizeof(nMode)); SetBltMode(nMode); break; } case META_POLYPOLYGON: { // Read the number of polygons. short nPolygons; file.read(&nPolygons, sizeof(nPolygons)); // Proceed to read counts and points (and draw). int* pCounts = NULL; POINT* pPoints = NULL; TRY { // Allocate the polygon counts. pCounts = new int[nPolygons]; // Read the polygon counts. int nPoints = 0; for (int nPolygon = 0; nPolygon < nPolygons; nPolygon++) { short p; file.read(&p, sizeof(p)); pCounts[nPolygon] = p; nPoints += p; } // Allocate the polygon points. pPoints = new POINT[nPoints]; // Read the polygon points. for (int nPoint = 0; nPoint < nPoints; nPoint++) { short p[2]; file.read(p, sizeof(p)); pPoints[nPoint].x = p[0]; pPoints[nPoint].y = p[1]; } // Draw the polypolygon. DrawPolyPolygon(pPoints, pCounts, nPolygons); } END_TRY delete [] pPoints; delete [] pCounts; fPrimitive = TRUE; break; } case META_POLYGON: { WORD wCount; file.read(&wCount, sizeof(wCount)); draw_polygon(wCount); fPrimitive = TRUE; break; } case META_POLYLINE: { WORD wCount; file.read(&wCount, sizeof(wCount)); draw_polyline(wCount, TRUE); fPrimitive = TRUE; break; } case META_ELLIPSE: { short Parms[4]; file.read(Parms, sizeof(Parms)); // Compute parameters to pass. // Parms[3] = left // Parms[2] = top // Parms[1] = right // Parms[0] = bottom OUTLINE_POINT center; center.x = (short)((int)Parms[3] + (int)Parms[1])/2; center.y = (short)((int)Parms[2] + (int)Parms[0])/2; short rx = Parms[3] - center.x; if (rx < 0) rx = -rx; short ry = Parms[2] - center.y; if (ry < 0) ry = -ry; draw_ellipse(center, rx, ry); fPrimitive = TRUE; break; } case META_ROUNDRECT: { // Cheat for now. Just draw it as a rectangle. // Skip the corner radii. file.seek(2*sizeof(short), ST_DEV_SEEK_CUR); // Fall through to... } case META_RECTANGLE: { short Parms[4]; file.read(Parms, sizeof(Parms)); // Parms[3] = left // Parms[2] = top // Parms[1] = right // Parms[0] = bottom OUTLINE_POINT p0, p1; p0.x = Parms[3]; p0.y = Parms[2]; p1.x = Parms[1]; p1.y = Parms[0]; draw_rectangle(p0, p1); fPrimitive = TRUE; break; } case META_DIBSTRETCHBLT: { // Read the numeric parameters. short Parms[10]; file.read(Parms, sizeof(Parms)); // Parms[0] = low-order word of raster op // Parms[1] = high-order word of raster op // Parms[2] = source y extent // Parms[3] = source x extent // Parms[4] = source y coordinate // Parms[5] = source x coordinate // Parms[6] = destination y extent // Parms[7] = destination x extent // Parms[8] = destination y coordinate // Parms[9] = destination x coordinate CRect crSource(CPoint(Parms[5], Parms[4]), CSize(Parms[3], Parms[2])); CRect crDest(CPoint(Parms[9], Parms[8]), CSize(Parms[7], Parms[6])); DWORD dwROP = MAKELONG(Parms[0], Parms[1]); // Process the rest of the dib blt. DoDibBlt(crSource, crDest, dwROP); fPrimitive = TRUE; break; } case META_DIBBITBLT: { // Read the numeric parameters. short Parms[7]; file.read(Parms, sizeof(Parms)); // Parms[0] = high-order word of raster op // Parms[1] = source y coordinate // Parms[2] = source x coordinate // Parms[3] = destination y extent // Parms[4] = destination x extent // Parms[5] = destination y coordinate // Parms[6] = destination x coordinate CRect crSource(CPoint(Parms[5], Parms[4]), CSize(Parms[7], Parms[6])); CRect crDest(CPoint(Parms[9], Parms[8]), CSize(Parms[7], Parms[6])); DWORD dwROP = MAKELONG(0, Parms[1]); // Process the rest of the dib blt. DoDibBlt(crSource, crDest, dwROP); fPrimitive = TRUE; break; } case META_STRETCHDIB: { // Read the numeric parameters. short Parms[11]; file.read(Parms, sizeof(Parms)); // Parms[0] = low-order word of raster op // Parms[1] = high-order word of raster op // Parms[2] = usage flag // Parms[3] = source y extent // Parms[4] = source x extent // Parms[5] = source y coordinate // Parms[6] = source x coordinate // Parms[7] = destination y extent // Parms[8] = destination x extent // Parms[9] = destination y coordinate // Parms[10] = destination x coordinate CRect crSource(CPoint(Parms[6], Parms[5]), CSize(Parms[4], Parms[3])); CRect crDest(CPoint(Parms[10], Parms[9]), CSize(Parms[8], Parms[7])); DWORD dwROP = MAKELONG(Parms[0], Parms[1]); WORD wUsage = (WORD)Parms[2]; // Process the rest of the dib blt. DoDibBlt(crSource, crDest, dwROP, wUsage); fPrimitive = TRUE; break; } case META_EXTTEXTOUT: { // Handle ExtTextOut call. // Read the numeric parameters. short Parms[4]; file.read(Parms, sizeof(Parms)); // Parms[0] = y // Parms[1] = x // Parms[2] = string length // Parms[3] = option flags RECTS rClip; if (Parms[3] != 0) { file.read(&rClip, sizeof(rClip)); } // String data follows int nStrLength = Parms[2]; int nStrSize = (nStrLength + 1) & ~1; LPBYTE pString = NULL; TRY { // Read the text. pString = new BYTE[nStrSize]; file.huge_read(pString, nStrSize); // See if there are any widths. ST_DEV_POSITION Here; file.tell(&Here); ST_DEV_POSITION lRecordEnd = lRecordOffset + Record.rdSize*sizeof(WORD); // TRACE("Count:%d; Here: %ld; lRecordEnd: %ld\n", // nStrLength, Here, lRecordEnd); int nDXSize = nStrLength*sizeof(short); short* pDX = NULL; if (lRecordEnd >= Here + nDXSize) { pDX = new short[nStrLength]; file.read(pDX, nDXSize); } OUTLINE_POINT p; p.x = (short)Parms[1]; p.y = (short)Parms[0]; RECT r; r.left = rClip.left; r.top = rClip.top; r.right = rClip.right; r.bottom = rClip.bottom; // Draw the text. DrawText(p, Parms[3], (LPCSTR)pString, nStrLength, &r, pDX); // Free the dx array. delete [] pDX; // Free the text. delete pString; } END_TRY fPrimitive = TRUE; break; } case META_TEXTOUT: { // Handle TextOut call. // Read the string size. short nStrLength; file.read(&nStrLength, sizeof(nStrLength)); int nStrSize = (nStrLength + 1) & ~1; LPBYTE pString = NULL; TRY { // Read the text. pString = new BYTE[nStrSize]; file.huge_read(pString, nStrSize); // Read the x and y. short Parms[2]; file.read(Parms, sizeof(Parms)); OUTLINE_POINT p; p.x = (short)Parms[1]; p.y = (short)Parms[0]; // Draw the text. DrawText(p, 0, (LPCSTR)pString, nStrLength, NULL); // Free the text. delete pString; } END_TRY fPrimitive = TRUE; break; } case META_MOVETO: case META_LINETO: { short Parms[2]; file.read(&Parms, sizeof(Parms)); // TRACE("%s: %d, %d\n", Record.rdFunction == META_MOVETO ? "MoveTo" : "LineTo", Parms[1], Parms[0]); OUTLINE_POINT p; p.x = Parms[1]; p.y = Parms[0]; if (Record.rdFunction == META_MOVETO) { // Move to. MoveTo(p); } else { // Must be Line to. LineTo(p); fPrimitive = TRUE; } break; } case META_PATBLT: { WORD Parms[6]; // Parms[0] - op low word // Parms[1] - op high word // Parms[2] - height // Parms[3] - width // Parms[4] - top // Parms[5] - left file.read(Parms, sizeof(Parms)); OUTLINE_POINT p0, p1; p0.x = Parms[5]; p0.y = Parms[4]; p1.x = p0.x + Parms[3]; p1.y = p0.y + Parms[2]; DoPatBlt(p0, p1, MAKELONG(Parms[0], Parms[1])); fPrimitive = TRUE; break; } case META_PIE: case META_ARC: { short Parms[8]; // Parms[0] = y4 end pt y // Parms[1] = x4 end pt x // Parms[2] = y3 start pt y // Parms[3] = x3 start pt x // Parms[4] = y2 Bound bottom // Parms[5] = x2 Bound right // Parms[6] = y1 Bound top // Parms[7] = x1 Bound left file.read(Parms, sizeof(Parms)); OUTLINE_POINT Center; Center.x = (short)midpoint(Parms[7], Parms[5]); Center.y = (short)midpoint(Parms[6], Parms[4]); double rx = Parms[5] - Center.x; if (rx < 0) rx = -rx; double ry = Parms[4] - Center.y; if (ry < 0) ry = -ry; double dStart = angle_from_vector(Parms[2] - Center.y, Parms[3] - Center.x); double dEnd = angle_from_vector(Parms[0] - Center.y, Parms[1] - Center.x); draw_elliptical_arc(Center, rx, ry, dStart-PI/2, dEnd-PI/2, (Record.rdFunction == META_PIE) ? 1 : -1); break; } case META_SAVEDC: { PushState(); break; } case META_RESTOREDC: { PopState(); break; } case META_SCALEVIEWPORTEXT: { // Read the parameter. short Parms[4]; // Parms[0] = ydenom // Parms[1] = ynum // Parms[2] = xdenom // Parms[3] = xnum file.read(Parms, sizeof(Parms)); m_DCState.m_cpViewportScaleNum.x = Parms[3]; m_DCState.m_cpViewportScaleDenom.x = Parms[2]; m_DCState.m_cpViewportScaleNum.y = Parms[1]; m_DCState.m_cpViewportScaleDenom.y = Parms[0]; NewSourceVars(); break; } default: { TRACE("UNKNOWN Record %d function: %04x, size: %08lx\n", m_nRecord, Record.rdFunction, Record.rdSize); break; } } m_nRecord++; // Seek past the record file.seek(lRecordOffset + Record.rdSize*sizeof(WORD), ST_DEV_SEEK_SET); *primitive = fPrimitive; return TRUE; }