]> git.saurik.com Git - wxWidgets.git/blob - src/msw/nativdlg.cpp
Workaround for wxMac since it is unable to dismiss the edit control
[wxWidgets.git] / src / msw / nativdlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/nativdlg.cpp
3 // Purpose: Native dialog loading code (part of wxWindow)
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include <stdio.h>
29
30 #include "wx/wx.h"
31 #endif
32
33 #include "wx/spinbutt.h"
34 #include "wx/msw/private.h"
35
36 // ---------------------------------------------------------------------------
37 // global functions
38 // ---------------------------------------------------------------------------
39
40 extern LONG APIENTRY _EXPORT wxDlgProc(HWND hWnd, UINT message,
41 WPARAM wParam, LPARAM lParam);
42
43 // ===========================================================================
44 // implementation
45 // ===========================================================================
46
47 bool wxWindow::LoadNativeDialog(wxWindow* parent, wxWindowID& id)
48 {
49 m_windowId = id;
50
51 wxWindowCreationHook hook(this);
52 m_hWnd = (WXHWND)::CreateDialog((HINSTANCE)wxGetInstance(),
53 MAKEINTRESOURCE(id),
54 parent ? (HWND)parent->GetHWND() : 0,
55 (DLGPROC) wxDlgProc);
56
57 if ( !m_hWnd )
58 return false;
59
60 SubclassWin(GetHWND());
61
62 if ( parent )
63 parent->AddChild(this);
64 else
65 wxTopLevelWindows.Append(this);
66
67 // Enumerate all children
68 HWND hWndNext;
69 hWndNext = ::GetWindow((HWND) m_hWnd, GW_CHILD);
70
71 if (hWndNext)
72 CreateWindowFromHWND(this, (WXHWND) hWndNext);
73
74 while (hWndNext != (HWND) NULL)
75 {
76 hWndNext = ::GetWindow(hWndNext, GW_HWNDNEXT);
77 if (hWndNext)
78 CreateWindowFromHWND(this, (WXHWND) hWndNext);
79 }
80
81 return true;
82 }
83
84 bool wxWindow::LoadNativeDialog(wxWindow* parent, const wxString& name)
85 {
86 SetName(name);
87
88 wxWindowCreationHook hook(this);
89 m_hWnd = (WXHWND)::CreateDialog((HINSTANCE) wxGetInstance(),
90 name.c_str(),
91 parent ? (HWND)parent->GetHWND() : 0,
92 (DLGPROC)wxDlgProc);
93
94 if ( !m_hWnd )
95 return false;
96
97 SubclassWin(GetHWND());
98
99 if ( parent )
100 parent->AddChild(this);
101 else
102 wxTopLevelWindows.Append(this);
103
104 // Enumerate all children
105 HWND hWndNext;
106 hWndNext = ::GetWindow((HWND) m_hWnd, GW_CHILD);
107
108 if (hWndNext)
109 CreateWindowFromHWND(this, (WXHWND) hWndNext);
110
111 while (hWndNext != (HWND) NULL)
112 {
113 hWndNext = ::GetWindow(hWndNext, GW_HWNDNEXT);
114 if (hWndNext)
115 CreateWindowFromHWND(this, (WXHWND) hWndNext);
116 }
117
118 return true;
119 }
120
121 // ---------------------------------------------------------------------------
122 // look for child by id
123 // ---------------------------------------------------------------------------
124
125 wxWindow* wxWindow::GetWindowChild1(wxWindowID id)
126 {
127 if ( m_windowId == id )
128 return this;
129
130 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
131 while ( node )
132 {
133 wxWindow* child = node->GetData();
134 wxWindow* win = child->GetWindowChild1(id);
135 if ( win )
136 return win;
137
138 node = node->GetNext();
139 }
140
141 return NULL;
142 }
143
144 wxWindow* wxWindow::GetWindowChild(wxWindowID id)
145 {
146 wxWindow* win = GetWindowChild1(id);
147 if ( !win )
148 {
149 HWND hWnd = ::GetDlgItem((HWND) GetHWND(), id);
150
151 if (hWnd)
152 {
153 wxWindow* child = CreateWindowFromHWND(this, (WXHWND) hWnd);
154 if (child)
155 {
156 child->AddChild(this);
157 return child;
158 }
159 }
160 }
161
162 return NULL;
163 }
164
165 // ---------------------------------------------------------------------------
166 // create wxWin window from a native HWND
167 // ---------------------------------------------------------------------------
168
169 wxWindow* wxWindow::CreateWindowFromHWND(wxWindow* parent, WXHWND hWnd)
170 {
171 wxString str(wxGetWindowClass(hWnd));
172 str.UpperCase();
173
174 long id = wxGetWindowId(hWnd);
175 long style = GetWindowLong((HWND) hWnd, GWL_STYLE);
176
177 wxWindow* win = NULL;
178
179 if (str == wxT("BUTTON"))
180 {
181 int style1 = (style & 0xFF);
182 #if wxUSE_CHECKBOX
183 if ((style1 == BS_3STATE) || (style1 == BS_AUTO3STATE) || (style1 == BS_AUTOCHECKBOX) ||
184 (style1 == BS_CHECKBOX))
185 {
186 win = new wxCheckBox;
187 }
188 else
189 #endif
190 #if wxUSE_RADIOBTN
191 if ((style1 == BS_AUTORADIOBUTTON) || (style1 == BS_RADIOBUTTON))
192 {
193 win = new wxRadioButton;
194 }
195 else
196 #endif
197 #if wxUSE_BMPBUTTON
198 #if defined(__WIN32__) && defined(BS_BITMAP)
199 if (style & BS_BITMAP)
200 {
201 // TODO: how to find the bitmap?
202 win = new wxBitmapButton;
203 wxLogError(wxT("Have not yet implemented bitmap button as BS_BITMAP button."));
204 }
205 else
206 #endif
207 if (style1 == BS_OWNERDRAW)
208 {
209 // TODO: how to find the bitmap?
210 // TODO: can't distinguish between bitmap button and bitmap static.
211 // Change implementation of wxStaticBitmap to SS_BITMAP.
212 // PROBLEM: this assumes that we're using resource-based bitmaps.
213 // So maybe need 2 implementations of bitmap buttons/static controls,
214 // with a switch in the drawing code. Call default proc if BS_BITMAP.
215 win = new wxBitmapButton;
216 }
217 else
218 #endif
219 #if wxUSE_BUTTON
220 if ((style1 == BS_PUSHBUTTON) || (style1 == BS_DEFPUSHBUTTON))
221 {
222 win = new wxButton;
223 }
224 else
225 #endif
226 #if wxUSE_STATBOX
227 if (style1 == BS_GROUPBOX)
228 {
229 win = new wxStaticBox;
230 }
231 else
232 #endif
233 {
234 wxLogError(wxT("Don't know what kind of button this is: id = %ld"),
235 id);
236 }
237 }
238 #if wxUSE_COMBOBOX
239 else if (str == wxT("COMBOBOX"))
240 {
241 win = new wxComboBox;
242 }
243 #endif
244 #if wxUSE_TEXTCTRL
245 // TODO: Problem if the user creates a multiline - but not rich text - text control,
246 // since wxWin assumes RichEdit control for this. Should have m_isRichText in
247 // wxTextCtrl. Also, convert as much of the window style as is necessary
248 // for correct functioning.
249 // Could have wxWindow::AdoptAttributesFromHWND(WXHWND)
250 // to be overridden by each control class.
251 else if (str == wxT("EDIT"))
252 {
253 win = new wxTextCtrl;
254 }
255 #endif
256 #if wxUSE_LISTBOX
257 else if (str == wxT("LISTBOX"))
258 {
259 win = new wxListBox;
260 }
261 #endif
262 #if wxUSE_SCROLLBAR
263 else if (str == wxT("SCROLLBAR"))
264 {
265 win = new wxScrollBar;
266 }
267 #endif
268 #if wxUSE_SPINBTN
269 else if (str == wxT("MSCTLS_UPDOWN32"))
270 {
271 win = new wxSpinButton;
272 }
273 #endif
274 #if wxUSE_SLIDER
275 else if (str == wxT("MSCTLS_TRACKBAR32"))
276 {
277 // Need to ascertain if it's horiz or vert
278 win = new wxSlider;
279 }
280 #endif // wxUSE_SLIDER
281 #if wxUSE_STATTEXT
282 else if (str == wxT("STATIC"))
283 {
284 int style1 = (style & 0xFF);
285
286 if ((style1 == SS_LEFT) || (style1 == SS_RIGHT)
287 #ifndef __WXWINCE__
288 || (style1 == SS_SIMPLE)
289 #endif
290 )
291 win = new wxStaticText;
292 #if wxUSE_STATBMP
293 #if defined(__WIN32__) && defined(BS_BITMAP)
294 else if (style1 == SS_BITMAP)
295 {
296 win = new wxStaticBitmap;
297
298 // Help! this doesn't correspond with the wxWin implementation.
299 wxLogError(wxT("Please make SS_BITMAP statics into owner-draw buttons."));
300 }
301 #endif
302 #endif /* wxUSE_STATBMP */
303 }
304 #endif
305 else
306 {
307 wxString msg(wxT("Don't know how to convert from Windows class "));
308 msg += str;
309 wxLogError(msg);
310 }
311
312 if (win)
313 {
314 parent->AddChild(win);
315 win->SetEventHandler(win);
316 win->SetHWND(hWnd);
317 win->SetId(id);
318 win->SubclassWin(hWnd);
319 win->AdoptAttributesFromHWND();
320 win->SetupColours();
321 }
322
323 return win;
324 }
325
326 // Make sure the window style (etc.) reflects the HWND style (roughly)
327 void wxWindow::AdoptAttributesFromHWND(void)
328 {
329 HWND hWnd = (HWND) GetHWND();
330 long style = GetWindowLong((HWND) hWnd, GWL_STYLE);
331
332 if (style & WS_VSCROLL)
333 m_windowStyle |= wxVSCROLL;
334 if (style & WS_HSCROLL)
335 m_windowStyle |= wxHSCROLL;
336 }