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