1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4
5 #include "win32textedit.h"
6
7 #if WINDOWS
8
9 #include "win32support.h"
10 #include "../../vstkeycode.h"
11
12 namespace VSTGUI {
13
14 //-----------------------------------------------------------------------------
CreateEditControl(DWORD wxStyle,const WCHAR * string,DWORD wstyle,const CRect & rect,HWND parent)15 HWND CreateEditControl (DWORD wxStyle, const WCHAR* string, DWORD wstyle, const CRect& rect,
16 HWND parent)
17 {
18 return CreateWindowEx (wxStyle, TEXT ("EDIT"), string, wstyle, static_cast<int> (rect.left),
19 static_cast<int> (rect.top), static_cast<int> (rect.getWidth ()),
20 static_cast<int> (rect.getHeight ()), parent, nullptr, GetInstance (),
21 nullptr);
22 }
23
24 //-----------------------------------------------------------------------------
Win32TextEdit(HWND parent,IPlatformTextEditCallback * textEdit)25 Win32TextEdit::Win32TextEdit (HWND parent, IPlatformTextEditCallback* textEdit)
26 : IPlatformTextEdit (textEdit)
27 , platformControl (0)
28 , platformFont (0)
29 , platformBackColor (0)
30 , oldWndProcEdit (0)
31 {
32 CRect rect = textEdit->platformGetSize ();
33 CFontRef fontID = textEdit->platformGetFont ();
34
35 CHoriTxtAlign horiTxtAlign = textEdit->platformGetHoriTxtAlign ();
36 int wstyle = 0;
37 if (horiTxtAlign == kLeftText)
38 wstyle |= ES_LEFT;
39 else if (horiTxtAlign == kRightText)
40 wstyle |= ES_RIGHT;
41 else
42 wstyle |= ES_CENTER;
43
44 CPoint textInset = textEdit->platformGetTextInset ();
45 rect.offset (textInset.x, textInset.y);
46 rect.right -= textInset.x*2;
47 rect.bottom -= textInset.y*2;
48
49 // get/set the current font
50 LOGFONT logfont = {0};
51
52 CCoord fontH = fontID->getSize ();
53 if (fontH > rect.getHeight ())
54 fontH = rect.getHeight () - 3;
55 if (fontH < rect.getHeight ())
56 {
57 CCoord adjust = (rect.getHeight () - (fontH + 3)) / (CCoord)2;
58 rect.top += adjust;
59 rect.bottom -= adjust;
60 }
61 UTF8StringHelper stringHelper (textEdit->platformGetText ());
62 text = stringHelper;
63
64 CColor backColor = textEdit->platformGetBackColor ();
65 DWORD wxStyle = WS_EX_LAYERED;
66 wxStyle = WS_EX_COMPOSITED;
67 wstyle |= WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
68 if (textEdit->platformIsSecureTextEdit ())
69 wstyle |= ES_PASSWORD;
70 platformControl = CreateEditControl (wxStyle, stringHelper.getWideString (), wstyle, rect, parent);
71 if (!platformControl)
72 {
73 wxStyle &= ~WS_EX_LAYERED;
74 platformControl = CreateEditControl (wxStyle, stringHelper.getWideString (), wstyle, rect, parent);
75 if (!platformControl)
76 {
77 wxStyle &= ~WS_EX_COMPOSITED;
78 platformControl = CreateEditControl (wxStyle, stringHelper.getWideString (), wstyle, rect, parent);
79 }
80 }
81 else
82 {
83 SetLayeredWindowAttributes (platformControl, RGB (backColor.red, backColor.green, backColor.blue), 0, LWA_COLORKEY);
84 }
85 platformBackColor = CreateSolidBrush (RGB (backColor.red, backColor.green, backColor.blue));
86
87 logfont.lfWeight = FW_NORMAL;
88 logfont.lfHeight = (LONG)-fontH;
89 logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
90 UTF8StringHelper fontNameHelper (fontID->getName ());
91 VSTGUI_STRCPY (logfont.lfFaceName, fontNameHelper);
92
93 logfont.lfClipPrecision = CLIP_STROKE_PRECIS;
94 logfont.lfOutPrecision = OUT_STRING_PRECIS;
95 logfont.lfQuality = DEFAULT_QUALITY;
96 logfont.lfCharSet = ANSI_CHARSET;
97
98 platformFont = CreateFontIndirect (&logfont);
99
100 SetWindowLongPtr (platformControl, GWLP_USERDATA, (__int3264)(LONG_PTR)this);
101 SendMessage (platformControl, WM_SETFONT, (WPARAM)platformFont, true);
102 SendMessage (platformControl, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG (0, 0));
103 SendMessage (platformControl, EM_SETSEL, 0, -1);
104 SendMessage (platformControl, EM_LIMITTEXT, 255, 0);
105 SetFocus (platformControl);
106
107 oldWndProcEdit = (WINDOWSPROC)(LONG_PTR)SetWindowLongPtr (platformControl, GWLP_WNDPROC, (__int3264)(LONG_PTR)procEdit);
108
109 }
110
111 //-----------------------------------------------------------------------------
~Win32TextEdit()112 Win32TextEdit::~Win32TextEdit () noexcept
113 {
114 if (platformControl)
115 {
116 SetWindowLongPtr (platformControl, GWLP_WNDPROC, (__int3264)(LONG_PTR)oldWndProcEdit);
117 DestroyWindow (platformControl);
118 }
119 if (platformFont)
120 DeleteObject (platformFont);
121 if (platformBackColor)
122 DeleteObject (platformBackColor);
123 }
124
125 //-----------------------------------------------------------------------------
getText()126 UTF8String Win32TextEdit::getText ()
127 {
128 #if 1
129 return text.c_str ();
130 #else
131 if (platformControl)
132 {
133 int textLength = GetWindowTextLength (platformControl);
134 TCHAR* newText = new TCHAR[textLength+1];
135 GetWindowText (platformControl, newText, textLength+1);
136 UTF8StringHelper windowText (newText);
137 text = windowText;
138 delete [] newText;
139 return text.c_str ();
140 }
141 return "";
142 #endif
143 }
144
145 //-----------------------------------------------------------------------------
setText(const UTF8String & _text)146 bool Win32TextEdit::setText (const UTF8String& _text)
147 {
148 if (platformControl && text != _text)
149 {
150 UTF8StringHelper windowText (_text);
151 return SetWindowText (platformControl, windowText) ? true : false;
152 }
153 return false;
154 }
155
156 //-----------------------------------------------------------------------------
updateSize()157 bool Win32TextEdit::updateSize ()
158 {
159 // TODO: Implement me !
160 return false;
161 }
162
163 //-----------------------------------------------------------------------------
textChanged()164 void Win32TextEdit::textChanged ()
165 {
166 if (platformControl)
167 {
168 int textLength = GetWindowTextLength (platformControl);
169 TCHAR* newText = new TCHAR[textLength+1];
170 GetWindowText (platformControl, newText, textLength+1);
171 UTF8StringHelper windowText (newText);
172 text = windowText;
173 delete [] newText;
174 textEdit->platformTextDidChange ();
175 }
176 }
177
178 //-----------------------------------------------------------------------------
procEdit(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)179 LONG_PTR WINAPI Win32TextEdit::procEdit (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
180 {
181 Win32TextEdit* win32TextEdit = (Win32TextEdit*)(LONG_PTR) GetWindowLongPtr (hwnd, GWLP_USERDATA);
182 if (win32TextEdit)
183 {
184 WINDOWSPROC oldProc = win32TextEdit->oldWndProcEdit;
185 switch (message)
186 {
187 case WM_GETDLGCODE :
188 {
189 LONG_PTR flags = DLGC_WANTALLKEYS;
190 return flags;
191 }
192
193 case WM_KEYDOWN:
194 {
195 if (win32TextEdit->textEdit)
196 {
197 if (auto keyCode = keyMessageToKeyCode (wParam, lParam))
198 {
199 // for now only dispatch virtual keys
200 if (keyCode->character == 0 && win32TextEdit->textEdit->platformOnKeyDown (*keyCode))
201 return 0;
202 }
203 }
204 break;
205 }
206
207 case WM_KILLFOCUS:
208 {
209 if (win32TextEdit->textEdit)
210 {
211 win32TextEdit->textEdit->platformLooseFocus (false);
212 return 0;
213 }
214 break;
215 }
216 case WM_COMMAND:
217 {
218 if (HIWORD (wParam) == EN_CHANGE && win32TextEdit->textEdit)
219 {
220 win32TextEdit->textChanged ();
221 }
222 return 0;
223 }
224 }
225 return CallWindowProc (oldProc, hwnd, message, wParam, lParam);
226 }
227 return DefWindowProc (hwnd, message, wParam, lParam);
228 }
229
230 } // namespace
231
232 #endif // WINDOWS
233