]> git.saurik.com Git - wxWidgets.git/blob - src/msw/nativdlg.cpp
* Fix logical error in m_overflow attribute merging
[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 #ifdef __GNUG__
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__) && !defined(__TWIN32__)
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 wxWindow* child = NULL;
78 if (hWndNext)
79 child = CreateWindowFromHWND(this, (WXHWND) hWndNext);
80
81 while (hWndNext != (HWND) NULL)
82 {
83 hWndNext = ::GetWindow(hWndNext, GW_HWNDNEXT);
84 if (hWndNext)
85 child = CreateWindowFromHWND(this, (WXHWND) hWndNext);
86 }
87
88 return TRUE;
89 }
90
91 bool wxWindow::LoadNativeDialog(wxWindow* parent, const wxString& name)
92 {
93 SetName(name);
94
95 wxWindowCreationHook hook(this);
96 m_hWnd = (WXHWND)::CreateDialog((HINSTANCE) wxGetInstance(),
97 name.c_str(),
98 parent ? (HWND)parent->GetHWND() : 0,
99 (DLGPROC)wxDlgProc);
100
101 if ( !m_hWnd )
102 return FALSE;
103
104 SubclassWin(GetHWND());
105
106 if ( parent )
107 parent->AddChild(this);
108 else
109 wxTopLevelWindows.Append(this);
110
111 // FIXME why don't we enum all children here?
112
113 return TRUE;
114 }
115
116 // ---------------------------------------------------------------------------
117 // look for child by id
118 // ---------------------------------------------------------------------------
119
120 wxWindow* wxWindow::GetWindowChild1(wxWindowID id)
121 {
122 if ( m_windowId == id )
123 return this;
124
125 wxWindowList::Node *node = GetChildren().GetFirst();
126 while ( node )
127 {
128 wxWindow* child = node->GetData();
129 wxWindow* win = child->GetWindowChild1(id);
130 if ( win )
131 return win;
132
133 node = node->GetNext();
134 }
135
136 return NULL;
137 }
138
139 wxWindow* wxWindow::GetWindowChild(wxWindowID id)
140 {
141 wxWindow* win = GetWindowChild1(id);
142 if ( !win )
143 {
144 HWND hWnd = ::GetDlgItem((HWND) GetHWND(), id);
145
146 if (hWnd)
147 {
148 wxWindow* child = CreateWindowFromHWND(this, (WXHWND) hWnd);
149 if (child)
150 {
151 child->AddChild(this);
152 return child;
153 }
154 }
155 }
156
157 return NULL;
158 }
159
160 // ---------------------------------------------------------------------------
161 // create wxWin window from a native HWND
162 // ---------------------------------------------------------------------------
163
164 wxWindow* wxWindow::CreateWindowFromHWND(wxWindow* parent, WXHWND hWnd)
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 ((style1 == BS_3STATE) || (style1 == BS_AUTO3STATE) || (style1 == BS_AUTOCHECKBOX) ||
178 (style1 == BS_CHECKBOX))
179 {
180 win = new wxCheckBox;
181 }
182 else if ((style1 == BS_AUTORADIOBUTTON) || (style1 == BS_RADIOBUTTON))
183 {
184 win = new wxRadioButton;
185 }
186 #if wxUSE_BMPBUTTON
187 #if defined(__WIN32__) && defined(BS_BITMAP)
188 else if (style & BS_BITMAP)
189 {
190 // TODO: how to find the bitmap?
191 win = new wxBitmapButton;
192 wxLogError(wxT("Have not yet implemented bitmap button as BS_BITMAP button."));
193 }
194 #endif
195 else if (style1 == BS_OWNERDRAW)
196 {
197 // TODO: how to find the bitmap?
198 // TODO: can't distinguish between bitmap button and bitmap static.
199 // Change implementation of wxStaticBitmap to SS_BITMAP.
200 // PROBLEM: this assumes that we're using resource-based bitmaps.
201 // So maybe need 2 implementations of bitmap buttons/static controls,
202 // with a switch in the drawing code. Call default proc if BS_BITMAP.
203 win = new wxBitmapButton;
204 }
205 #endif
206 else if ((style1 == BS_PUSHBUTTON) || (style1 == BS_DEFPUSHBUTTON))
207 {
208 win = new wxButton;
209 }
210 else if (style1 == BS_GROUPBOX)
211 {
212 win = new wxStaticBox;
213 }
214 else
215 {
216 wxLogError(wxT("Don't know what kind of button this is: id = %ld"),
217 id);
218 }
219 }
220 else if (str == wxT("COMBOBOX"))
221 {
222 win = new wxComboBox;
223 }
224 // TODO: Problem if the user creates a multiline - but not rich text - text control,
225 // since wxWin assumes RichEdit control for this. Should have m_isRichText in
226 // wxTextCtrl. Also, convert as much of the window style as is necessary
227 // for correct functioning.
228 // Could have wxWindow::AdoptAttributesFromHWND(WXHWND)
229 // to be overridden by each control class.
230 else if (str == wxT("EDIT"))
231 {
232 win = new wxTextCtrl;
233 }
234 else if (str == wxT("LISTBOX"))
235 {
236 win = new wxListBox;
237 }
238 else if (str == wxT("SCROLLBAR"))
239 {
240 win = new wxScrollBar;
241 }
242 #if defined(__WIN95__) && !defined(__TWIN32__) && wxUSE_SPINBTN
243 else if (str == wxT("MSCTLS_UPDOWN32"))
244 {
245 win = new wxSpinButton;
246 }
247 #endif
248 #if wxUSE_SLIDER
249 else if (str == wxT("MSCTLS_TRACKBAR32"))
250 {
251 // Need to ascertain if it's horiz or vert
252 win = new wxSlider;
253 }
254 #endif // wxUSE_SLIDER
255 else if (str == wxT("STATIC"))
256 {
257 int style1 = (style & 0xFF);
258
259 if ((style1 == SS_LEFT) || (style1 == SS_RIGHT) || (style1 == SS_SIMPLE))
260 win = new wxStaticText;
261 #if wxUSE_STATBMP
262 #if defined(__WIN32__) && defined(BS_BITMAP)
263 else if (style1 == SS_BITMAP)
264 {
265 win = new wxStaticBitmap;
266
267 // Help! this doesn't correspond with the wxWin implementation.
268 wxLogError(wxT("Please make SS_BITMAP statics into owner-draw buttons."));
269 }
270 #endif
271 #endif /* wxUSE_STATBMP */
272 }
273 else
274 {
275 wxString msg(wxT("Don't know how to convert from Windows class "));
276 msg += str;
277 wxLogError(msg);
278 }
279
280 if (win)
281 {
282 parent->AddChild(win);
283 win->SetEventHandler(win);
284 win->SetHWND(hWnd);
285 win->SetId(id);
286 win->SubclassWin(hWnd);
287 win->AdoptAttributesFromHWND();
288 win->SetupColours();
289 }
290
291 return win;
292 }
293
294 // Make sure the window style (etc.) reflects the HWND style (roughly)
295 void wxWindow::AdoptAttributesFromHWND(void)
296 {
297 HWND hWnd = (HWND) GetHWND();
298 long style = GetWindowLong((HWND) hWnd, GWL_STYLE);
299
300 if (style & WS_VSCROLL)
301 m_windowStyle |= wxVSCROLL;
302 if (style & WS_HSCROLL)
303 m_windowStyle |= wxHSCROLL;
304 }
305