1 /** DGui project file.
2 
3 Copyright: Trogu Antonio Davide 2011-2013
4 
5 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 
7 Authors: Trogu Antonio Davide
8 */
9 module dgui.canvas;
10 
11 import std.conv : to;
12 import std.path;
13 import std..string;
14 import core.memory;
15 import dgui.core.interfaces.idisposable;
16 import dgui.core.charset;
17 import dgui.core.winapi;
18 import dgui.core.exception;
19 import dgui.core.handle;
20 import dgui.core.utils;
21 public import dgui.core.geometry;
22 
23 /**
24   Enum that contain the font style of a Font Object.
25   */
26 enum FontStyle: ubyte
27 {
28 	normal = 0,		/// Normal Font Style
29 	bold = 1,		/// Bold Font Style
30 	italic = 2,		/// Italic Font Style
31 	underline = 4,	/// Underline Font Style
32 	strikeout = 8,	/// Strikeout Font Style
33 }
34 
35 /**
36   Enum that contain the image type (useful in order to identify a Image object).
37   */
38 
39 enum ImageType
40 {
41 	bitmap 		   = 0,	/// Bitmap Image
42 	iconOrCursor = 1,	/// Icon or Cursor
43 }
44 
45 /**
46   Enum that specify the fill mode of a gradient.
47   */
48 enum GradientFillRectMode
49 {
50 	horizontal = 0,	/// Horizontal Fill
51 	vertical   = 1,	/// Vertical Fill
52 }
53 
54 /**
55   Enum that specify the border type (used in a Canvas.drawEdge() call).
56   */
57 enum EdgeType: uint
58 {
59 	raisedOuter = BDR_RAISEDOUTER,	/// Raised Outer Edge
60 	raisedInner = BDR_RAISEDINNER, /// Raised Innter Edge
61 
62 	sunkenOuter = BDR_SUNKENOUTER,	/// Sunken Outer Edge
63 	sunkenInner = BDR_SUNKENINNER, /// Sunken Inner Edge
64 
65 	bump = EDGE_BUMP,				/// Bump Edge
66 	etched = EDGE_ETCHED,			/// Etched Edge
67 	raised = EDGE_RAISED,		/// Edge Raised Edge
68 	sunken = EDGE_SUNKEN,			/// Sunken Edge
69 }
70 
71 enum FrameType: uint
72 {
73 	button		= DFC_BUTTON,
74 	caption		= DFC_CAPTION,
75 	menu 		= DFC_MENU,
76 	popupMenu	= DFC_POPUPMENU,
77 	scroll		= DFC_SCROLL,
78 }
79 
80 enum FrameMode: uint
81 {
82 	button3state				= DFCS_BUTTON3STATE,
83 	buttonCheck				= DFCS_BUTTONCHECK,
84 	buttonPush					= DFCS_BUTTONPUSH,
85 	buttonRadio				= DFCS_BUTTONRADIO,
86 	buttonRadioImage			= DFCS_BUTTONRADIOIMAGE,
87 	buttonRadioMask			= DFCS_BUTTONRADIOMASK,
88 
89 	captionClose				= DFCS_CAPTIONCLOSE,
90 	captionHelp				= DFCS_CAPTIONHELP,
91 	captionMax					= DFCS_CAPTIONMAX,
92 	captionMin					= DFCS_CAPTIONMIN,
93 	captionRestore 			= DFCS_CAPTIONRESTORE,
94 
95 	menuArrow					= DFCS_MENUARROW,
96 	menuArrowRight 			= DFCS_MENUARROWRIGHT,
97 	menuBullet					= DFCS_MENUBULLET,
98 	menuCheck					= DFCS_MENUCHECK,
99 
100 	scrollComboBox				= DFCS_SCROLLCOMBOBOX,
101 	scrollDown					= DFCS_SCROLLDOWN,
102 	scrollLeft					= DFCS_SCROLLLEFT,
103 	scrollRight				= DFCS_SCROLLRIGHT,
104 	scrollSizeGrip				= DFCS_SCROLLSIZEGRIP,
105 	scrollSizeGripRight		= DFCS_SCROLLSIZEGRIPRIGHT,
106 	scrollUp					= DFCS_SCROLLUP,
107 
108 	checked						= DFCS_CHECKED,
109 	flat						= DFCS_FLAT,
110 	hot							= DFCS_HOT,
111 	inactive					= DFCS_INACTIVE,
112 	mono						= DFCS_MONO,
113 	pushed						= DFCS_PUSHED,
114 	transparent					= DFCS_TRANSPARENT,
115 }
116 
117 /**
118   Enum that specify the draw border mode  (used in a Canvas.drawEdge() call).
119   */
120 enum EdgeMode: uint
121 {
122 	adjust	 = BF_ADJUST,		/// Shrink the rectangle in order to exlude the edges that were drawn.
123 	diagonal = BF_DIAGONAL,		/// Diagonal Border.
124 	flat	 = BF_FLAT,			/// Flat Border.
125 	left	 = BF_LEFT,			/// Left Border Only.
126 	top		 = BF_TOP,			/// Top Border Only.
127 	right    = BF_RIGHT,		/// Right Border Only.
128 	bottom 	 = BF_BOTTOM,		/// Bottom Border Only.
129 	internal = BF_MIDDLE,		/// Internal Border will be filled.
130 	mono 	 = BF_MONO,			/// One Dimensional Border.
131 	rect 	 = BF_RECT,			/// Fills the entire border of the rectangle.
132 	//SOFT 	 = BF_SOFT,
133 }
134 
135 /**
136   Enum that specify the style of a Hatch Brush object
137   */
138 enum HatchStyle: int
139 {
140 	horizontal 		   = HS_HORIZONTAL,		/// The brush has horizontal stripes.
141 	vertical 		   = HS_VERTICAL,		/// The brush has vertical stripes.
142 	degree45Upward   = HS_BDIAGONAL, 		/// The brush has 45° degree rising stripes.
143 	degree45Downward = HS_FDIAGONAL,		/// The brush has 45° degree falling stripes.
144 	cross			   = HS_CROSS,			/// The brush has crossed stripes.
145 	diagonalCross	   = HS_DIAGCROSS,		/// The brush has diagonal crossed stripes.
146 }
147 
148 
149 /**
150   Enum that specify the style of a Pen object.
151   */
152 enum PenStyle: uint
153 {
154 	solid		 = PS_SOLID,		/// Solid Pen (Standard).
155 	dash		 = PS_DASH,			/// Dashed Pen.
156 	dot  		 = PS_DOT,			/// Dotted Pen.
157 	dashDot	 = PS_DASHDOT,		/// Dash-Dotted Pen.
158 	dashDotDot = PS_DASHDOTDOT,	/// Dashed-Dotted-Dotted Pen.
159 	null_		 = PS_NULL,			/// Invisible Pen.
160 	insideFrame = PS_INSIDEFRAME,	/// Solid Pen (line are drown inside the border of a closed shape).
161 }
162 
163 /**
164   Enum that specify the style of a text in a drawText() call
165   */
166 enum TextFormatFlags: uint
167 {
168 	noPrefix				= DT_NOPREFIX,		/// Turn of processing of prefix characters (like '&', character that it will be not displayed underline).
169 	wordBreak			    = DT_WORDBREAK,		/// Break the line if a carriage return is found or the selected rectangle is too small.
170 	singleLine				= DT_SINGLELINE,	/// The text is draw in one single line.
171 	lineLimit 				= DT_EDITCONTROL,	/// Duplicate the text displaying of a multiline control.
172 	noClip 				= DT_NOCLIP,		/// The text is not clipped.
173 	//DIRECTION_RIGHT_TO_LEFT = DT_RTLREADING,
174 }
175 
176 /**
177   Enum that specify the style of a text alignment in a drawText() call
178   */
179 enum TextAlignment: uint
180 {
181 	left   = DT_LEFT,		/// Text is left aligned.
182 	right  = DT_RIGHT,		/// Text is right aligned.
183 	center = DT_CENTER,		/// Text is centred horizontally.
184 
185 	top    = DT_TOP,		/// Text is top aligned.
186 	bottom = DT_BOTTOM,		/// Text is bottom aligned.
187 	middle = DT_VCENTER,	/// Text is centred vertically.
188 }
189 
190 /**
191   Enum that specify the trimming of a text alignment in a drawText() call
192   */
193 enum TextTrimming: uint
194 {
195 	none 		  = 0,					/// No Trimming.
196 	ellipsis	  = DT_END_ELLIPSIS,	/// If the text is too long, it will be replaced with end ellipsis (like: ellips...).
197 	ellipsisPath = DT_PATH_ELLIPSIS,   /// If the text is too long, it will be replaces with middle ellipsis (like: texttr...ing).
198 }
199 
200 /**
201   Specify the copy mode of a Bitmap
202   */
203 enum BitmapCopyMode
204 {
205 	normal 	= SRCCOPY,		/// Standard Copy.
206 	invert	= SRCINVERT,	/// Copy Inverted.
207 	and   	= SRCAND,		/// Copy using _AND operator (Source _AND Destination).
208 	or      = SRCPAINT,		/// Copy using _OR operator (Source _OR Destination).
209 }
210 
211 /**
212   It rappresentes a color of a bitmap.
213   */
214 struct BitmapBit
215 {
216 	union
217 	{
218 		ubyte rgbBlue;
219 		ubyte blue;			/// Blue color.
220 	}
221 
222 	union
223 	{
224 		ubyte rgbGreen;
225 		ubyte green;	    /// Green color.
226 	}
227 
228 	union
229 	{
230 		ubyte rgbRed;
231 		ubyte red;			/// Red color.
232 	}
233 
234 	union
235 	{
236 		ubyte rgbReserved;
237 		ubyte alpha; 		/// Alpha channel (if available).
238 	}
239 }
240 
241 /**
242   This structure allows direct modification of a bitmap
243   */
244 struct BitmapData
245 {
246 	BITMAPINFO* info;	/// BITMAPINFO structure (usually, it is used internally).
247 	uint imageSize;		/// The size of the _Bitmap.
248 	uint bitsCount;		/// Number of BitmapBits structure of the _Bitmap (is the _Bits field length).
249 	BitmapBit* bits;	/// Pointer to the _Bitmap's bits (it allows direct modification of the colors)
250 }
251 
252 /**
253   A _Color in ARGB format (compatible with COLORREF win32 type)
254   */
255 struct Color
256 {
257 	private bool _valid = false; // Check if it was assigned a value
258 
259 	public union
260 	{
261 		align(1) struct
262 		{
263 			ubyte red   = 0x00;
264 			ubyte green = 0x00;
265 			ubyte blue  = 0x00;
266 			ubyte alpha = 0x00; //0x00: Transparent (or Don't Care), 0xFF: Opaque
267 		}
268 
269 		COLORREF colorref;	/// Compatibility with COLORREF type
270 	}
271 
272 	/// Checks if the color information is _valid.
273 	@property public final bool valid()
274 	{
275 		return this._valid;
276 	}
277 
278 	public static Color opCall(ubyte r, ubyte g, ubyte b)
279 	{
280 		return Color(0x00, r, g, b);
281 	}
282 
283 	public static Color opCall(ubyte a, ubyte r, ubyte g, ubyte b)
284 	{
285 		Color color = void; //Inializzata sotto;
286 
287 		color._valid = true;
288 
289 		color.alpha = a;
290 		color.red = r;
291 		color.green = g;
292 		color.blue = b;
293 
294 		return color;
295 	}
296 
297 	/// Returns an invalid color
298 	public static Color invalid()
299 	{
300 		static Color color;
301 		//color._valid = false; //Set valid to false (false = default value)
302 		return color;
303 	}
304 
305 	/// Given a COLORREF, it returns a _Color object
306 	public static Color fromCOLORREF(COLORREF cref)
307 	{
308 		Color color = void;
309 
310 		color._valid = true;
311 		color.colorref = cref;
312 		return color;
313 	}
314 }
315 
316 struct FontMetrics
317 {
318 	int height;
319 	int ascent;
320 	int descent;
321 	int internalLeading;
322 	int externalLeading;
323 	int averageCharWidth;
324 	int maxCharWidth;
325 }
326 
327 /**
328  The _Canvas object is the DGui's rappresentation of a Device Context (Screen DC, Memory DC and Printer DC)
329  $(DDOC_BLANKLINE)
330  $(B Note): Printer DC is not implemented
331  */
332 class Canvas: Handle!(HDC), IDisposable
333 {
334 	private alias extern(Windows) BOOL function(HDC, int, int, int, int, HDC, int, int, int, int, UINT) GdiTransparentBltProc;
335 	private alias extern(Windows) BOOL function(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION) GdiAlphaBlendProc;
336 	private alias extern(Windows) BOOL function(HDC, TRIVERTEX*, ULONG, void*, ULONG, ULONG) GdiGradientFillProc;
337 
338 	private static GdiTransparentBltProc _gdiTransparentBlt = null;
339 	private static GdiAlphaBlendProc _gdiAlphaBlend = null;
340 	private static GdiGradientFillProc _gdiGradientFill = null;
341 
342 	private enum CanvasType: ubyte
343 	{
344 		normal = 0,
345 		fromControl = 1,
346 		inMemory = 2,
347 	}
348 
349 	private CanvasType _canvasType = CanvasType.normal;
350 	private HBITMAP _hBitmap;
351 	private bool _owned;
352 
353 	protected this(HDC hdc, bool owned, CanvasType type)
354 	{
355 		this._handle = hdc;
356 		this._owned = owned;
357 		this._canvasType = type;
358 	}
359 
360 	public ~this()
361 	{
362 		this.dispose();
363 	}
364 
365 	public void copyTo(Canvas c, BitmapCopyMode bcm, Rect destRect, Point posSrc)
366 	{
367 		BITMAP bmp;
368 
369 		if(!destRect.width && destRect.height)
370 		{
371 			GetObjectW(GetCurrentObject(this._handle, OBJ_BITMAP), BITMAP.sizeof, &bmp);
372 		}
373 
374 		BitBlt(c.handle, destRect.x, destRect.y,
375 			   destRect.width ? destRect.width : bmp.bmWidth,
376 			   destRect.height ? destRect.height : bmp.bmHeight,
377 			   this._handle, posSrc.x, posSrc.y, bcm);
378 	}
379 
380 	public void copyTo(Canvas c, Rect destRect, Point posSrc)
381 	{
382 		this.copyTo(c, BitmapCopyMode.normal, destRect, posSrc);
383 	}
384 
385 	public void copyTo(Canvas c, BitmapCopyMode bcm, Rect destRect)
386 	{
387 		this.copyTo(c, bcm, destRect, nullPoint);
388 	}
389 
390 	public void copyTo(Canvas c, BitmapCopyMode bcm)
391 	{
392 		this.copyTo(c, bcm, nullRect, nullPoint);
393 	}
394 
395 	public void copyTo(Canvas c)
396 	{
397 		this.copyTo(c, BitmapCopyMode.normal);
398 	}
399 
400 	public void copyTransparent(Canvas c, Color transpColor)
401 	{
402 		this.copyTransparent(c, transpColor, nullRect);
403 	}
404 
405 	public void copyTransparent(Canvas c, Color transpColor, Rect r)
406 	{
407 		if(!_gdiTransparentBlt)
408 		{
409 			_gdiTransparentBlt = cast(GdiTransparentBltProc)GetProcAddress(getModuleHandle("gdi32.dll"), toStringz("GdiTransparentBlt"));
410 		}
411 
412 		BITMAP bmp;
413 		HBITMAP hBitmap = GetCurrentObject(this._handle, OBJ_BITMAP);
414 		GetObjectW(hBitmap, BITMAP.sizeof, &bmp);
415 
416 		if(r.empty)
417 		{
418 			r = Rect(0, 0, bmp.bmWidth, bmp.bmHeight);
419 		}
420 
421 		_gdiTransparentBlt(c.handle, r.x, r.y, r.width, r.height, this._handle, 0, 0, bmp.bmWidth, bmp.bmHeight, transpColor.colorref);
422 	}
423 
424 	public void dispose()
425 	{
426 		if(this._handle && this._owned)
427 		{
428 			switch(this._canvasType)
429 			{
430 				case CanvasType.fromControl:
431 					ReleaseDC(WindowFromDC(this._handle), this._handle);
432 					break;
433 
434 				case CanvasType.inMemory:
435 					DeleteObject(this._hBitmap);
436 					DeleteDC(this._handle);
437 					break;
438 
439 				default:
440 					break;
441 			}
442 
443 			this._handle = null;
444 		}
445 	}
446 
447 	public static Size measureString(string s, Canvas c, Font f)
448 	{
449 		Size sz;
450 
451 		HFONT hOldFont = f ? SelectObject(c.handle, f.handle) : null;
452 		GetTextExtentPoint32W(c.handle, toUTFz!(wchar*)(s), s.length, &sz.size);
453 
454 		if(f)
455 		{
456 			SelectObject(c.handle, hOldFont);
457 		}
458 
459 		return sz;
460 	}
461 
462 	public static Size measureString(string s, Canvas c)
463 	{
464 		return Canvas.measureString(s, c, null);
465 	}
466 
467 	public static Size measureString(string s, Font f)
468 	{
469 		scope Canvas c = Screen.canvas;
470 		return Canvas.measureString(s, c, f);
471 	}
472 
473 	public static Size measureString(string s)
474 	{
475 		scope Canvas c = Screen.canvas;
476 		return Canvas.measureString(s, c, SystemFonts.windowsFont);
477 	}
478 
479 	public final void fillRectGradient(Rect r, Color startColor, Color endColor, GradientFillRectMode gfrm)
480 	{
481 		if(!_gdiGradientFill)
482 		{
483 			_gdiGradientFill = cast(GdiGradientFillProc)GetProcAddress(getModuleHandle("gdi32.dll"), toStringz("GdiGradientFill"));
484 		}
485 
486 		TRIVERTEX[2] tv;
487 		static GRADIENT_RECT gr = {UpperLeft: 0, LowerRight: 1};
488 
489 		tv[0].x = r.left;
490 		tv[0].y = r.top;
491 		tv[0].Red = startColor.red << 8;
492 		tv[0].Green = startColor.green << 8;
493 		tv[0].Blue = startColor.blue << 8;
494 		tv[0].Alpha = startColor.alpha << 8;
495 
496 		tv[1].x = r.right;
497 		tv[1].y = r.bottom;
498 		tv[1].Red = endColor.red << 8;
499 		tv[1].Green = endColor.green  << 8;
500 		tv[1].Blue =  endColor.blue << 8;
501 		tv[1].Alpha = endColor.alpha << 8;
502 
503 		_gdiGradientFill(this._handle, tv.ptr, 2, &gr, 1, gfrm);
504 	}
505 
506 	public final void fillTriangleGradient(int x1, int y1, int x2, int y2, int x3, int y3, Color color1, Color color2, Color color3)
507 	{
508 		this.fillTriangleGradient(Point(x1, y1), Point(x2, y2), Point(x3, y3), color1, color2, color3);
509 	}
510 
511 	public final void fillTriangleGradient(Point pt1, Point pt2, Point pt3, Color color1, Color color2, Color color3)
512 	{
513 		if(!_gdiGradientFill)
514 		{
515 			_gdiGradientFill = cast(GdiGradientFillProc)GetProcAddress(getModuleHandle("gdi32.dll"), toStringz("GdiGradientFill"));
516 		}
517 
518 		TRIVERTEX[3] tv;
519 		static GRADIENT_TRIANGLE gt = {Vertex1: 0, Vertex2: 1, Vertex3: 2};
520 
521 		tv[0].x = pt1.x;
522 		tv[0].y = pt1.y;
523 		tv[0].Red = color1.red << 8;
524 		tv[0].Green = color1.green << 8;
525 		tv[0].Blue = color1.blue << 8;
526 		tv[0].Alpha = color1.alpha << 8;
527 
528 		tv[1].x = pt2.x;
529 		tv[1].y = pt2.y;
530 		tv[1].Red = color2.red << 8;
531 		tv[1].Green = color2.green  << 8;
532 		tv[1].Blue = color2.blue << 8;
533 		tv[1].Alpha = color2.alpha << 8;
534 
535 		tv[2].x = pt3.x;
536 		tv[2].y = pt3.y;
537 		tv[2].Red = color3.red << 8;
538 		tv[2].Green = color3.green  << 8;
539 		tv[2].Blue = color3.blue << 8;
540 		tv[2].Alpha = color3.alpha << 8;
541 
542 		_gdiGradientFill(this._handle, tv.ptr, 3, &gt, 1, 2 /* GRADIENT_FILL_TRIANGLE */);
543 	}
544 
545 	public final void drawImage(Image img, Point upLeft, Point upRight, Point lowLeft)
546 	{
547 		this.drawImage(img, 0, 0, upLeft, upRight, lowLeft);
548 	}
549 	public final void drawImage(Image img, int x, int y, Point upLeft, Point upRight, Point lowLeft)
550 	{
551 		POINT[3] pts;
552 
553 		pts[0] = upLeft.point;
554 		pts[1] = upRight.point;
555 		pts[2] = lowLeft.point;
556 
557 		Size sz = img.size;
558 		HDC hdc = CreateCompatibleDC(this._handle);
559 		HBITMAP hOldBitmap = SelectObject(hdc, img.handle);
560 
561 		PlgBlt(this._handle, pts.ptr, hdc, x, y, sz.width, sz.height, null, 0, 0);
562 
563 		SelectObject(hdc, hOldBitmap);
564 		DeleteDC(hdc);
565 	}
566 
567 	public final void drawImage(Image img, int x, int y)
568 	{
569 		Size sz = img.size;
570 
571 		switch(img.type)
572 		{
573 			case ImageType.bitmap:
574 				HDC hdc = CreateCompatibleDC(this._handle);
575 				HBITMAP hOldBitmap = SelectObject(hdc, img.handle);
576 				BitBlt(this._handle, x, y, sz.width, sz.height, hdc, 0, 0, SRCCOPY);
577 				SelectObject(hdc, hOldBitmap);
578 				DeleteDC(hdc);
579 				break;
580 
581 			case ImageType.iconOrCursor:
582 				DrawIconEx(this._handle, x, y, img.handle, sz.width, sz.height, 0, null, DI_NORMAL);
583 				break;
584 
585 			default:
586 				break;
587 		}
588 	}
589 
590 	public final void drawImage(Image img, Rect r)
591 	{
592 		Size sz = img.size;
593 
594 		switch(img.type)
595 		{
596 			case ImageType.bitmap:
597 				HDC hdc = CreateCompatibleDC(this._handle);
598 				HBITMAP hOldBitmap = SelectObject(hdc, img.handle);
599 				StretchBlt(this._handle, r.x, r.y, r.width, r.height, hdc, 0, 0, sz.width, sz.height, SRCCOPY);
600 				SelectObject(hdc, hOldBitmap);
601 				DeleteDC(hdc);
602 				break;
603 
604 			case ImageType.iconOrCursor:
605 				DrawIconEx(this._handle, r.x, r.y, img.handle, r.width, r.height, 0, null, DI_NORMAL);
606 				break;
607 
608 			default:
609 				break;
610 		}
611 	}
612 
613 	public final void drawFrameControl(Rect r, FrameType frameType, FrameMode frameMode)
614 	{
615 		DrawFrameControl(this._handle, &r.rect, frameType, frameMode);
616 	}
617 
618 	public final void drawEdge(Rect r, EdgeType edgeType, EdgeMode edgeMode)
619 	{
620 		DrawEdge(this._handle, &r.rect, edgeType, edgeMode);
621 	}
622 
623 	public final void drawText(string text, Rect r, Color foreColor, Font font, TextFormat textFormat)
624 	{
625 		DRAWTEXTPARAMS dtp;
626 
627 		dtp.cbSize = DRAWTEXTPARAMS.sizeof;
628 		dtp.iLeftMargin = textFormat.leftMargin;
629 		dtp.iRightMargin = textFormat.rightMargin;
630 		dtp.iTabLength = textFormat.tabLength;
631 
632 		HFONT hOldFont = SelectObject(this._handle, font.handle);
633 		COLORREF oldColorRef = SetTextColor(this._handle, foreColor.colorref);
634 		int oldBkMode = SetBkMode(this._handle, TRANSPARENT);
635 
636 		drawTextEx(this._handle, text, &r.rect,
637 				   DT_EXPANDTABS | DT_TABSTOP | textFormat.formatFlags | textFormat.alignment | textFormat.trimming,
638 				   &dtp);
639 
640 		SetBkMode(this._handle, oldBkMode);
641 		SetTextColor(this._handle, oldColorRef);
642 		SelectObject(this._handle, hOldFont);
643 	}
644 
645 	public final void drawText(string text, Rect r, Color foreColor, Font font)
646 	{
647 		scope TextFormat tf = new TextFormat(TextFormatFlags.noPrefix | TextFormatFlags.wordBreak |
648 											 TextFormatFlags.noClip | TextFormatFlags.lineLimit);
649 
650 		tf.trimming = TextTrimming.none;
651 
652 		this.drawText(text, r, foreColor, font, tf);
653 	}
654 
655 	public final void drawText(string text, Rect r, Color foreColor)
656 	{
657 		scope Font f = Font.fromHFONT(GetCurrentObject(this._handle, OBJ_FONT), false);
658 		this.drawText(text, r, foreColor, f);
659 	}
660 
661 	public final void drawText(string text, Rect r, Font f, TextFormat tf)
662 	{
663 		this.drawText(text, r, Color.fromCOLORREF(GetTextColor(this._handle)), f, tf);
664 	}
665 
666 	public final void drawText(string text, Rect r, TextFormat tf)
667 	{
668 		scope Font f = Font.fromHFONT(GetCurrentObject(this._handle, OBJ_FONT), false);
669 		this.drawText(text, r, Color.fromCOLORREF(GetTextColor(this._handle)), f, tf);
670 	}
671 
672 	public final void drawText(string text, Rect r, Font f)
673 	{
674 		this.drawText(text, r, Color.fromCOLORREF(GetTextColor(this._handle)), f);
675 	}
676 
677 	public final void drawText(string text, Rect r)
678 	{
679 		scope Font f = Font.fromHFONT(GetCurrentObject(this._handle, OBJ_FONT), false);
680 		this.drawText(text, r, Color.fromCOLORREF(GetTextColor(this._handle)), f);
681 	}
682 
683 	public final void drawLine(Pen p, int x1, int y1, int x2, int y2)
684 	{
685 		HPEN hOldPen = SelectObject(this._handle, p.handle);
686 
687 		MoveToEx(this._handle, x1, y1, null);
688 		LineTo(this._handle, x2, y2);
689 
690 		SelectObject(this._handle, hOldPen);
691 	}
692 
693 	public final void drawEllipse(Pen pen, Brush fill, Rect r)
694 	{
695 		HPEN hOldPen;
696 		HBRUSH hOldBrush;
697 
698 		if(pen)
699 		{
700 			hOldPen = SelectObject(this._handle, pen.handle);
701 		}
702 
703 		if(fill)
704 		{
705 			hOldBrush = SelectObject(this._handle, fill.handle);
706 		}
707 
708 		Ellipse(this._handle, r.left, r.top, r.right, r.bottom);
709 
710 		if(hOldBrush)
711 		{
712 			SelectObject(this._handle, hOldBrush);
713 		}
714 
715 		if(hOldPen)
716 		{
717 			SelectObject(this._handle, hOldPen);
718 		}
719 	}
720 
721 	public final void drawEllipse(Pen pen, Rect r)
722 	{
723 		this.drawEllipse(pen, SystemBrushes.nullBrush, r);
724 	}
725 
726 	public final void drawRectangle(Pen pen, Brush fill, Rect r)
727 	{
728 		HPEN hOldPen;
729 		HBRUSH hOldBrush;
730 
731 		if(pen)
732 		{
733 			hOldPen = SelectObject(this._handle, pen.handle);
734 		}
735 
736 		if(fill)
737 		{
738 			hOldBrush = SelectObject(this._handle, fill.handle);
739 		}
740 
741 		Rectangle(this._handle, r.left, r.top, r.right, r.bottom);
742 
743 		if(hOldBrush)
744 		{
745 			SelectObject(this._handle, hOldBrush);
746 		}
747 
748 		if(hOldPen)
749 		{
750 			SelectObject(this._handle, hOldPen);
751 		}
752 	}
753 
754 	public final void drawRectangle(Pen pen, Rect r)
755 	{
756 		this.drawRectangle(pen, SystemBrushes.nullBrush, r);
757 	}
758 
759 	public final void fillRectangle(Brush b, Rect r)
760 	{
761 		FillRect(this._handle, &r.rect, b.handle);
762 	}
763 
764 	public final void fillEllipse(Brush b, Rect r)
765 	{
766 		this.drawEllipse(SystemPens.nullPen, b, r);
767 	}
768 
769 	public final Canvas createInMemory(Bitmap b)
770 	{
771 		HDC hdc = CreateCompatibleDC(this._handle);
772 		Canvas c = new Canvas(hdc, true, CanvasType.inMemory);
773 
774 		if(!b)
775 		{
776 			Rect r;
777 			HWND hWnd = WindowFromDC(this._handle);
778 
779 			if(hWnd)
780 			{
781 				GetClientRect(hWnd, &r.rect);
782 			}
783 			else // Try with bitmap's size
784 			{
785 				BITMAP bmp;
786 				HBITMAP hOrgBitmap = GetCurrentObject(this._handle, OBJ_BITMAP);
787 				GetObjectW(hOrgBitmap, BITMAP.sizeof, &bmp);
788 
789 				assert(bmp.bmWidth > 0 && bmp.bmHeight > 0, "Bitmap zero size");
790 				r = Rect(0, 0, bmp.bmWidth, bmp.bmHeight);
791 			}
792 
793 			HBITMAP hBitmap = CreateCompatibleBitmap(this._handle, r.width, r.height);
794 			c._hBitmap = hBitmap;
795 			SelectObject(hdc, hBitmap);  // Destroyed by Mem Canvas Object
796 		}
797 		else
798 		{
799 			SelectObject(hdc, b.handle); // This bitmap is not destroyed because the Bitmap object own his HBITMAP
800 		}
801 
802 		return c;
803 	}
804 
805 	public final Canvas createInMemory()
806 	{
807 		return this.createInMemory(null);
808 	}
809 
810 	public static Canvas fromHDC(HDC hdc, bool owned = true)
811 	{
812 		return new Canvas(hdc, owned, CanvasType.fromControl);
813 	}
814 }
815 
816 abstract class GraphicObject: Handle!(HGDIOBJ), IDisposable
817 {
818 	protected bool _owned;
819 
820 	protected this()
821 	{
822 
823 	}
824 
825 	protected this(HGDIOBJ hGdiObj, bool owned)
826 	{
827 		this._handle = hGdiObj;
828 		this._owned = owned;
829 	}
830 
831 	public ~this()
832 	{
833 		this.dispose();
834 	}
835 
836 	protected static int getInfo(T)(HGDIOBJ hGdiObj, ref T t)
837 	{
838 		return GetObjectW(hGdiObj, T.sizeof, &t);
839 	}
840 
841 	public void dispose()
842 	{
843 		if(this._handle && this._owned)
844 		{
845 			DeleteObject(this._handle);
846 			this._handle = null;
847 		}
848 	}
849 }
850 
851 abstract class Image: GraphicObject
852 {
853 	protected this()
854 	{
855 
856 	}
857 
858 	@property public abstract Size size();
859 	@property public abstract ImageType type();
860 
861 	protected this(HGDIOBJ hGdiObj, bool owned)
862 	{
863 		super(hGdiObj, owned);
864 	}
865 }
866 
867 class Bitmap: Image
868 {
869 	public this(Size sz)
870 	{
871 		HBITMAP hBitmap = this.createBitmap(sz.width, sz.height, RGB(0xFF, 0xFF, 0xFF));
872 		super(hBitmap, true);
873 	}
874 
875 	public this(Size sz, Color bc)
876 	{
877 		HBITMAP hBitmap = this.createBitmap(sz.width, sz.height, bc.colorref);
878 		super(hBitmap, true);
879 	}
880 
881 	public this(int w, int h)
882 	{
883 		HBITMAP hBitmap = this.createBitmap(w, h, RGB(0xFF, 0xFF, 0xFF));
884 		super(hBitmap, true);
885 	}
886 
887 	public this(int w, int h, Color bc)
888 	{
889 		HBITMAP hBitmap = this.createBitmap(w, h, bc.colorref);
890 		super(hBitmap, true);
891 	}
892 
893 	protected this(HBITMAP hBitmap, bool owned)
894 	{
895 		super(hBitmap, owned);
896 	}
897 
898 	protected this(string fileName)
899 	{
900 		HBITMAP hBitmap = loadImage(null, fileName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
901 
902 		if(!hBitmap)
903 		{
904 			throwException!(Win32Exception)("Cannot load Bitmap From File: '%s'", fileName);
905 		}
906 
907 		super(hBitmap, true);
908 	}
909 
910 	private static HBITMAP createBitmap(int w, int h, COLORREF backColor)
911 	{
912 		Rect r = Rect(0, 0, w, h);
913 
914 		HDC hdc = GetWindowDC(null);
915 		HDC hcdc = CreateCompatibleDC(hdc);
916 		HBITMAP hBitmap = CreateCompatibleBitmap(hdc, w, h);
917 		HBITMAP hOldBitmap = SelectObject(hcdc, hBitmap);
918 
919 		HBRUSH hBrush = CreateSolidBrush(backColor);
920 		FillRect(hcdc, &r.rect, hBrush);
921 		DeleteObject(hBrush);
922 
923 		SelectObject(hcdc, hOldBitmap);
924 		DeleteDC(hcdc);
925 		ReleaseDC(null, hdc);
926 
927 		return hBitmap;
928 	}
929 
930 	/*
931 	 *  !!! Is this procedure useful? !!!
932 	 *
933 	public Bitmap alphaBlend(ubyte alpha)
934 	{
935 		if(!_gdiAlphaBlend)
936 		{
937 			_gdiAlphaBlend = cast(GdiAlphaBlendProc)GetProcAddress(getModuleHandle("gdi32.dll"), toStringz("GdiAlphaBlend"));
938 		}
939 
940 		BITMAP b;
941 		getInfo!(BITMAP)(this._handle, b);
942 
943 		HDC hdc = GetWindowDC(null);
944 		HDC hdc1 = CreateCompatibleDC(hdc);
945 		HDC hdc2 = CreateCompatibleDC(hdc);
946 		HBITMAP hBitmap = CreateCompatibleBitmap(hdc, b.bmWidth, b.bmHeight);
947 		HBITMAP hOldBitmap1 = SelectObject(hdc1, hBitmap);
948 		HBITMAP hOldBitmap2 = SelectObject(hdc2, this._handle);
949 
950 		BLENDFUNCTION bf;
951 		bf.BlendOp = 0; // AC_SRC_OVER
952 		bf.SourceConstantAlpha = alpha;
953 
954 		if(b.bmBitsPixel == 32) // Premultiply bits if Bitmap's bpp = 32bpp
955 		{
956 			BitmapData bd;
957 			Bitmap.getData(hBitmap, bd);
958 
959 			for(int i = 0; i < bd.bitsCount; i++)
960 			{
961 				bd.bits[i].red = cast(ubyte)(bd.bits[i].red * (alpha / 0xFF));
962 				bd.bits[i].green = cast(ubyte)(bd.bits[i].green * (alpha / 0xFF));
963 				bd.bits[i].blue = cast(ubyte)(bd.bits[i].blue * (alpha / 0xFF));
964 			}
965 
966 			Bitmap.setData(hBitmap, bd);
967 
968 			bf.AlphaFormat = 1; // AC_SRC_ALPHA
969 		}
970 
971 		_gdiAlphaBlend(hdc1, 0, 0, b.bmWidth, b.bmHeight, hdc2, 0, 0, b.bmWidth, b.bmHeight, bf);
972 
973 		SelectObject(hdc2, hOldBitmap2);
974 		SelectObject(hdc1, hOldBitmap1);
975 		DeleteDC(hdc2);
976 		DeleteDC(hdc1);
977 		ReleaseDC(null, hdc);
978 
979 		return Bitmap.fromHBITMAP(hBitmap);
980 	}
981 	*/
982 
983 	public Bitmap clone()
984 	{
985 		BITMAP b;
986 		getInfo!(BITMAP)(this._handle, b);
987 
988 		HDC hdc = GetDC(null);
989 		HDC hcdc1 = CreateCompatibleDC(hdc); // Contains this bitmap
990 		HDC hcdc2 = CreateCompatibleDC(hdc); // The Bitmap will be copied here
991 		HBITMAP hBitmap = CreateCompatibleBitmap(hdc, b.bmWidth, b.bmHeight); //Don't delete it, it will be deleted by the class Bitmap
992 
993 		HBITMAP hOldBitmap1 = SelectObject(hcdc1, this._handle);
994 		HBITMAP hOldBitmap2 = SelectObject(hcdc2, hBitmap);
995 
996 		BitBlt(hcdc2, 0, 0, b.bmWidth, b.bmHeight, hcdc1, 0, 0, SRCCOPY);
997 		SelectObject(hcdc2, hOldBitmap2);
998 		SelectObject(hcdc1, hOldBitmap1);
999 
1000 		DeleteDC(hcdc2);
1001 		DeleteDC(hcdc1);
1002 		ReleaseDC(null, hdc);
1003 
1004 		Bitmap bmp = new Bitmap(hBitmap, true);
1005 		return bmp;
1006 	}
1007 
1008 	public static void getData(HBITMAP hBitmap, ref BitmapData bd)
1009 	{
1010 		BITMAPINFO bi;
1011 		bi.bmiHeader.biSize = BITMAPINFOHEADER.sizeof;
1012 		bi.bmiHeader.biBitCount = 0;
1013 
1014 		HDC hdc = GetWindowDC(null);
1015 		GetDIBits(hdc, hBitmap, 0, 0, null, &bi, DIB_RGB_COLORS); // Get Bitmap Info
1016 
1017 		bd.imageSize = bi.bmiHeader.biSizeImage;
1018 		bd.bitsCount = bi.bmiHeader.biSizeImage / RGBQUAD.sizeof;
1019 		bd.bits = cast(BitmapBit*)GC.malloc(bi.bmiHeader.biSizeImage);
1020 
1021 		switch(bi.bmiHeader.biBitCount) // Calculate color table size (if needed)
1022 		{
1023 			case 24:
1024 				bd.info = cast(BITMAPINFO*)GC.malloc(bi.bmiHeader.biSize);
1025 				break;
1026 
1027 			case 16, 32:
1028 				bd.info = cast(BITMAPINFO*)GC.malloc(bi.bmiHeader.biSize + uint.sizeof * 3); // Needs Investigation
1029 				break;
1030 
1031 			default:
1032 				bd.info = cast(BITMAPINFO*)GC.malloc(bi.bmiHeader.biSize + RGBQUAD.sizeof * (1 << bi.bmiHeader.biBitCount));
1033 				break;
1034 		}
1035 
1036 		bd.info.bmiHeader = bi.bmiHeader;
1037 		GetDIBits(hdc, hBitmap, 0, bd.info.bmiHeader.biHeight, cast(RGBQUAD*)bd.bits, bd.info, DIB_RGB_COLORS);
1038 		ReleaseDC(null, hdc);
1039 	}
1040 
1041 
1042 	public void getData(ref BitmapData bd)
1043 	{
1044 		return Bitmap.getData(this._handle, bd);
1045 	}
1046 
1047 	private static void setData(HBITMAP hBitmap, ref BitmapData bd)
1048 	{
1049 		HDC hdc = GetWindowDC(null);
1050 		SetDIBits(hdc, hBitmap, 0, bd.info.bmiHeader.biHeight, cast(RGBQUAD*)bd.bits, bd.info, DIB_RGB_COLORS);
1051 
1052 		ReleaseDC(null, hdc);
1053 		Bitmap.freeData(bd);
1054 	}
1055 
1056 	public void setData(ref BitmapData bd)
1057 	{
1058 		Bitmap.setData(this._handle, bd);
1059 	}
1060 
1061 	public static void freeData(ref BitmapData bd)
1062 	{
1063 		GC.free(bd.bits);
1064 		GC.free(bd.info);
1065 	}
1066 
1067 	@property public override Size size()
1068 	{
1069 		BITMAP bmp = void; //Inizializzata da getInfo()
1070 
1071 		getInfo!(BITMAP)(this._handle, bmp);
1072 		return Size(bmp.bmWidth, bmp.bmHeight);
1073 	}
1074 
1075 	@property public override ImageType type()
1076 	{
1077 		return ImageType.bitmap;
1078 	}
1079 
1080 	public static Bitmap fromHBITMAP(HBITMAP hBitmap, bool owned = true)
1081 	{
1082 		return new Bitmap(hBitmap, owned);
1083 	}
1084 
1085 	public static Bitmap fromFile(string fileName)
1086 	{
1087 		return new Bitmap(fileName);
1088 	}
1089 }
1090 
1091 class Icon: Image
1092 {
1093 	protected this(HICON hIcon, bool owned)
1094 	{
1095 		super(hIcon, owned);
1096 	}
1097 
1098 	protected this(string fileName)
1099 	{
1100 		HICON hIcon;
1101 
1102 		if(!icmp(std.path.extension(fileName), ".ico"))
1103 		{
1104 			hIcon = loadImage(null, fileName, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
1105 		}
1106 		else
1107 		{
1108 			ushort dummy = 0;
1109 			hIcon = extractAssociatedIcon(fileName, &dummy);
1110 		}
1111 
1112 		if(!hIcon)
1113 		{
1114 			throwException!(Win32Exception)("Cannot load Icon From File: '%s'", fileName);
1115 		}
1116 
1117 		super(hIcon, true);
1118 	}
1119 
1120 	public override void dispose()
1121 	{
1122 		if(this._handle && this._owned)
1123 		{
1124 			DestroyIcon(this._handle); // Use DestroyIcon() not DestroyObject()
1125 		}
1126 	}
1127 
1128 	@property public override Size size()
1129 	{
1130 		ICONINFO ii = void; //Inizializzata da GetIconInfo()
1131 		BITMAP bmp = void; //Inizializzata da getInfo()
1132 		Size sz = void; //Inizializzata sotto.
1133 
1134 		if(!GetIconInfo(this._handle, &ii))
1135 		{
1136 			throwException!(Win32Exception)("Unable to get information from Icon");
1137 		}
1138 
1139 		if(ii.hbmColor) //Exists: Icon Color Bitmap
1140 		{
1141 			if(!getInfo!(BITMAP)(ii.hbmColor, bmp))
1142 			{
1143 				throwException!(Win32Exception)("Unable to get Icon Color Bitmap");
1144 			}
1145 
1146 			sz.width = bmp.bmWidth;
1147 			sz.height = bmp.bmHeight;
1148 			DeleteObject(ii.hbmColor);
1149 		}
1150 		else
1151 		{
1152 			if(!getInfo!(BITMAP)(ii.hbmMask, bmp))
1153 			{
1154 				throwException!(Win32Exception)("Unable to get Icon Mask");
1155 			}
1156 
1157 			sz.width = bmp.bmWidth;
1158 			sz.height = bmp.bmHeight / 2;
1159 		}
1160 
1161 		DeleteObject(ii.hbmMask);
1162 		return sz;
1163 	}
1164 
1165 	@property public override ImageType type()
1166 	{
1167 		return ImageType.iconOrCursor;
1168 	}
1169 
1170 	public Bitmap toBitmap(Size sz)
1171 	{
1172 		HDC hwdc = GetWindowDC(null);
1173 		HDC hdc1 = CreateCompatibleDC(hwdc);
1174 
1175 		HBITMAP hBitmap = CreateCompatibleBitmap(hwdc, sz.width, sz.height);
1176 		HBITMAP hOldBitmap = SelectObject(hdc1, hBitmap);
1177 
1178 		Rect r = Rect(nullPoint, sz);
1179 		HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
1180 		FillRect(hdc1, &r.rect, hBrush);
1181 		DeleteObject(hBrush);
1182 
1183 		DrawIconEx(hdc1, 0, 0, this._handle, sz.width, sz.height, 0, null, DI_NORMAL);
1184 		SelectObject(hdc1, hOldBitmap);
1185 		DeleteDC(hdc1);
1186 		ReleaseDC(null, hwdc);
1187 
1188 		return Bitmap.fromHBITMAP(hBitmap);
1189 	}
1190 
1191 	public Bitmap toBitmap()
1192 	{
1193 		Size sz = this.size;
1194 		return this.toBitmap(sz);
1195 	}
1196 
1197 	public static Icon fromHICON(HICON hIcon, bool owned = true)
1198 	{
1199 		return new Icon(hIcon, owned);
1200 	}
1201 
1202 	public static Icon fromFile(string fileName)
1203 	{
1204 		return new Icon(fileName);
1205 	}
1206 }
1207 
1208 final class Cursor: Icon
1209 {
1210 	protected this(HCURSOR hCursor, bool owned)
1211 	{
1212 		super(hCursor, owned);
1213 	}
1214 
1215 	public override void dispose()
1216 	{
1217 		if(this._handle && this._owned)
1218 		{
1219 			DestroyCursor(this._handle); // Use DestroyCursor() not DestroyObject()
1220 		}
1221 	}
1222 
1223 	@property public static Point position()
1224 	{
1225 		Point pt;
1226 
1227 		GetCursorPos(&pt.point);
1228 		return pt;
1229 	}
1230 
1231 	public static Cursor fromHCURSOR(HCURSOR hCursor, bool owned = true)
1232 	{
1233 		return new Cursor(hCursor, owned);
1234 	}
1235 }
1236 
1237 final class Font: GraphicObject
1238 {
1239 	private static int _logPixelSY = 0;
1240 
1241 	private bool _metricsDone = false;
1242 	private FontMetrics _metrics;
1243 
1244 	private this(HFONT hFont, bool owned)
1245 	{
1246 		super(hFont, owned);
1247 	}
1248 
1249 	private static void initLogPixelSY()
1250 	{
1251 		if(!_logPixelSY)
1252 		{
1253 			HDC hdc = GetWindowDC(null);
1254 			_logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
1255 			ReleaseDC(null, hdc);
1256 		}
1257 	}
1258 
1259 	public this(string name, int h, FontStyle style = FontStyle.normal)
1260 	{
1261 		Font.initLogPixelSY();
1262 
1263 		LOGFONTW lf;
1264 		lf.lfHeight = -MulDiv(h, _logPixelSY, 72);
1265 
1266 		doStyle(style, lf);
1267 		this._handle = createFontIndirect(name, &lf);
1268 	}
1269 
1270 	public this(Font f, FontStyle fs)
1271 	{
1272 		LOGFONTW lf;
1273 
1274 		getInfo!(LOGFONTW)(f.handle, lf);
1275 		doStyle(fs, lf);
1276 		this._handle = createFontIndirect(&lf);
1277 	}
1278 
1279 	@property public string name()
1280 	{
1281 		LOGFONTW lf;
1282 
1283 		getInfo!(LOGFONTW)(this._handle, lf);
1284 		int idx = indexOf(lf.lfFaceName, '\0');
1285 		return to!(string)(lf.lfFaceName[0..idx]);
1286 	}
1287 
1288 	@property public int height()
1289 	{
1290 		LOGFONTW lf;
1291 
1292 		Font.initLogPixelSY();
1293 
1294 		getInfo!(LOGFONTW)(this._handle, lf);
1295 		return -MulDiv(72, lf.lfHeight, _logPixelSY);
1296 	}
1297 
1298 	@property public FontMetrics metrics()
1299 	{
1300 		if(!this._metricsDone)
1301 		{
1302 			TEXTMETRICW tm;
1303 
1304 			HDC hdc = CreateCompatibleDC(null);
1305 			HFONT hOldFont = SelectObject(hdc, this._handle);
1306 			GetTextMetricsW(hdc, &tm);
1307 			SelectObject(hdc, hOldFont);
1308 			DeleteDC(hdc);
1309 
1310 			this._metrics.height = tm.tmHeight;
1311 			this._metrics.ascent = tm.tmAscent;
1312 			this._metrics.descent = tm.tmDescent;
1313 			this._metrics.internalLeading = tm.tmInternalLeading;
1314 			this._metrics.externalLeading = tm.tmExternalLeading;
1315 			this._metrics.averageCharWidth = tm.tmAveCharWidth;
1316 			this._metrics.maxCharWidth = tm.tmMaxCharWidth;
1317 
1318 			this._metricsDone = true;
1319 		}
1320 
1321 		return this._metrics;
1322 	}
1323 
1324 	private static void doStyle(FontStyle style, ref LOGFONTW lf)
1325 	{
1326 		lf.lfCharSet = DEFAULT_CHARSET;
1327 		lf.lfWeight = FW_NORMAL;
1328 		//lf.lfItalic = FALSE;    Inizializzata dal compilatore
1329 		//lf.lfStrikeOut = FALSE; Inizializzata dal compilatore
1330 		//lf.lfUnderline = FALSE; Inizializzata dal compilatore
1331 
1332 		if(style & FontStyle.bold)
1333 		{
1334 			lf.lfWeight = FW_BOLD;
1335 		}
1336 
1337 		if(style & FontStyle.italic)
1338 		{
1339 			lf.lfItalic = 1;
1340 		}
1341 
1342 		if(style & FontStyle.strikeout)
1343 		{
1344 			lf.lfStrikeOut = 1;
1345 		}
1346 
1347 		if(style & FontStyle.underline)
1348 		{
1349 			lf.lfUnderline = 1;
1350 		}
1351 	}
1352 
1353 	public static Font fromHFONT(HFONT hFont, bool owned = true)
1354 	{
1355 		return new Font(hFont, owned);
1356 	}
1357 }
1358 
1359 abstract class Brush: GraphicObject
1360 {
1361 	protected this(HBRUSH hBrush, bool owned)
1362 	{
1363 		super(hBrush, owned);
1364 	}
1365 }
1366 
1367 class SolidBrush: Brush
1368 {
1369 	private Color _color;
1370 
1371 	protected this(HBRUSH hBrush, bool owned)
1372 	{
1373 		super(hBrush, owned);
1374 	}
1375 
1376 	public this(Color color)
1377 	{
1378 		this._color = color;
1379 		super(CreateSolidBrush(color.colorref), true);
1380 	}
1381 
1382 	@property public final Color color()
1383 	{
1384 		return this._color;
1385 	}
1386 
1387 	public static SolidBrush fromHBRUSH(HBRUSH hBrush, bool owned = true)
1388 	{
1389 		return new SolidBrush(hBrush, owned);
1390 	}
1391 }
1392 
1393 class HatchBrush: Brush
1394 {
1395 	private Color _color;
1396 	private HatchStyle _style;
1397 
1398 	protected this(HBRUSH hBrush, bool owned)
1399 	{
1400 		super(hBrush, owned);
1401 	}
1402 
1403 	public this(Color color, HatchStyle style)
1404 	{
1405 		this._color = color;
1406 		this._style = style;
1407 
1408 		super(CreateHatchBrush(style, color.colorref), true);
1409 	}
1410 
1411 	@property public final Color color()
1412 	{
1413 		return this._color;
1414 	}
1415 
1416 	@property public final HatchStyle style()
1417 	{
1418 		return this._style;
1419 	}
1420 
1421 	public static HatchBrush fromHBRUSH(HBRUSH hBrush, bool owned = true)
1422 	{
1423 		return new HatchBrush(hBrush, owned);
1424 	}
1425 }
1426 
1427 class PatternBrush: Brush
1428 {
1429 	private Bitmap _bmp;
1430 
1431 	protected this(HBRUSH hBrush, bool owned)
1432 	{
1433 		super(hBrush, owned);
1434 	}
1435 
1436 	public this(Bitmap bmp)
1437 	{
1438 		this._bmp = bmp;
1439 		super(CreatePatternBrush(bmp.handle), true);
1440 	}
1441 
1442 	@property public final Bitmap bitmap()
1443 	{
1444 		return this._bmp;
1445 	}
1446 
1447 	public static PatternBrush fromHBRUSH(HBRUSH hBrush, bool owned = true)
1448 	{
1449 		return new PatternBrush(hBrush, owned);
1450 	}
1451 }
1452 
1453 final class Pen: GraphicObject
1454 {
1455 	private PenStyle _style;
1456 	private Color _color;
1457 	private int _width;
1458 
1459 	protected this(HPEN hPen, bool owned)
1460 	{
1461 		super(hPen, owned);
1462 	}
1463 
1464 	public this(Color color, int width = 1, PenStyle style = PenStyle.solid)
1465 	{
1466 		this._color = color;
1467 		this._width = width;
1468 		this._style = style;
1469 
1470 		this._handle = CreatePen(style, width, color.colorref);
1471 
1472 		super(this._handle, true);
1473 	}
1474 
1475 	@property public PenStyle style()
1476 	{
1477 		return this._style;
1478 	}
1479 
1480 	@property public int width()
1481 	{
1482 		return this._width;
1483 	}
1484 
1485 	@property public Color color()
1486 	{
1487 		return this._color;
1488 	}
1489 
1490 	public static Pen fromHPEN(HPEN hPen, bool owned = true)
1491 	{
1492 		return new Pen(hPen, owned);
1493 	}
1494 }
1495 
1496 final class SystemPens
1497 {
1498 	@property public static Pen nullPen()
1499 	{
1500 		return Pen.fromHPEN(GetStockObject(NULL_PEN), false);
1501 	}
1502 
1503 	@property public static Pen blackPen()
1504 	{
1505 		return Pen.fromHPEN(GetStockObject(BLACK_PEN), false);
1506 	}
1507 
1508 	@property public static Pen whitePen()
1509 	{
1510 		return Pen.fromHPEN(GetStockObject(WHITE_PEN), false);
1511 	}
1512 }
1513 
1514 final class SystemIcons
1515 {
1516 	@property public static Icon application()
1517 	{
1518 		static Icon ico;
1519 
1520 		if(!ico)
1521 		{
1522 			HICON hIco = loadImage(null, cast(wchar*)IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
1523 			ico = Icon.fromHICON(hIco);
1524 		}
1525 
1526 		return ico;
1527 	}
1528 
1529 	@property public static Icon asterisk()
1530 	{
1531 		static Icon ico;
1532 
1533 		if(!ico)
1534 		{
1535 			HICON hIco = loadImage(null, IDI_ASTERISK, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
1536 			ico = Icon.fromHICON(hIco);
1537 		}
1538 
1539 		return ico;
1540 	}
1541 
1542 	@property public static Icon error()
1543 	{
1544 		static Icon ico;
1545 
1546 		if(!ico)
1547 		{
1548 			HICON hIco = loadImage(null, IDI_ERROR, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
1549 			ico = Icon.fromHICON(hIco);
1550 		}
1551 
1552 		return ico;
1553 	}
1554 
1555 	@property public static Icon question()
1556 	{
1557 		static Icon ico;
1558 
1559 		if(!ico)
1560 		{
1561 			HICON hIco = loadImage(null, IDI_QUESTION, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
1562 			ico = Icon.fromHICON(hIco);
1563 		}
1564 
1565 		return ico;
1566 	}
1567 
1568 	@property public static Icon warning()
1569 	{
1570 		static Icon ico;
1571 
1572 		if(!ico)
1573 		{
1574 			HICON hIco = loadImage(null, IDI_WARNING, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
1575 			ico = Icon.fromHICON(hIco);
1576 		}
1577 
1578 		return ico;
1579 	}
1580 }
1581 
1582 final class SystemBrushes
1583 {
1584 	@property public static SolidBrush blackBrush()
1585 	{
1586 		return SolidBrush.fromHBRUSH(GetStockObject(BLACK_BRUSH), false);
1587 	}
1588 
1589 	@property public static SolidBrush darkGrayBrush()
1590 	{
1591 		return SolidBrush.fromHBRUSH(GetStockObject(DKGRAY_BRUSH), false);
1592 	}
1593 
1594 	@property public static SolidBrush grayBrush()
1595 	{
1596 		return SolidBrush.fromHBRUSH(GetStockObject(GRAY_BRUSH), false);
1597 	}
1598 
1599 	@property public static SolidBrush lightGrayBrush()
1600 	{
1601 		return SolidBrush.fromHBRUSH(GetStockObject(LTGRAY_BRUSH), false);
1602 	}
1603 
1604 	@property public static SolidBrush nullBrush()
1605 	{
1606 		return SolidBrush.fromHBRUSH(GetStockObject(NULL_BRUSH), false);
1607 	}
1608 
1609 	@property public static SolidBrush whiteBrush()
1610 	{
1611 		return SolidBrush.fromHBRUSH(GetStockObject(WHITE_BRUSH), false);
1612 	}
1613 
1614 	@property public static SolidBrush brush3DDarkShadow()
1615 	{
1616 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_3DDKSHADOW), false);
1617 	}
1618 
1619 	@property public static SolidBrush brush3DFace()
1620 	{
1621 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_3DFACE), false);
1622 	}
1623 
1624 	@property public static SolidBrush brushButtonFace()
1625 	{
1626 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_BTNFACE), false);
1627 	}
1628 
1629 	@property public static SolidBrush brush3DLight()
1630 	{
1631 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_3DLIGHT), false);
1632 	}
1633 
1634 	@property public static SolidBrush brush3DShadow()
1635 	{
1636 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_3DSHADOW), false);
1637 	}
1638 
1639 	@property public static SolidBrush brushActiveBorder()
1640 	{
1641 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_ACTIVEBORDER), false);
1642 	}
1643 
1644 	@property public static SolidBrush brushActiveCaption()
1645 	{
1646 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_3DLIGHT), false);
1647 	}
1648 
1649 	@property public static SolidBrush brushAppWorkspace()
1650 	{
1651 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_APPWORKSPACE), false);
1652 	}
1653 
1654 	@property public static SolidBrush brushBackground()
1655 	{
1656 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_BACKGROUND), false);
1657 	}
1658 
1659 	@property public static SolidBrush brushButtonText()
1660 	{
1661 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_BTNTEXT), false);
1662 	}
1663 
1664 	@property public static SolidBrush brushCaptionText()
1665 	{
1666 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_CAPTIONTEXT), false);
1667 	}
1668 
1669 	@property public static SolidBrush brushGrayText()
1670 	{
1671 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_GRAYTEXT), false);
1672 	}
1673 
1674 	@property public static SolidBrush brushHighlight()
1675 	{
1676 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_HIGHLIGHT), false);
1677 	}
1678 
1679 	@property public static SolidBrush brushHighlightText()
1680 	{
1681 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_HIGHLIGHTTEXT), false);
1682 	}
1683 
1684 	@property public static SolidBrush brushInactiveBorder()
1685 	{
1686 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_INACTIVEBORDER), false);
1687 	}
1688 
1689 	@property public static SolidBrush brushInactiveCaption()
1690 	{
1691 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_INACTIVECAPTION), false);
1692 	}
1693 
1694 	@property public static SolidBrush brushInactiveCaptionText()
1695 	{
1696 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_INACTIVECAPTIONTEXT), false);
1697 	}
1698 
1699 	@property public static SolidBrush brushInfo()
1700 	{
1701 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_INFOBK), false);
1702 	}
1703 
1704 	@property public static SolidBrush brushInfoText()
1705 	{
1706 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_INFOTEXT), false);
1707 	}
1708 
1709 	@property public static SolidBrush brushMenu()
1710 	{
1711 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_MENU), false);
1712 	}
1713 
1714 	@property public static SolidBrush brushMenuText()
1715 	{
1716 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_MENUTEXT), false);
1717 	}
1718 
1719 	@property public static SolidBrush brushScrollBar()
1720 	{
1721 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_SCROLLBAR), false);
1722 	}
1723 
1724 	@property public static SolidBrush brushWindow()
1725 	{
1726 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_WINDOW), false);
1727 	}
1728 
1729 	@property public static SolidBrush brushWindowFrame()
1730 	{
1731 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_WINDOW), false);
1732 	}
1733 
1734 	@property public static SolidBrush brushWindowText()
1735 	{
1736 		return SolidBrush.fromHBRUSH(GetSysColorBrush(COLOR_WINDOWTEXT), false);
1737 	}
1738 }
1739 
1740 final class SystemFonts
1741 {
1742 	@property public static Font windowsFont()
1743 	{
1744 		static Font f;
1745 
1746 		if(!f)
1747 		{
1748 			NONCLIENTMETRICSW ncm = void; //La inizializza sotto.
1749 			ncm.cbSize = NONCLIENTMETRICSW.sizeof;
1750 
1751 			if(SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, NONCLIENTMETRICSW.sizeof, &ncm, 0))
1752 			{
1753 				f = Font.fromHFONT(createFontIndirect(&ncm.lfMessageFont), false);
1754 			}
1755 			else
1756 			{
1757 				f = SystemFonts.ansiVarFont;
1758 			}
1759 		}
1760 
1761 		return f;
1762 	}
1763 
1764 	@property public static Font ansiFixedFont()
1765 	{
1766 		static Font f;
1767 
1768 		if(!f)
1769 		{
1770 			f = Font.fromHFONT(GetStockObject(ANSI_FIXED_FONT), false);
1771 		}
1772 
1773 		return f;
1774 	}
1775 
1776 	@property public static Font ansiVarFont()
1777 	{
1778 		static Font f;
1779 
1780 		if(!f)
1781 		{
1782 			f = Font.fromHFONT(GetStockObject(ANSI_VAR_FONT), false);
1783 		}
1784 
1785 		return f;
1786 	}
1787 
1788 	@property public static Font deviceDefaultFont()
1789 	{
1790 		static Font f;
1791 
1792 		if(!f)
1793 		{
1794 			f = Font.fromHFONT(GetStockObject(DEVICE_DEFAULT_FONT), false);
1795 		}
1796 
1797 		return f;
1798 	}
1799 
1800 	@property public static Font oemFixedFont()
1801 	{
1802 		static Font f;
1803 
1804 		if(!f)
1805 		{
1806 			f = Font.fromHFONT(GetStockObject(OEM_FIXED_FONT), false);
1807 		}
1808 
1809 		return f;
1810 	}
1811 
1812 	@property public static Font systemFont()
1813 	{
1814 		static Font f;
1815 
1816 		if(!f)
1817 		{
1818 			f = Font.fromHFONT(GetStockObject(SYSTEM_FONT), false);
1819 		}
1820 
1821 		return f;
1822 	}
1823 
1824 	@property public static Font systemFixedFont()
1825 	{
1826 		static Font f;
1827 
1828 		if(!f)
1829 		{
1830 			f = Font.fromHFONT(GetStockObject(SYSTEM_FIXED_FONT), false);
1831 		}
1832 
1833 		return f;
1834 	}
1835 }
1836 
1837 final class SystemCursors
1838 {
1839 	@property public static Cursor appStarting()
1840 	{
1841 		static Cursor c;
1842 
1843 		if(!c)
1844 		{
1845 			 c = Cursor.fromHCURSOR(loadImage(getHInstance(), IDC_APPSTARTING, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1846 		}
1847 
1848 		return c;
1849 	}
1850 
1851 	@property public static Cursor arrow()
1852 	{
1853 		static Cursor c;
1854 
1855 		if(!c)
1856 		{
1857 			c = Cursor.fromHCURSOR(loadImage(null, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1858 		}
1859 
1860 		return c;
1861 	}
1862 
1863 	@property public static Cursor cross()
1864 	{
1865 		static Cursor c;
1866 
1867 		if(!c)
1868 		{
1869 			c = Cursor.fromHCURSOR(loadImage(null, cast(wchar*)IDC_CROSS, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1870 		}
1871 
1872 		return c;
1873 	}
1874 
1875 	@property public static Cursor iBeam()
1876 	{
1877 		static Cursor c;
1878 
1879 		if(!c)
1880 		{
1881 			c = Cursor.fromHCURSOR(loadImage(null, IDC_IBEAM, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1882 		}
1883 
1884 		return c;
1885 	}
1886 
1887 	@property public static Cursor icon()
1888 	{
1889 		static Cursor c;
1890 
1891 		if(!c)
1892 		{
1893 			c = Cursor.fromHCURSOR(loadImage(null, IDC_ICON, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1894 		}
1895 
1896 		return c;
1897 	}
1898 
1899 	@property public static Cursor no()
1900 	{
1901 		static Cursor c;
1902 
1903 		if(!c)
1904 		{
1905 			c = Cursor.fromHCURSOR(loadImage(null, IDC_NO, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1906 		}
1907 
1908 		return c;
1909 	}
1910 
1911 	@property public static Cursor sizeAll()
1912 	{
1913 		static Cursor c;
1914 
1915 		if(!c)
1916 		{
1917 			c = Cursor.fromHCURSOR(loadImage(null, IDC_SIZEALL, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1918 		}
1919 
1920 		return c;
1921 	}
1922 
1923 	@property public static Cursor sizeNESW()
1924 	{
1925 		static Cursor c;
1926 
1927 		if(!c)
1928 		{
1929 			c = Cursor.fromHCURSOR(loadImage(null, IDC_SIZENESW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1930 		}
1931 
1932 		return c;
1933 	}
1934 
1935 	@property public static Cursor sizeNS()
1936 	{
1937 		static Cursor c;
1938 
1939 		if(!c)
1940 		{
1941 			c = Cursor.fromHCURSOR(loadImage(null, IDC_SIZENS, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1942 		}
1943 
1944 		return c;
1945 	}
1946 
1947 	@property public static Cursor sizeNWSE()
1948 	{
1949 		static Cursor c;
1950 
1951 		if(!c)
1952 		{
1953 			c = Cursor.fromHCURSOR(loadImage(null, IDC_SIZENWSE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1954 		}
1955 
1956 		return c;
1957 	}
1958 
1959 	@property public static Cursor sizeWE()
1960 	{
1961 		static Cursor c;
1962 
1963 		if(!c)
1964 		{
1965 			c = Cursor.fromHCURSOR(loadImage(null, IDC_SIZEWE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1966 		}
1967 
1968 		return c;
1969 	}
1970 
1971 	@property public static Cursor upArrow()
1972 	{
1973 		static Cursor c;
1974 
1975 		if(!c)
1976 		{
1977 			c = Cursor.fromHCURSOR(loadImage(null, IDC_UPARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1978 		}
1979 
1980 		return c;
1981 	}
1982 
1983 	@property public static Cursor wait()
1984 	{
1985 		static Cursor c;
1986 
1987 		if(!c)
1988 		{
1989 			c = Cursor.fromHCURSOR(loadImage(null, IDC_WAIT, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED), false);
1990 		}
1991 
1992 		return c;
1993 	}
1994 }
1995 
1996 final class SystemColors
1997 {
1998 	@property public static Color red()
1999 	{
2000 		return Color(0xFF, 0x00, 0x00);
2001 	}
2002 
2003 	@property public static Color green()
2004 	{
2005 		return Color(0x00, 0xFF, 0x00);
2006 	}
2007 
2008 	@property public static Color blue()
2009 	{
2010 		return Color(0x00, 0x00, 0xFF);
2011 	}
2012 
2013 	@property public static Color black()
2014 	{
2015 		return Color(0x00, 0x00, 0x00);
2016 	}
2017 
2018 	@property public static Color white()
2019 	{
2020 		return Color(0xFF, 0xFF, 0xFF);
2021 	}
2022 
2023 	@property public static Color yellow()
2024 	{
2025 		return Color(0xFF, 0xFF, 0x00);
2026 	}
2027 
2028 	@property public static Color magenta()
2029 	{
2030 		return Color(0xFF, 0x00, 0xFF);
2031 	}
2032 
2033 	@property public static Color magicPink()
2034 	{
2035 		return SystemColors.magenta; //Is 'Magic Pink'
2036 	}
2037 
2038 	@property public static Color cyan()
2039 	{
2040 		return Color(0x00, 0xFF, 0xFF);
2041 	}
2042 
2043 	@property public static Color darkGray()
2044 	{
2045 		return Color(0xA9, 0xA9, 0xA9);
2046 	}
2047 
2048 	@property public static Color lightGray()
2049 	{
2050 		return Color(0xD3, 0xD3, 0xD3);
2051 	}
2052 
2053 	@property public static Color darkRed()
2054 	{
2055 		return Color(0x8B, 0x00, 0x00);
2056 	}
2057 
2058 	@property public static Color darkGreen()
2059 	{
2060 		return Color(0x00, 0x64, 0x00);
2061 	}
2062 
2063 	@property public static Color darkBlue()
2064 	{
2065 		return Color(0x00, 0x00, 0x8B);
2066 	}
2067 
2068 	@property public static Color darkYellow()
2069 	{
2070 		return Color(0x00, 0x80, 0x80);
2071 	}
2072 
2073 	@property public static Color darkMagenta()
2074 	{
2075 		return Color(0x80, 0x00, 0x80);
2076 	}
2077 
2078 	@property public static Color darkCyan()
2079 	{
2080 		return Color(0x80, 0x80, 0x00);
2081 	}
2082 
2083 	@property public static Color transparent()
2084 	{
2085 		return Color(0x00, 0x00, 0x00, 0x00);
2086 	}
2087 
2088 	@property public static Color color3DDarkShadow()
2089 	{
2090 		return Color.fromCOLORREF(GetSysColor(COLOR_3DDKSHADOW));
2091 	}
2092 
2093 	@property public static Color color3DFace()
2094 	{
2095 		return Color.fromCOLORREF(GetSysColor(COLOR_3DFACE));
2096 	}
2097 
2098 	@property public static Color colorButtonFace()
2099 	{
2100 		return Color.fromCOLORREF(GetSysColor(COLOR_BTNFACE));
2101 	}
2102 
2103 	@property public static Color color3DLight()
2104 	{
2105 		return Color.fromCOLORREF(GetSysColor(COLOR_3DLIGHT));
2106 	}
2107 
2108 	@property public static Color color3DShadow()
2109 	{
2110 		return Color.fromCOLORREF(GetSysColor(COLOR_3DSHADOW));
2111 	}
2112 
2113 	@property public static Color colorActiveBorder()
2114 	{
2115 		return Color.fromCOLORREF(GetSysColor(COLOR_ACTIVEBORDER));
2116 	}
2117 
2118 	@property public static Color colorActiveCaption()
2119 	{
2120 		return Color.fromCOLORREF(GetSysColor(COLOR_3DLIGHT));
2121 	}
2122 
2123 	@property public static Color colorAppWorkspace()
2124 	{
2125 		return Color.fromCOLORREF(GetSysColor(COLOR_APPWORKSPACE));
2126 	}
2127 
2128 	@property public static Color colorBackground()
2129 	{
2130 		return Color.fromCOLORREF(GetSysColor(COLOR_BACKGROUND));
2131 	}
2132 
2133 	@property public static Color colorButtonText()
2134 	{
2135 		return Color.fromCOLORREF(GetSysColor(COLOR_BTNTEXT));
2136 	}
2137 
2138 	@property public static Color colorCaptionText()
2139 	{
2140 		return Color.fromCOLORREF(GetSysColor(COLOR_CAPTIONTEXT));
2141 	}
2142 
2143 	@property public static Color colorGrayText()
2144 	{
2145 		return Color.fromCOLORREF(GetSysColor(COLOR_GRAYTEXT));
2146 	}
2147 
2148 	@property public static Color colorHighlight()
2149 	{
2150 		return Color.fromCOLORREF(GetSysColor(COLOR_HIGHLIGHT));
2151 	}
2152 
2153 	@property public static Color colorHighlightText()
2154 	{
2155 		return Color.fromCOLORREF(GetSysColor(COLOR_HIGHLIGHTTEXT));
2156 	}
2157 
2158 	@property public static Color colorInactiveBorder()
2159 	{
2160 		return Color.fromCOLORREF(GetSysColor(COLOR_INACTIVEBORDER));
2161 	}
2162 
2163 	@property public static Color colorInactiveCaption()
2164 	{
2165 		return Color.fromCOLORREF(GetSysColor(COLOR_INACTIVECAPTION));
2166 	}
2167 
2168 	@property public static Color colorInactiveCaptionText()
2169 	{
2170 		return Color.fromCOLORREF(GetSysColor(COLOR_INACTIVECAPTIONTEXT));
2171 	}
2172 
2173 	@property public static Color colorInfo()
2174 	{
2175 		return Color.fromCOLORREF(GetSysColor(COLOR_INFOBK));
2176 	}
2177 
2178 	@property public static Color colorInfoText()
2179 	{
2180 		return Color.fromCOLORREF(GetSysColor(COLOR_INFOTEXT));
2181 	}
2182 
2183 	@property public static Color colorMenu()
2184 	{
2185 		return Color.fromCOLORREF(GetSysColor(COLOR_MENU));
2186 	}
2187 
2188 	@property public static Color colorMenuText()
2189 	{
2190 		return Color.fromCOLORREF(GetSysColor(COLOR_MENUTEXT));
2191 	}
2192 
2193 	@property public static Color colorScrollBar()
2194 	{
2195 		return Color.fromCOLORREF(GetSysColor(COLOR_SCROLLBAR));
2196 	}
2197 
2198 	@property public static Color colorWindow()
2199 	{
2200 		return Color.fromCOLORREF(GetSysColor(COLOR_WINDOW));
2201 	}
2202 
2203 	@property public static Color colorWindowFrame()
2204 	{
2205 		return Color.fromCOLORREF(GetSysColor(COLOR_WINDOW));
2206 	}
2207 
2208 	@property public static Color colorWindowText()
2209 	{
2210 		return Color.fromCOLORREF(GetSysColor(COLOR_WINDOWTEXT));
2211 	}
2212 }
2213 
2214 final class TextFormat
2215 {
2216 	private TextTrimming _trim = TextTrimming.none; // TextTrimming.CHARACTER.
2217 	private TextFormatFlags _flags = TextFormatFlags.noPrefix | TextFormatFlags.wordBreak;
2218 	private TextAlignment _align = TextAlignment.left;
2219 	private DRAWTEXTPARAMS _params = {DRAWTEXTPARAMS.sizeof, 8, 0, 0};
2220 
2221 	public this()
2222 	{
2223 
2224 	}
2225 
2226 	public this(TextFormat tf)
2227 	{
2228 		this._trim = tf._trim;
2229 		this._flags = tf._flags;
2230 		this._align = tf._align;
2231 		this._params = tf._params;
2232 	}
2233 
2234 	public this(TextFormatFlags tff)
2235 	{
2236 		this._flags = tff;
2237 	}
2238 
2239 	@property public TextAlignment alignment()
2240 	{
2241 		return this._align;
2242 	}
2243 
2244 	@property public void alignment(TextAlignment ta)
2245 	{
2246 		this._align = ta;
2247 	}
2248 
2249 	@property public void formatFlags(TextFormatFlags tff)
2250 	{
2251 		this._flags = tff;
2252 	}
2253 
2254 	@property public TextFormatFlags formatFlags()
2255 	{
2256 		return this._flags;
2257 	}
2258 
2259 	@property public void trimming(TextTrimming tt)
2260 	{
2261 		this._trim = tt;
2262 	}
2263 
2264 	@property public TextTrimming trimming()
2265 	{
2266 		return this._trim;
2267 	}
2268 
2269 	@property public int tabLength()
2270 	{
2271 		return _params.iTabLength;
2272 	}
2273 
2274 	@property public void tabLength(int tablen)
2275 	{
2276 		this._params.iTabLength = tablen;
2277 	}
2278 
2279 	@property public int leftMargin()
2280 	{
2281 		return this._params.iLeftMargin;
2282 	}
2283 
2284 	@property public void leftMargin(int sz)
2285 	{
2286 		this._params.iLeftMargin = sz;
2287 	}
2288 
2289 	@property public int rightMargin()
2290 	{
2291 		return this._params.iRightMargin;
2292 	}
2293 
2294 	@property public void rightMargin(int sz)
2295 	{
2296 		this._params.iRightMargin = sz;
2297 	}
2298 }
2299 
2300 final class Screen
2301 {
2302 	@property public static Size size()
2303 	{
2304 		Size sz = void; //Inizializzata sotto
2305 
2306 		sz.width = GetSystemMetrics(SM_CXSCREEN);
2307 		sz.height = GetSystemMetrics(SM_CYSCREEN);
2308 
2309 		return sz;
2310 	}
2311 
2312 	@property public static Rect workArea()
2313 	{
2314 		Rect r = void; //Inizializzata sotto
2315 
2316 		SystemParametersInfoW(SPI_GETWORKAREA, 0, &r.rect, 0);
2317 		return r;
2318 	}
2319 
2320 	@property public static Canvas canvas()
2321 	{
2322 		return Canvas.fromHDC(GetWindowDC(null));
2323 	}
2324 }