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