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