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.core.controls.subclassedcontrol; 10 11 public import dguihub.core.controls.reflectedcontrol; 12 13 abstract class SubclassedControl : ReflectedControl { 14 private WNDPROC _oldWndProc; // Original Window Procedure 15 16 protected override void createControlParams(ref CreateControlParams ccp) { 17 this._oldWndProc = WindowClass.superclass(ccp.superclassName, 18 ccp.className, cast(WNDPROC) /*FIXME may throw*/ &Control.msgRouter); 19 } 20 21 protected override uint originalWndProc(ref Message m) { 22 if (IsWindowUnicode(this._handle)) { 23 m.result = CallWindowProcW(this._oldWndProc, this._handle, m.msg, m.wParam, m.lParam); 24 } else { 25 m.result = CallWindowProcA(this._oldWndProc, this._handle, m.msg, m.wParam, m.lParam); 26 } 27 28 return m.result; 29 } 30 31 protected override void wndProc(ref Message m) { 32 switch (m.msg) { 33 case WM_ERASEBKGND: { 34 if (SubclassedControl.hasBit(this._cBits, ControlBits.doubleBuffered)) { 35 Rect r = void; 36 GetUpdateRect(this._handle, &r.rect, false); 37 38 scope Canvas orgCanvas = Canvas.fromHDC(cast(HDC)m.wParam, false); //Don't delete it, it's a DC from WM_ERASEBKGND or WM_PAINT 39 scope Canvas memCanvas = orgCanvas.createInMemory(); // Off Screen Canvas 40 41 Message rm = m; 42 43 rm.msg = WM_ERASEBKGND; 44 rm.wParam = cast(WPARAM)memCanvas.handle; 45 this.originalWndProc(rm); 46 47 rm.msg = WM_PAINT; 48 //rm.wParam = cast(WPARAM)memCanvas.handle; 49 this.originalWndProc(rm); 50 51 scope PaintEventArgs e = new PaintEventArgs(memCanvas, r); 52 this.onPaint(e); 53 54 memCanvas.copyTo(orgCanvas, r, r.position); 55 SubclassedControl.setBit(this._cBits, ControlBits.erased, true); 56 m.result = 0; 57 } else { 58 this.originalWndProc(m); 59 } 60 } 61 break; 62 63 case WM_PAINT: { 64 if (SubclassedControl.hasBit(this._cBits, ControlBits.doubleBuffered) 65 && SubclassedControl.hasBit(this._cBits, ControlBits.erased)) { 66 SubclassedControl.setBit(this._cBits, ControlBits.erased, false); 67 m.result = 0; 68 } else { 69 /* *** Not double buffered *** */ 70 Rect r = void; 71 GetUpdateRect(this._handle, &r.rect, false); //Keep drawing area 72 this.originalWndProc(m); 73 74 scope Canvas c = Canvas.fromHDC(m.wParam ? cast(HDC)m.wParam 75 : GetDC(this._handle), m.wParam ? false : true); 76 HRGN hRgn = CreateRectRgnIndirect(&r.rect); 77 SelectClipRgn(c.handle, hRgn); 78 DeleteObject(hRgn); 79 80 SetBkColor(c.handle, this.backColor.colorref); 81 SetTextColor(c.handle, this.foreColor.colorref); 82 83 scope PaintEventArgs e = new PaintEventArgs(c, r); 84 this.onPaint(e); 85 } 86 } 87 break; 88 89 case WM_CREATE: 90 this.originalWndProc(m); 91 super.wndProc(m); 92 break; 93 94 default: 95 super.wndProc(m); 96 break; 97 } 98 } 99 }