//-----------------------------------------------------------------------------
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);
}
Exemple #3
0
//-----------------------------------------------------------------------------
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 ();
    }
}
Exemple #5
0
//-----------------------------------------------------------------------------
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);
}
Exemple #6
0
//-----------------------------------------------------------------------------
bool IPlatformFont::getAllPlatformFontFamilies (std::list<std::string>& fontFamilyNames)
{
#if VSTGUI_DIRECT2D_SUPPORT
	if (getD2DFactory ())
	{
		return D2DFont::getAllPlatformFontFamilies (fontFamilyNames);
	}
#endif
	return GdiPlusFont::getAllPlatformFontFamilies (fontFamilyNames);
}
Exemple #7
0
//-----------------------------------------------------------------------------
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;
}
Exemple #8
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 ();
	}
}
Exemple #10
0
//-----------------------------------------------------------------------------
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 ();
    }
}
Exemple #12
0
//-----------------------------------------------------------------------------
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;
}
Exemple #13
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));
	}
}
Exemple #14
0
//-----------------------------------------------------------------------------
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;
}
Exemple #15
0
//-----------------------------------------------------------------------------
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));
}