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