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.tooltip; 10 11 import dguihub.core.controls.subclassedcontrol; 12 13 enum ToolTipIcons { 14 none = TTI_NONE, 15 info = TTI_INFO, 16 warning = TTI_WARNING, 17 error = TTI_ERROR, 18 } 19 20 class ToolTip : SubclassedControl { 21 private ToolTipIcons _ttIcon = ToolTipIcons.none; 22 private bool _creating = false; 23 private Control _ctrl; 24 private string _title; 25 26 public override void dispose() { 27 if (this._ctrl) { 28 this.removeTool(); 29 } 30 31 super.dispose(); 32 } 33 34 private void addTool(Control c) { 35 this._ctrl = c; 36 37 TOOLINFOW ti; 38 39 ti.cbSize = TOOLINFOW.sizeof; 40 ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND; 41 ti.lpszText = cast(wchar*)LPSTR_TEXTCALLBACKW; 42 ti.hwnd = c.parent ? c.parent.handle : c.handle; 43 ti.uId = cast(uint)c.handle; 44 45 this.sendMessage(TTM_ADDTOOLW, 0, cast(LPARAM)&ti); 46 } 47 48 private void removeTool() { 49 TOOLINFOW ti; 50 51 ti.cbSize = TOOLINFOW.sizeof; 52 ti.hwnd = this._ctrl.parent ? this._ctrl.parent.handle : this._ctrl.handle; 53 ti.uId = cast(uint)this._ctrl.handle; 54 55 this.sendMessage(TTM_DELTOOLW, 0, cast(LPARAM)&ti); 56 this._ctrl = null; 57 } 58 59 @property public void icon(ToolTipIcons tti) { 60 this._ttIcon = tti; 61 62 if (this.created) { 63 this.sendMessage(TTM_SETTITLEW, this._ttIcon, cast(LPARAM)toUTFz!(wchar*)(this._title)); 64 } 65 } 66 67 @property public string title() { 68 return this._title; 69 } 70 71 @property public void title(string s) { 72 this._title = s; 73 74 if (this.created) { 75 this.sendMessage(TTM_SETTITLEW, this._ttIcon, cast(LPARAM)toUTFz!(wchar*)(this._title)); 76 } 77 } 78 79 @property public void baloonTip(bool b) { 80 this.setStyle(TTS_BALLOON, b); 81 } 82 83 @property public void closeButton(bool b) { 84 this.setStyle(TTS_CLOSE, b); 85 } 86 87 @property public void alwaysTip(bool b) { 88 this.setStyle(TTS_ALWAYSTIP, b); 89 } 90 91 @property public override void parent(Control c) { 92 if (this._creating) { 93 super.parent = c; 94 } else { 95 throwException!(DGuiException)("A ToolTip cannot have a parent"); 96 } 97 } 98 99 public final void activate(Control c) { 100 if (!this.created) { 101 this._creating = true; 102 this.parent = c.parent ? c.parent : c; 103 this.show(); 104 this._creating = false; 105 } 106 107 if (this._ctrl !is c) { 108 if (this._ctrl) { 109 this.removeTool(); 110 } 111 112 this.addTool(c); 113 } 114 115 this.sendMessage(TTM_ACTIVATE, true, 0); 116 } 117 118 public override void show() { 119 if (this._creating) { 120 super.show(); 121 } else { 122 throwException!(DGuiException)("Cannot create a ToolTip directly"); 123 } 124 } 125 126 protected override void createControlParams(ref CreateControlParams ccp) { 127 ccp.superclassName = WC_TOOLTIP; 128 ccp.className = WC_DTOOLTIP; 129 ccp.defaultBackColor = SystemColors.colorInfo; 130 ccp.defaultForeColor = SystemColors.colorInfoText; 131 132 this.setStyle(WS_POPUP | TTS_NOPREFIX, true); 133 this.setExStyle(WS_EX_TOPMOST | WS_EX_TOOLWINDOW, true); 134 135 /* According To MSDN: 136 The window procedure for the tooltip control automatically sets the size, position, and visibility of the control. 137 The height of the tooltip window is based on the height of the font currently selected into the device context 138 for the tooltip control. 139 The width varies based on the length of the string currently in the tooltip window. */ 140 this.bounds = Rect(CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT); 141 142 ToolTip.setBit(this._cBits, ControlBits.cannotAddChild | ControlBits.useCachedText, true); 143 super.createControlParams(ccp); 144 } 145 146 protected override void onReflectedMessage(ref Message m) { 147 if (m.msg == WM_NOTIFY) { 148 NMHDR* pNotify = cast(NMHDR*)m.lParam; 149 150 if (pNotify.code == TTN_GETDISPINFOW) { 151 NMTTDISPINFOW* pDispInfo = cast(NMTTDISPINFOW*)pNotify; 152 pDispInfo.lpszText = toUTFz!(wchar*)(this.text); 153 } 154 } 155 156 super.onReflectedMessage(m); 157 } 158 159 protected override void onHandleCreated(EventArgs e) { 160 if (this._ttIcon !is ToolTipIcons.none || this._title.length) { 161 this.sendMessage(TTM_SETTITLEW, this._ttIcon, cast(LPARAM)toUTFz!(wchar*)(this._title)); 162 } 163 164 SetWindowPos(this._handle, cast(HWND)HWND_TOPMOST, 0, 0, 0, 0, 165 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 166 super.onHandleCreated(e); 167 } 168 }