1. wxPaintDC reuse now seems to actually work instead of leading to mysterious
[wxWidgets.git] / src / msw / menuitem.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: menuitem.cpp
3 // Purpose: wxMenuItem implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 11.11.97
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "menuitem.h"
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 "wx/font.h"
33 #include "wx/bitmap.h"
34 #include "wx/settings.h"
35 #include "wx/font.h"
36 #include "wx/accel.h"
37 #include "wx/menu.h"
38 #include "wx/string.h"
39 #include "wx/window.h"
40 #endif
41
42 #include "wx/ownerdrw.h"
43 #include "wx/menuitem.h"
44 #include "wx/log.h"
45
46 #include "wx/msw/private.h"
47
48 // ---------------------------------------------------------------------------
49 // convenience macro
50 // ---------------------------------------------------------------------------
51
52 #define GetHMenuOf(menu) ((HMENU)menu->GetHMenu())
53
54 // ============================================================================
55 // implementation
56 // ============================================================================
57
58 // ----------------------------------------------------------------------------
59 // dynamic classes implementation
60 // ----------------------------------------------------------------------------
61
62 #if !defined(USE_SHARED_LIBRARY) || !USE_SHARED_LIBRARY
63 #if wxUSE_OWNER_DRAWN
64 IMPLEMENT_DYNAMIC_CLASS2(wxMenuItem, wxObject, wxOwnerDrawn)
65 #else //!USE_OWNER_DRAWN
66 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
67 #endif //USE_OWNER_DRAWN
68
69 #endif //USE_SHARED_LIBRARY
70
71 // ----------------------------------------------------------------------------
72 // wxMenuItem
73 // ----------------------------------------------------------------------------
74
75 // ctor & dtor
76 // -----------
77
78 wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
79 const wxString& strName, const wxString& strHelp,
80 bool bCheckable,
81 wxMenu *pSubMenu) :
82 #if wxUSE_OWNER_DRAWN
83 wxOwnerDrawn(strName, bCheckable),
84 #else //no owner drawn support
85 m_bCheckable(bCheckable),
86 m_strName(strName),
87 #endif //owner drawn
88 m_strHelp(strHelp)
89 {
90 wxASSERT_MSG( pParentMenu != NULL, "a menu item should have a parent" );
91
92 #if wxUSE_OWNER_DRAWN
93 // set default menu colors
94 #define SYS_COLOR(c) (wxSystemSettings::GetSystemColour(wxSYS_COLOUR_##c))
95
96 SetTextColour(SYS_COLOR(MENUTEXT));
97 SetBackgroundColour(SYS_COLOR(MENU));
98
99 // we don't want normal items be owner-drawn
100 ResetOwnerDrawn();
101
102 #undef SYS_COLOR
103 #endif
104
105 m_pParentMenu = pParentMenu;
106 m_pSubMenu = pSubMenu;
107 m_bEnabled = TRUE;
108 m_bChecked = FALSE;
109 m_idItem = id;
110 }
111
112 wxMenuItem::~wxMenuItem()
113 {
114 }
115
116 // misc
117 // ----
118
119 // return the id for calling Win32 API functions
120 int wxMenuItem::GetRealId() const
121 {
122 return m_pSubMenu ? (int)m_pSubMenu->GetHMenu() : GetId();
123 }
124
125 // delete the sub menu
126 // -------------------
127 void wxMenuItem::DeleteSubMenu()
128 {
129 delete m_pSubMenu;
130 m_pSubMenu = NULL;
131 }
132
133 // change item state
134 // -----------------
135
136 void wxMenuItem::Enable(bool bDoEnable)
137 {
138 if ( m_bEnabled != bDoEnable ) {
139 long rc = EnableMenuItem(GetHMenuOf(m_pParentMenu),
140 GetRealId(),
141 MF_BYCOMMAND |
142 (bDoEnable ? MF_ENABLED : MF_GRAYED));
143
144 if ( rc == -1 ) {
145 wxLogLastError("EnableMenuItem");
146 }
147
148 m_bEnabled = bDoEnable;
149 }
150 }
151
152 void wxMenuItem::Check(bool bDoCheck)
153 {
154 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
155
156 if ( m_bChecked != bDoCheck ) {
157 long rc = CheckMenuItem(GetHMenuOf(m_pParentMenu),
158 GetId(),
159 MF_BYCOMMAND |
160 (bDoCheck ? MF_CHECKED : MF_UNCHECKED));
161
162 if ( rc == -1 ) {
163 wxLogLastError("CheckMenuItem");
164 }
165
166 m_bChecked = bDoCheck;
167 }
168 }
169
170 void wxMenuItem::SetName(const wxString& strName)
171 {
172 // don't do anything if label didn't change
173 if ( m_strName == strName )
174 return;
175
176 m_strName = strName;
177
178 HMENU hMenu = GetHMenuOf(m_pParentMenu);
179
180 UINT id = GetRealId();
181 UINT flagsOld = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
182 if ( flagsOld == 0xFFFFFFFF )
183 {
184 wxLogLastError("GetMenuState");
185 }
186 else
187 {
188 if ( IsSubMenu() )
189 {
190 // high byte contains the number of items in a submenu for submenus
191 flagsOld &= 0xFF;
192 flagsOld |= MF_POPUP;
193 }
194
195 LPCSTR data;
196 #if wxUSE_OWNER_DRAWN
197 if ( IsOwnerDrawn() )
198 {
199 flagsOld |= MF_OWNERDRAW;
200 data = (LPCSTR)this;
201 }
202 else
203 #endif //owner drawn
204 {
205 flagsOld |= MF_STRING;
206 data = strName;
207 }
208
209 if ( ::ModifyMenu(hMenu, id,
210 MF_BYCOMMAND | flagsOld,
211 id, data) == 0xFFFFFFFF )
212 {
213 wxLogLastError("ModifyMenu");
214 }
215 }
216 }
217