//----------------------------------------------------------------------------- void D2DDrawContext::createRenderTarget () { if (window) { RECT rc; GetClientRect (window, &rc); D2D1_SIZE_U size = D2D1::SizeU (rc.right - rc.left, rc.bottom - rc.top); ID2D1HwndRenderTarget* hwndRenderTarget = 0; // D2D1_RENDER_TARGET_TYPE targetType = D2D1_RENDER_TARGET_TYPE_DEFAULT; D2D1_RENDER_TARGET_TYPE targetType = D2D1_RENDER_TARGET_TYPE_SOFTWARE; D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat (DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED); HRESULT hr = getD2DFactory ()->CreateHwndRenderTarget (D2D1::RenderTargetProperties (targetType, pixelFormat), D2D1::HwndRenderTargetProperties (window, size, D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS), &hwndRenderTarget); if (SUCCEEDED (hr)) { hwndRenderTarget->SetDpi (96.0, 96.0); renderTarget = hwndRenderTarget; } } else if (bitmap) { D2DBitmap* d2dBitmap = dynamic_cast<D2DBitmap*> (bitmap->getPlatformBitmap ()); if (d2dBitmap) { D2D1_RENDER_TARGET_TYPE targetType = D2D1_RENDER_TARGET_TYPE_SOFTWARE; D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat (DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED); HRESULT hr = getD2DFactory ()->CreateWicBitmapRenderTarget (d2dBitmap->getBitmap (), D2D1::RenderTargetProperties (targetType, pixelFormat), &renderTarget); } } init (); }
//----------------------------------------------------------------------------- void D2DDrawContext::setLineStyle (const CLineStyle& style) { if (strokeStyle && currentState.lineStyle == style) return; if (strokeStyle) { strokeStyle->Release (); strokeStyle = 0; } D2D1_STROKE_STYLE_PROPERTIES properties; switch (style.getLineCap ()) { case CLineStyle::kLineCapButt: properties.startCap = properties.endCap = properties.dashCap = D2D1_CAP_STYLE_FLAT; break; case CLineStyle::kLineCapRound: properties.startCap = properties.endCap = properties.dashCap = D2D1_CAP_STYLE_ROUND; break; case CLineStyle::kLineCapSquare: properties.startCap = properties.endCap = properties.dashCap = D2D1_CAP_STYLE_SQUARE; break; } switch (style.getLineJoin ()) { case CLineStyle::kLineJoinMiter: properties.lineJoin = D2D1_LINE_JOIN_MITER; break; case CLineStyle::kLineJoinRound: properties.lineJoin = D2D1_LINE_JOIN_ROUND; break; case CLineStyle::kLineJoinBevel: properties.lineJoin = D2D1_LINE_JOIN_BEVEL; break; } properties.dashOffset = (FLOAT)style.getDashPhase (); properties.miterLimit = 10.f; if (style.getDashCount ()) { properties.dashStyle = D2D1_DASH_STYLE_CUSTOM; FLOAT* lengths = new FLOAT[style.getDashCount ()]; for (int32_t i = 0; i < style.getDashCount (); i++) lengths[i] = (FLOAT)style.getDashLengths ()[i]; getD2DFactory ()->CreateStrokeStyle (properties, lengths, style.getDashCount (), &strokeStyle); delete [] lengths; } else { properties.dashStyle = D2D1_DASH_STYLE_SOLID; getD2DFactory ()->CreateStrokeStyle (properties, 0, 0, &strokeStyle); } COffscreenContext::setLineStyle (style); }
//----------------------------------------------------------------------------- IPlatformBitmap* IPlatformBitmap::createFromPath (UTF8StringPtr absolutePath) { UTF8StringHelper path (absolutePath); IStream* stream = 0; if (SUCCEEDED (SHCreateStreamOnFileEx (path, STGM_READ|STGM_SHARE_DENY_WRITE, 0, false, 0, &stream))) { #if VSTGUI_DIRECT2D_SUPPORT if (getD2DFactory ()) { D2DBitmap* result = new D2DBitmap (); if (result->loadFromStream (stream)) { stream->Release (); return result; } stream->Release (); result->forget (); return 0; } #endif GdiplusBitmap* bitmap = new GdiplusBitmap (); if (bitmap->loadFromStream (stream)) { stream->Release (); return bitmap; } bitmap->forget (); stream->Release (); } return 0; }
//----------------------------------------------------------------------------- void D2DDrawContext::fillLinearGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& startPoint, const CPoint& endPoint, bool evenOdd, CGraphicsTransform* t) { if (renderTarget == 0) return; D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path); if (d2dPath == 0) return; ID2D1PathGeometry* path = d2dPath->getPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING); if (path) { D2DApplyClip ac (this); ID2D1Geometry* geometry = 0; if (t) { ID2D1TransformedGeometry* tg = 0; D2D1_MATRIX_3X2_F matrix; matrix._11 = (FLOAT)t->m11; matrix._12 = (FLOAT)t->m12; matrix._21 = (FLOAT)t->m21; matrix._22 = (FLOAT)t->m22; matrix._31 = (FLOAT)t->dx; matrix._32 = (FLOAT)t->dy; getD2DFactory ()->CreateTransformedGeometry (path, matrix, &tg); geometry = tg; } else { geometry = path; geometry->AddRef (); } ID2D1GradientStopCollection* collection = 0; D2D1_GRADIENT_STOP gradientStops[2]; gradientStops[0].position = (FLOAT)gradient.getColor1Start (); gradientStops[1].position = (FLOAT)gradient.getColor2Start (); gradientStops[0].color = D2D1::ColorF (gradient.getColor1 ().red/255.f, gradient.getColor1 ().green/255.f, gradient.getColor1 ().blue/255.f, gradient.getColor1 ().alpha/255.f * currentState.globalAlpha); gradientStops[1].color = D2D1::ColorF (gradient.getColor2 ().red/255.f, gradient.getColor2 ().green/255.f, gradient.getColor2 ().blue/255.f, gradient.getColor2 ().alpha/255.f * currentState.globalAlpha); if (SUCCEEDED (getRenderTarget ()->CreateGradientStopCollection (gradientStops, 2, &collection))) { ID2D1LinearGradientBrush* brush = 0; D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES properties; properties.startPoint = makeD2DPoint (startPoint); properties.endPoint = makeD2DPoint (endPoint); if (SUCCEEDED (getRenderTarget ()->CreateLinearGradientBrush (properties, collection, &brush))) { getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Translation ((FLOAT)getOffset ().x, (FLOAT)getOffset ().y)); getRenderTarget ()->FillGeometry (geometry, brush); getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Identity ()); brush->Release (); } collection->Release (); } geometry->Release (); } }
//----------------------------------------------------------------------------- CDrawContext* createDrawContext (HWND window, HDC device, const CRect& surfaceRect) { #if VSTGUI_DIRECT2D_SUPPORT if (getD2DFactory ()) return new D2DDrawContext (window, surfaceRect); #endif return new GdiplusDrawContext (window, surfaceRect); }
//----------------------------------------------------------------------------- bool IPlatformFont::getAllPlatformFontFamilies (std::list<std::string>& fontFamilyNames) { #if VSTGUI_DIRECT2D_SUPPORT if (getD2DFactory ()) { return D2DFont::getAllPlatformFontFamilies (fontFamilyNames); } #endif return GdiPlusFont::getAllPlatformFontFamilies (fontFamilyNames); }
//----------------------------------------------------------------------------- IPlatformFont* IPlatformFont::create (const char* name, const CCoord& size, const int32_t& style) { #if VSTGUI_DIRECT2D_SUPPORT if (getD2DFactory ()) { return new D2DFont (name, size, style); } #endif GdiPlusFont* font = new GdiPlusFont (name, size, style); if (font->getFont ()) return font; font->forget (); return 0; }
//----------------------------------------------------------------------------- IPlatformBitmap* IPlatformBitmap::create (CPoint* size) { #if VSTGUI_DIRECT2D_SUPPORT if (getD2DFactory ()) { if (size) return new D2DBitmap (*size); return new D2DBitmap (); } #endif if (size) return new GdiplusBitmap (*size); return new GdiplusBitmap (); }
//----------------------------------------------------------------------------- void D2DDrawContext::fillRadialGradient (CGraphicsPath* _path, const CGradient& gradient, const CPoint& center, CCoord radius, const CPoint& originOffset, bool evenOdd, CGraphicsTransform* t) { if (renderTarget == 0) return; D2DApplyClip ac (this); if (ac.isEmpty ()) return; D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path); if (d2dPath == 0) return; ID2D1Geometry* path = d2dPath->createPath (evenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING); if (path) { ID2D1Geometry* geometry = 0; if (t) { ID2D1TransformedGeometry* tg = 0; getD2DFactory ()->CreateTransformedGeometry (path, convert (*t), &tg); geometry = tg; } else { geometry = path; geometry->AddRef (); } ID2D1GradientStopCollection* collection = createGradientStopCollection (gradient); if (collection) { // brush properties ID2D1RadialGradientBrush* brush = 0; D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES properties; properties.center = makeD2DPoint (center); properties.gradientOriginOffset = makeD2DPoint (originOffset); properties.radiusX = (FLOAT)radius; properties.radiusY = (FLOAT)radius; if (SUCCEEDED (getRenderTarget ()->CreateRadialGradientBrush (properties, collection, &brush))) { getRenderTarget ()->FillGeometry (geometry, brush); brush->Release (); } collection->Release (); } geometry->Release (); path->Release (); } }
//----------------------------------------------------------------------------- COffscreenContext* Win32Frame::createOffscreenContext (CCoord width, CCoord height) { #if VSTGUI_DIRECT2D_SUPPORT if (getD2DFactory ()) { D2DBitmap* bitmap = new D2DBitmap (CPoint (width, height)); D2DDrawContext* context = new D2DDrawContext (bitmap); bitmap->forget (); return context; } #endif GdiplusBitmap* bitmap = new GdiplusBitmap (CPoint (width, height)); GdiplusDrawContext* context = new GdiplusDrawContext (bitmap); bitmap->forget (); return context; }
//----------------------------------------------------------------------------- void D2DDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t) { if (renderTarget == 0) return; D2DGraphicsPath* d2dPath = dynamic_cast<D2DGraphicsPath*> (_path); if (d2dPath == 0) return; ID2D1PathGeometry* path = d2dPath->getPath (mode == kPathFilledEvenOdd ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING); if (path) { D2DApplyClip ac (this); ID2D1Geometry* geometry = 0; if (t) { ID2D1TransformedGeometry* tg = 0; D2D1_MATRIX_3X2_F matrix; matrix._11 = (FLOAT)t->m11; matrix._12 = (FLOAT)t->m12; matrix._21 = (FLOAT)t->m21; matrix._22 = (FLOAT)t->m22; matrix._31 = (FLOAT)t->dx; matrix._32 = (FLOAT)t->dy; getD2DFactory ()->CreateTransformedGeometry (path, matrix, &tg); geometry = tg; } else { geometry = path; geometry->AddRef (); } getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Translation ((FLOAT)getOffset ().x, (FLOAT)getOffset ().y)); if (mode == kPathFilled || mode == kPathFilledEvenOdd) getRenderTarget ()->FillGeometry (geometry, getFillBrush ()); else if (mode == kPathStroked) getRenderTarget ()->DrawGeometry (geometry, getStrokeBrush (), (FLOAT)getLineWidth (), getStrokeStyle ()); getRenderTarget ()->SetTransform (D2D1::Matrix3x2F::Identity ()); geometry->Release (); } }
//----------------------------------------------------------------------------- IPlatformBitmap* IPlatformBitmap::createFromMemory (const void* ptr, uint32_t memSize) { #ifdef __GNUC__ typedef IStream* (*SHCreateMemStreamProc) (const BYTE* pInit, UINT cbInit); HMODULE shlwDll = LoadLibraryA ("shlwapi.dll"); SHCreateMemStreamProc proc = reinterpret_cast<SHCreateMemStreamProc> (GetProcAddress (shlwDll, MAKEINTRESOURCEA (12))); IStream* stream = proc (static_cast<const BYTE*> (ptr), memSize); #else IStream* stream = SHCreateMemStream ((const BYTE*)ptr, memSize); #endif if (stream) { #if VSTGUI_DIRECT2D_SUPPORT if (getD2DFactory ()) { D2DBitmap* result = new D2DBitmap (); if (result->loadFromStream (stream)) { stream->Release (); return result; } stream->Release (); result->forget (); return 0; } #endif GdiplusBitmap* bitmap = new GdiplusBitmap (); if (bitmap->loadFromStream (stream)) { stream->Release (); return bitmap; } bitmap->forget (); stream->Release (); } #ifdef __GNUC__ FreeLibrary (shlwDll); #endif return 0; }
//----------------------------------------------------------------------------- Win32Frame::Win32Frame (IPlatformFrameCallback* frame, const CRect& size, HWND parent) : IPlatformFrame (frame) , windowHandle (0) , parentWindow (parent) , tooltipWindow (0) , backBuffer (0) , deviceContext (0) , inPaint (false) , mouseInside (false) , updateRegionList (0) , updateRegionListSize (0) { initWindowClass (); DWORD style = isParentLayered (parent) ? WS_EX_TRANSPARENT : 0; #if !DEBUG_DRAWING if (getD2DFactory ()) // workaround for Direct2D hotfix (KB2028560) { // when WS_EX_COMPOSITED is set drawing does not work correctly. This seems like a bug in Direct2D wich happens with this hotfix } else if (getSystemVersion ().dwMajorVersion >= 6) // Vista and above style |= WS_EX_COMPOSITED; else backBuffer = createOffscreenContext (size.getWidth (), size.getHeight ()); #endif windowHandle = CreateWindowEx (style, gClassName, TEXT("Window"), WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, (int)size.width (), (int)size.height (), parentWindow, NULL, GetInstance (), NULL); if (windowHandle) { SetWindowLongPtr (windowHandle, GWLP_USERDATA, (__int3264)(LONG_PTR)this); RegisterDragDrop (windowHandle, new CDropTarget (this)); } }
//----------------------------------------------------------------------------- ID2D1PathGeometry* D2DGraphicsPath::getPath (int32_t fillMode) { if (path == 0 || fillMode != currentPathFillMode) { dirty (); if (!SUCCEEDED (getD2DFactory ()->CreatePathGeometry (&path))) return 0; if (fillMode == -1) fillMode = 0; currentPathFillMode = fillMode; ID2D1GeometrySink* sink = 0; if (!SUCCEEDED (path->Open (&sink))) { path->Release (); path = 0; return 0; } sink->SetFillMode ((D2D1_FILL_MODE)fillMode); bool figureOpen = false; CPoint lastPos; for (ElementList::const_iterator it = elements.begin (); it != elements.end (); it++) { Element e = (*it); switch (e.type) { case Element::kArc: { bool clockwise = e.instruction.arc.clockwise; double startAngle = e.instruction.arc.startAngle; double endAngle = e.instruction.arc.endAngle; CRect o_r (e.instruction.arc.rect.left, e.instruction.arc.rect.top, e.instruction.arc.rect.right, e.instruction.arc.rect.bottom); CRect r (o_r); o_r.originize (); CPoint center = o_r.getCenter (); CPoint start; start.x = r.left + center.x + center.x * cos (radians (startAngle)); start.y = r.top + center.y + center.y * sin (radians (startAngle)); if (!figureOpen) { sink->BeginFigure (makeD2DPoint (start), D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } else if (lastPos != start) { sink->AddLine (makeD2DPoint (start)); } double sweepangle = endAngle - startAngle; if (clockwise) { // sweepangle positive while (sweepangle < 0.0) sweepangle += 360.0; while (sweepangle > 360.0) sweepangle -= 360.0; } else { // sweepangle negative while (sweepangle > 0.0) sweepangle -= 360.0; while (sweepangle < -360.0) sweepangle += 360.0; } CPoint endPoint; endPoint.x = r.left + center.x + center.x * cos (radians (endAngle)); endPoint.y = r.top + center.y + center.y * sin (radians (endAngle)); D2D1_ARC_SEGMENT arc; arc.size = makeD2DSize (r.getWidth ()/2., r.getHeight ()/2.); arc.rotationAngle = 0; arc.sweepDirection = clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE; arc.point = makeD2DPoint (endPoint); arc.arcSize = fabs(sweepangle) <= 180. ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE; sink->AddArc (arc); lastPos = endPoint; break; } case Element::kEllipse: { CRect r (e.instruction.rect.left, e.instruction.rect.top, e.instruction.rect.right, e.instruction.rect.bottom); CPoint top (r.getTopLeft ()); top.x += r.getWidth () / 2.; CPoint bottom (r.getBottomLeft ()); bottom.x += r.getWidth () / 2.; if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top)) { sink->EndFigure (D2D1_FIGURE_END_OPEN); figureOpen = false; } if (!figureOpen) { sink->BeginFigure (makeD2DPoint (top), D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } D2D1_ARC_SEGMENT arc = D2D1::ArcSegment (makeD2DPoint (bottom), D2D1::SizeF ((FLOAT)r.getWidth ()/2.f, (FLOAT)r.getHeight ()/2.f), 180.f, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL); sink->AddArc (arc); arc.point = makeD2DPoint (top); sink->AddArc (arc); lastPos = top; break; } case Element::kRect: { D2D1_POINT_2F points[4] = { {(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.top}, {(FLOAT)e.instruction.rect.right, (FLOAT)e.instruction.rect.bottom}, {(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.bottom}, {(FLOAT)e.instruction.rect.left, (FLOAT)e.instruction.rect.top} }; if (figureOpen && lastPos != CPoint (e.instruction.rect.left, e.instruction.rect.top)) { sink->EndFigure (D2D1_FIGURE_END_OPEN); figureOpen = false; } if (figureOpen == false) { sink->BeginFigure (points[3], D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; } sink->AddLine (points[0]); sink->AddLine (points[1]); sink->AddLine (points[2]); sink->AddLine (points[3]); lastPos = CPoint (e.instruction.rect.left, e.instruction.rect.top); break; } case Element::kLine: { if (figureOpen) { D2D1_POINT_2F end = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y}; sink->AddLine (end); lastPos = CPoint (e.instruction.point.x, e.instruction.point.y); } break; } case Element::kBezierCurve: { if (figureOpen) { D2D1_POINT_2F control1 = {(FLOAT)e.instruction.curve.control1.x, (FLOAT)e.instruction.curve.control1.y}; D2D1_POINT_2F control2 = {(FLOAT)e.instruction.curve.control2.x, (FLOAT)e.instruction.curve.control2.y}; D2D1_POINT_2F end = {(FLOAT)e.instruction.curve.end.x, (FLOAT)e.instruction.curve.end.y}; D2D1_BEZIER_SEGMENT bezier = D2D1::BezierSegment (control1, control2, end); sink->AddBezier (bezier); lastPos = CPoint (e.instruction.curve.end.x, e.instruction.curve.end.y); } break; } case Element::kBeginSubpath: { if (figureOpen) sink->EndFigure (D2D1_FIGURE_END_OPEN); D2D1_POINT_2F start = {(FLOAT)e.instruction.point.x, (FLOAT)e.instruction.point.y}; sink->BeginFigure (start, D2D1_FIGURE_BEGIN_FILLED); figureOpen = true; lastPos = CPoint (e.instruction.point.x, e.instruction.point.y); break; } case Element::kCloseSubpath: { if (figureOpen) { sink->EndFigure (D2D1_FIGURE_END_CLOSED); figureOpen = false; } break; } } } if (figureOpen) sink->EndFigure (D2D1_FIGURE_END_OPEN); HRESULT res = sink->Close (); if (!SUCCEEDED (res)) { path->Release (); path = 0; } sink->Release (); } return path; }
//----------------------------------------------------------------------------- Win32TextEdit::Win32TextEdit (HWND parent, IPlatformTextEditCallback* textEdit) : IPlatformTextEdit (textEdit) , platformControl (0) , platformFont (0) , platformBackColor (0) , oldWndProcEdit (0) { CRect rect = textEdit->platformGetSize (); CFontRef fontID = textEdit->platformGetFont (); CHoriTxtAlign horiTxtAlign = textEdit->platformGetHoriTxtAlign (); int wstyle = 0; if (horiTxtAlign == kLeftText) wstyle |= ES_LEFT; else if (horiTxtAlign == kRightText) wstyle |= ES_RIGHT; else wstyle |= ES_CENTER; CPoint textInset = textEdit->platformGetTextInset (); rect.offset (textInset.x, textInset.y); rect.right -= textInset.x*2; rect.bottom -= textInset.y*2; // get/set the current font LOGFONT logfont = {0}; CCoord fontH = fontID->getSize (); if (fontH > rect.getHeight ()) fontH = rect.getHeight () - 3; if (fontH < rect.getHeight ()) { CCoord adjust = (rect.getHeight () - (fontH + 3)) / (CCoord)2; rect.top += adjust; rect.bottom -= adjust; } UTF8StringHelper stringHelper (textEdit->platformGetText ()); text = stringHelper; DWORD wxStyle = 0; if (getD2DFactory () == 0 && getSystemVersion ().dwMajorVersion >= 6) // Vista and above wxStyle = WS_EX_COMPOSITED; wstyle |= WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL; platformControl = CreateWindowEx (wxStyle, TEXT("EDIT"), stringHelper, wstyle, (int)rect.left, (int)rect.top, (int)rect.getWidth (), (int)rect.getHeight (), parent, NULL, GetInstance (), 0); logfont.lfWeight = FW_NORMAL; logfont.lfHeight = (LONG)-fontH; logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS; UTF8StringHelper fontNameHelper (fontID->getName ()); VSTGUI_STRCPY (logfont.lfFaceName, fontNameHelper); logfont.lfClipPrecision = CLIP_STROKE_PRECIS; logfont.lfOutPrecision = OUT_STRING_PRECIS; logfont.lfQuality = DEFAULT_QUALITY; logfont.lfCharSet = ANSI_CHARSET; platformFont = CreateFontIndirect (&logfont); SetWindowLongPtr (platformControl, GWLP_USERDATA, (__int3264)(LONG_PTR)this); SendMessage (platformControl, WM_SETFONT, (WPARAM)platformFont, true); SendMessage (platformControl, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG (0, 0)); SendMessage (platformControl, EM_SETSEL, 0, -1); SendMessage (platformControl, EM_LIMITTEXT, 255, 0); SetFocus (platformControl); oldWndProcEdit = (WINDOWSPROC)(LONG_PTR)SetWindowLongPtr (platformControl, GWLP_WNDPROC, (__int3264)(LONG_PTR)procEdit); CColor backColor = textEdit->platformGetBackColor (); platformBackColor = CreateSolidBrush (RGB (backColor.red, backColor.green, backColor.blue)); }