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