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