store ids of sub-items directly in wxSubwindows instead of using a parallel data...
[wxWidgets.git] / include / wx / msw / subwin.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/msw/subwin.h
3 // Purpose: helper for implementing the controls with subwindows
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 2004-12-11
7 // RCS-ID: $Id$
8 // Copyright: (c) 2004 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_MSW_SUBWIN_H_
13 #define _WX_MSW_SUBWIN_H_
14
15 #include "wx/msw/private.h"
16
17 // ----------------------------------------------------------------------------
18 // wxSubwindows contains all HWNDs making part of a single wx control
19 // ----------------------------------------------------------------------------
20
21 class WXDLLEXPORT wxSubwindows
22 {
23 public:
24 // the number of subwindows can be specified either as parameter to ctor or
25 // later in Create()
26 wxSubwindows(size_t n = 0) { Init(); if ( n ) Create(n); }
27
28 // allocate enough space for the given number of windows
29 void Create(size_t n)
30 {
31 wxASSERT_MSG( !m_hwnds, _T("Create() called twice?") );
32
33 m_count = n;
34 m_hwnds = (HWND *)calloc(n, sizeof(HWND));
35 m_ids = new wxWindowIDRef[n];
36 }
37
38 // non-virtual dtor, this class is not supposed to be used polymorphically
39 ~wxSubwindows()
40 {
41 for ( size_t n = 0; n < m_count; n++ )
42 {
43 ::DestroyWindow(m_hwnds[n]);
44 }
45
46 free(m_hwnds);
47 delete [] m_ids;
48 }
49
50 // get the number of subwindows
51 size_t GetCount() const { return m_count; }
52
53 // access a given window
54 HWND& Get(size_t n)
55 {
56 wxASSERT_MSG( n < m_count, _T("subwindow index out of range") );
57
58 return m_hwnds[n];
59 }
60
61 HWND operator[](size_t n) const
62 {
63 return wx_const_cast(wxSubwindows *, this)->Get(n);
64 }
65
66 // initialize the given window: id will be stored in wxWindowIDRef ensuring
67 // that it is not reused while this object exists
68 void Set(size_t n, HWND hwnd, wxWindowID id)
69 {
70 wxASSERT_MSG( n < m_count, _T("subwindow index out of range") );
71
72 m_hwnds[n] = hwnd;
73 m_ids[n] = id;
74 }
75
76 // check if we have this window
77 bool HasWindow(HWND hwnd)
78 {
79 for ( size_t n = 0; n < m_count; n++ )
80 {
81 if ( m_hwnds[n] == hwnd )
82 return true;
83 }
84
85 return false;
86 }
87
88
89 // methods which are forwarded to all subwindows
90 // ---------------------------------------------
91
92 // show/hide everything
93 void Show(bool show)
94 {
95 int sw = show ? SW_SHOW : SW_HIDE;
96 for ( size_t n = 0; n < m_count; n++ )
97 {
98 ::ShowWindow(m_hwnds[n], sw);
99 }
100 }
101
102 // enable/disable everything
103 void Enable(bool enable)
104 {
105 for ( size_t n = 0; n < m_count; n++ )
106 {
107 ::EnableWindow(m_hwnds[n], enable);
108 }
109 }
110
111 // set font for all windows
112 void SetFont(const wxFont& font)
113 {
114 HFONT hfont = GetHfontOf(font);
115 wxCHECK_RET( hfont, _T("invalid font") );
116
117 for ( size_t n = 0; n < m_count; n++ )
118 {
119 ::SendMessage(m_hwnds[n], WM_SETFONT, (WPARAM)hfont, 0);
120
121 // otherwise the window might not be redrawn correctly
122 ::InvalidateRect(m_hwnds[n], NULL, FALSE /* don't erase bg */);
123 }
124 }
125
126 // find the bounding box for all windows
127 wxRect GetBoundingBox() const
128 {
129 wxRect r;
130 for ( size_t n = 0; n < m_count; n++ )
131 {
132 RECT rc;
133 ::GetWindowRect(m_hwnds[n], &rc);
134
135 r.Union(wxRectFromRECT(rc));
136 }
137
138 return r;
139 }
140
141 private:
142 void Init()
143 {
144 m_count = 0;
145 m_hwnds = NULL;
146 }
147
148 // number of elements in m_hwnds array
149 size_t m_count;
150
151 // the HWNDs we contain
152 HWND *m_hwnds;
153
154 // the IDs of the windows
155 wxWindowIDRef *m_ids;
156
157
158 DECLARE_NO_COPY_CLASS(wxSubwindows)
159 };
160
161 // convenient macro to forward a few methods which are usually propagated to
162 // subwindows to a wxSubwindows object
163 //
164 // parameters should be:
165 // - cname the name of the class implementing these methods
166 // - base the name of its base class
167 // - subwins the name of the member variable of type wxSubwindows *
168 #define WX_FORWARD_STD_METHODS_TO_SUBWINDOWS(cname, base, subwins) \
169 bool cname::ContainsHWND(WXHWND hWnd) const \
170 { \
171 return subwins && subwins->HasWindow((HWND)hWnd); \
172 } \
173 \
174 bool cname::Show(bool show) \
175 { \
176 if ( !base::Show(show) ) \
177 return false; \
178 \
179 if ( subwins ) \
180 subwins->Show(show); \
181 \
182 return true; \
183 } \
184 \
185 bool cname::Enable(bool enable) \
186 { \
187 if ( !base::Enable(enable) ) \
188 return false; \
189 \
190 if ( subwins ) \
191 subwins->Enable(enable); \
192 \
193 return true; \
194 } \
195 \
196 bool cname::SetFont(const wxFont& font) \
197 { \
198 if ( !base::SetFont(font) ) \
199 return false; \
200 \
201 if ( subwins ) \
202 subwins->SetFont(font); \
203 \
204 return true; \
205 }
206
207
208 #endif // _WX_MSW_SUBWIN_H_
209