]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/menuitem.cpp
fixes bug 414369
[wxWidgets.git] / src / msw / menuitem.cpp
... / ...
CommitLineData
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/window.h"
37 #include "wx/accel.h"
38 #include "wx/menu.h"
39 #include "wx/string.h"
40#endif
41
42#include "wx/menuitem.h"
43#include "wx/log.h"
44
45#if wxUSE_ACCEL
46 #include "wx/accel.h"
47#endif // wxUSE_ACCEL
48
49#include "wx/msw/private.h"
50
51// ---------------------------------------------------------------------------
52// macro
53// ---------------------------------------------------------------------------
54
55// hide the ugly cast
56#define GetHMenuOf(menu) ((HMENU)menu->GetHMenu())
57
58// conditional compilation
59#if wxUSE_OWNER_DRAWN
60 #define OWNER_DRAWN_ONLY( code ) if ( IsOwnerDrawn() ) code
61#else // !wxUSE_OWNER_DRAWN
62 #define OWNER_DRAWN_ONLY( code )
63#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
64
65// ============================================================================
66// implementation
67// ============================================================================
68
69// ----------------------------------------------------------------------------
70// dynamic classes implementation
71// ----------------------------------------------------------------------------
72
73 #if wxUSE_OWNER_DRAWN
74 IMPLEMENT_DYNAMIC_CLASS2(wxMenuItem, wxMenuItemBase, wxOwnerDrawn)
75 #else //!USE_OWNER_DRAWN
76 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxMenuItemBase)
77 #endif //USE_OWNER_DRAWN
78
79// ----------------------------------------------------------------------------
80// wxMenuItem
81// ----------------------------------------------------------------------------
82
83// ctor & dtor
84// -----------
85
86wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
87 int id,
88 const wxString& text,
89 const wxString& strHelp,
90 bool bCheckable,
91 wxMenu *pSubMenu)
92#if wxUSE_OWNER_DRAWN
93 : wxOwnerDrawn(text, bCheckable)
94#endif // owner drawn
95{
96 wxASSERT_MSG( pParentMenu != NULL, wxT("a menu item should have a parent") );
97
98#if wxUSE_OWNER_DRAWN
99 // set default menu colors
100 #define SYS_COLOR(c) (wxSystemSettings::GetSystemColour(wxSYS_COLOUR_##c))
101
102 SetTextColour(SYS_COLOR(MENUTEXT));
103 SetBackgroundColour(SYS_COLOR(MENU));
104
105 // we don't want normal items be owner-drawn
106 ResetOwnerDrawn();
107
108 #undef SYS_COLOR
109#endif // wxUSE_OWNER_DRAWN
110
111 m_parentMenu = pParentMenu;
112 m_subMenu = pSubMenu;
113 m_isEnabled = TRUE;
114 m_isChecked = FALSE;
115 m_id = id;
116 m_text = text;
117 m_isCheckable = bCheckable;
118 m_help = strHelp;
119}
120
121wxMenuItem::~wxMenuItem()
122{
123}
124
125// misc
126// ----
127
128// return the id for calling Win32 API functions
129int wxMenuItem::GetRealId() const
130{
131 return m_subMenu ? (int)m_subMenu->GetHMenu() : GetId();
132}
133
134// get item state
135// --------------
136
137bool wxMenuItem::IsChecked() const
138{
139 int flag = ::GetMenuState(GetHMenuOf(m_parentMenu), GetId(), MF_BYCOMMAND);
140
141 return (flag & MF_CHECKED) != 0;
142}
143
144/* static */
145wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
146{
147 return wxStripMenuCodes(text);
148}
149
150// accelerators
151// ------------
152
153#if wxUSE_ACCEL
154
155wxAcceleratorEntry *wxMenuItem::GetAccel() const
156{
157 return wxGetAccelFromString(GetText());
158}
159
160#endif // wxUSE_ACCEL
161
162// change item state
163// -----------------
164
165void wxMenuItem::Enable(bool enable)
166{
167 if ( m_isEnabled == enable )
168 return;
169
170 long rc = EnableMenuItem(GetHMenuOf(m_parentMenu),
171 GetRealId(),
172 MF_BYCOMMAND |
173 (enable ? MF_ENABLED : MF_GRAYED));
174
175 if ( rc == -1 ) {
176 wxLogLastError(wxT("EnableMenuItem"));
177 }
178
179 wxMenuItemBase::Enable(enable);
180}
181
182void wxMenuItem::Check(bool check)
183{
184 wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
185
186 if ( m_isChecked == check )
187 return;
188
189 long rc = CheckMenuItem(GetHMenuOf(m_parentMenu),
190 GetRealId(),
191 MF_BYCOMMAND |
192 (check ? MF_CHECKED : MF_UNCHECKED));
193
194 if ( rc == -1 ) {
195 wxLogLastError(wxT("CheckMenuItem"));
196 }
197
198 wxMenuItemBase::Check(check);
199}
200
201void wxMenuItem::SetText(const wxString& text)
202{
203 // don't do anything if label didn't change
204 if ( m_text == text )
205 return;
206
207 wxMenuItemBase::SetText(text);
208 OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
209
210 HMENU hMenu = GetHMenuOf(m_parentMenu);
211 wxCHECK_RET( hMenu, wxT("menuitem without menu") );
212
213#if wxUSE_ACCEL
214 m_parentMenu->UpdateAccel(this);
215#endif // wxUSE_ACCEL
216
217 UINT id = GetRealId();
218 UINT flagsOld = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
219 if ( flagsOld == 0xFFFFFFFF )
220 {
221 wxLogLastError(wxT("GetMenuState"));
222 }
223 else
224 {
225 if ( IsSubMenu() )
226 {
227 // high byte contains the number of items in a submenu for submenus
228 flagsOld &= 0xFF;
229 flagsOld |= MF_POPUP;
230 }
231
232 LPCTSTR data;
233
234#if wxUSE_OWNER_DRAWN
235 if ( IsOwnerDrawn() )
236 {
237 flagsOld |= MF_OWNERDRAW;
238 data = (LPCTSTR)this;
239 }
240 else
241#endif //owner drawn
242 {
243 flagsOld |= MF_STRING;
244 data = (wxChar*) text.c_str();
245 }
246
247 if ( ::ModifyMenu(hMenu, id,
248 MF_BYCOMMAND | flagsOld,
249 id, data) == (int)0xFFFFFFFF )
250 {
251 wxLogLastError(wxT("ModifyMenu"));
252 }
253 }
254}
255
256void wxMenuItem::SetCheckable(bool checkable)
257{
258 wxMenuItemBase::SetCheckable(checkable);
259 OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) );
260}
261
262// ----------------------------------------------------------------------------
263// wxMenuItemBase
264// ----------------------------------------------------------------------------
265
266wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
267 int id,
268 const wxString& name,
269 const wxString& help,
270 bool isCheckable,
271 wxMenu *subMenu)
272{
273 return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
274}