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: subwin.h 30981 2004-12-13 01:02:32Z VZ $
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
21class WXDLLEXPORT wxSubwindows
22{
23public:
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    }
36
37    // non-virtual dtor, this class is not supposed to be used polymorphically
38    ~wxSubwindows()
39    {
40        for ( size_t n = 0; n < m_count; n++ )
41        {
42            ::DestroyWindow(m_hwnds[n]);
43        }
44
45        free(m_hwnds);
46    }
47
48    // get the number of subwindows
49    size_t GetCount() const { return m_count; }
50
51    // access a given window
52    HWND& Get(size_t n)
53    {
54        wxASSERT_MSG( n < m_count, _T("subwindow index out of range") );
55
56        return m_hwnds[n];
57    }
58
59    HWND& operator[](size_t n) { return Get(n); }
60    HWND operator[](size_t n) const
61    {
62        return wx_const_cast(wxSubwindows *, this)->Get(n);
63    }
64
65    // check if we have this window
66    bool HasWindow(HWND hwnd)
67    {
68        for ( size_t n = 0; n < m_count; n++ )
69        {
70            if ( m_hwnds[n] == hwnd )
71                return true;
72        }
73
74        return false;
75    }
76
77
78    // methods which are forwarded to all subwindows
79    // ---------------------------------------------
80
81    // show/hide everything
82    void Show(bool show)
83    {
84        int sw = show ? SW_SHOW : SW_HIDE;
85        for ( size_t n = 0; n < m_count; n++ )
86        {
87            ::ShowWindow(m_hwnds[n], sw);
88        }
89    }
90
91    // enable/disable everything
92    void Enable(bool enable)
93    {
94        for ( size_t n = 0; n < m_count; n++ )
95        {
96            ::EnableWindow(m_hwnds[n], enable);
97        }
98    }
99
100    // set font for all windows
101    void SetFont(const wxFont& font)
102    {
103        HFONT hfont = GetHfontOf(font);
104        wxCHECK_RET( hfont, _T("invalid font") );
105
106        for ( size_t n = 0; n < m_count; n++ )
107        {
108            ::SendMessage(m_hwnds[n], WM_SETFONT, (WPARAM)hfont, 0);
109
110            // otherwise the window might not be redrawn correctly
111            ::InvalidateRect(m_hwnds[n], NULL, FALSE /* don't erase bg */);
112        }
113    }
114
115    // find the bounding box for all windows
116    wxRect GetBoundingBox() const
117    {
118        wxRect r;
119        for ( size_t n = 0; n < m_count; n++ )
120        {
121            RECT rc;
122            ::GetWindowRect(m_hwnds[n], &rc);
123
124            r.Union(wxRectFromRECT(rc));
125        }
126
127        return r;
128    }
129
130private:
131    void Init()
132    {
133        m_count = 0;
134        m_hwnds = NULL;
135    }
136
137    // number of elements in m_hwnds array
138    size_t m_count;
139
140    // the HWNDs we contain
141    HWND *m_hwnds;
142
143
144    DECLARE_NO_COPY_CLASS(wxSubwindows)
145};
146
147// convenient macro to forward a few methods which are usually propagated to
148// subwindows to a wxSubwindows object
149//
150// parameters should be:
151//  - cname the name of the class implementing these methods
152//  - base the name of its base class
153//  - subwins the name of the member variable of type wxSubwindows *
154#define WX_FORWARD_STD_METHODS_TO_SUBWINDOWS(cname, base, subwins)            \
155    bool cname::ContainsHWND(WXHWND hWnd) const                               \
156    {                                                                         \
157        return subwins && subwins->HasWindow((HWND)hWnd);                     \
158    }                                                                         \
159                                                                              \
160    bool cname::Show(bool show)                                               \
161    {                                                                         \
162        if ( !base::Show(show) )                                              \
163            return false;                                                     \
164                                                                              \
165        if ( subwins )                                                        \
166            subwins->Show(show);                                              \
167                                                                              \
168        return true;                                                          \
169    }                                                                         \
170                                                                              \
171    bool cname::Enable(bool enable)                                           \
172    {                                                                         \
173        if ( !base::Enable(enable) )                                          \
174            return false;                                                     \
175                                                                              \
176        if ( subwins )                                                        \
177            subwins->Enable(enable);                                          \
178                                                                              \
179        return true;                                                          \
180    }                                                                         \
181                                                                              \
182    bool cname::SetFont(const wxFont& font)                                   \
183    {                                                                         \
184        if ( !base::SetFont(font) )                                           \
185            return false;                                                     \
186                                                                              \
187        if ( subwins )                                                        \
188            subwins->SetFont(font);                                           \
189                                                                              \
190        return true;                                                          \
191    }
192
193
194#endif // _WX_MSW_SUBWIN_H_
195
196