]> git.saurik.com Git - wxWidgets.git/blame - src/msw/menuitem.cpp
Correction to accelerator bug fix: add FVIRTKEY if ctrl, alt or shift
[wxWidgets.git] / src / msw / menuitem.cpp
CommitLineData
2bda0e17
KB
1///////////////////////////////////////////////////////////////////////////////
2// Name: menuitem.cpp
3// Purpose: wxMenuItem implementation
4// Author: Vadim Zeitlin
c2dcfdef 5// Modified by:
2bda0e17
KB
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
c2dcfdef
VZ
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
a3b46648 20#ifdef __GNUG__
c2dcfdef 21 #pragma implementation "menuitem.h"
a3b46648 22#endif
2bda0e17
KB
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
c2dcfdef 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
c2dcfdef
VZ
32 #include "wx/font.h"
33 #include "wx/bitmap.h"
34 #include "wx/settings.h"
35 #include "wx/font.h"
4e938f5b 36 #include "wx/window.h"
0c589ad0
BM
37 #include "wx/accel.h"
38 #include "wx/menu.h"
39 #include "wx/string.h"
2bda0e17
KB
40#endif
41
2bda0e17 42#include "wx/menuitem.h"
6776a0b2 43#include "wx/log.h"
2bda0e17 44
717a57c2
VZ
45#if wxUSE_ACCEL
46 #include "wx/accel.h"
47#endif // wxUSE_ACCEL
48
42e69d6b 49#include "wx/msw/private.h"
ce3ed50d 50
c2dcfdef 51// ---------------------------------------------------------------------------
974e8d94 52// macro
c2dcfdef
VZ
53// ---------------------------------------------------------------------------
54
974e8d94 55// hide the ugly cast
c2dcfdef
VZ
56#define GetHMenuOf(menu) ((HMENU)menu->GetHMenu())
57
974e8d94
VZ
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
2bda0e17
KB
65// ============================================================================
66// implementation
67// ============================================================================
68
69// ----------------------------------------------------------------------------
70// dynamic classes implementation
71// ----------------------------------------------------------------------------
72
6d5b2a57
VZ
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
2bda0e17
KB
78
79// ----------------------------------------------------------------------------
80// wxMenuItem
81// ----------------------------------------------------------------------------
82
83// ctor & dtor
84// -----------
85
974e8d94
VZ
86wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
87 int id,
88 const wxString& text,
89 const wxString& strHelp,
2bda0e17 90 bool bCheckable,
90002c49 91 wxMenu *pSubMenu)
47d67540 92#if wxUSE_OWNER_DRAWN
6d5b2a57 93 : wxOwnerDrawn(GetLabelFromText(text), bCheckable)
974e8d94 94#endif // owner drawn
2bda0e17 95{
223d09f6 96 wxASSERT_MSG( pParentMenu != NULL, wxT("a menu item should have a parent") );
2bda0e17 97
47d67540 98#if wxUSE_OWNER_DRAWN
2bda0e17
KB
99 // set default menu colors
100 #define SYS_COLOR(c) (wxSystemSettings::GetSystemColour(wxSYS_COLOUR_##c))
c2dcfdef 101
2bda0e17
KB
102 SetTextColour(SYS_COLOR(MENUTEXT));
103 SetBackgroundColour(SYS_COLOR(MENU));
104
6d5b2a57
VZ
105 #undef SYS_COLOR
106
2bda0e17
KB
107 // we don't want normal items be owner-drawn
108 ResetOwnerDrawn();
109
6d5b2a57
VZ
110 // tell the owner drawing code to to show the accel string as well
111 SetAccelString(text.AfterFirst(_T('\t')));
974e8d94
VZ
112#endif // wxUSE_OWNER_DRAWN
113
114 m_parentMenu = pParentMenu;
115 m_subMenu = pSubMenu;
116 m_isEnabled = TRUE;
117 m_isChecked = FALSE;
118 m_id = id;
119 m_text = text;
120 m_isCheckable = bCheckable;
121 m_help = strHelp;
2bda0e17
KB
122}
123
c2dcfdef 124wxMenuItem::~wxMenuItem()
2bda0e17
KB
125{
126}
127
128// misc
129// ----
130
c2dcfdef
VZ
131// return the id for calling Win32 API functions
132int wxMenuItem::GetRealId() const
133{
974e8d94 134 return m_subMenu ? (int)m_subMenu->GetHMenu() : GetId();
c2dcfdef
VZ
135}
136
3dfac970
VZ
137// get item state
138// --------------
139
a8cfd0cb 140bool wxMenuItem::IsChecked() const
3dfac970 141{
a8cfd0cb 142 int flag = ::GetMenuState(GetHMenuOf(m_parentMenu), GetId(), MF_BYCOMMAND);
3dfac970 143
4aee367e 144 return (flag & MF_CHECKED) != 0;
3dfac970
VZ
145}
146
3b59cdbf
VZ
147/* static */
148wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
717a57c2 149{
4a3563c5 150 return wxStripMenuCodes(text);
717a57c2
VZ
151}
152
153// accelerators
154// ------------
155
156#if wxUSE_ACCEL
157
158wxAcceleratorEntry *wxMenuItem::GetAccel() const
159{
160 return wxGetAccelFromString(GetText());
161}
162
163#endif // wxUSE_ACCEL
164
2bda0e17
KB
165// change item state
166// -----------------
167
717a57c2 168void wxMenuItem::Enable(bool enable)
2bda0e17 169{
717a57c2
VZ
170 if ( m_isEnabled == enable )
171 return;
172
173 long rc = EnableMenuItem(GetHMenuOf(m_parentMenu),
174 GetRealId(),
175 MF_BYCOMMAND |
176 (enable ? MF_ENABLED : MF_GRAYED));
c2dcfdef 177
717a57c2 178 if ( rc == -1 ) {
f6bcfd97 179 wxLogLastError(wxT("EnableMenuItem"));
c2dcfdef 180 }
717a57c2
VZ
181
182 wxMenuItemBase::Enable(enable);
2bda0e17
KB
183}
184
717a57c2 185void wxMenuItem::Check(bool check)
2bda0e17 186{
974e8d94 187 wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
c2dcfdef 188
717a57c2
VZ
189 if ( m_isChecked == check )
190 return;
c2dcfdef 191
717a57c2
VZ
192 long rc = CheckMenuItem(GetHMenuOf(m_parentMenu),
193 GetRealId(),
194 MF_BYCOMMAND |
195 (check ? MF_CHECKED : MF_UNCHECKED));
c2dcfdef 196
717a57c2 197 if ( rc == -1 ) {
f6bcfd97 198 wxLogLastError(wxT("CheckMenuItem"));
c2dcfdef 199 }
717a57c2
VZ
200
201 wxMenuItemBase::Check(check);
c2dcfdef
VZ
202}
203
974e8d94 204void wxMenuItem::SetText(const wxString& text)
c2dcfdef
VZ
205{
206 // don't do anything if label didn't change
974e8d94 207 if ( m_text == text )
c2dcfdef
VZ
208 return;
209
974e8d94
VZ
210 wxMenuItemBase::SetText(text);
211 OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
c2dcfdef 212
974e8d94 213 HMENU hMenu = GetHMenuOf(m_parentMenu);
717a57c2
VZ
214 wxCHECK_RET( hMenu, wxT("menuitem without menu") );
215
216#if wxUSE_ACCEL
217 m_parentMenu->UpdateAccel(this);
218#endif // wxUSE_ACCEL
2bda0e17 219
c2dcfdef
VZ
220 UINT id = GetRealId();
221 UINT flagsOld = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
222 if ( flagsOld == 0xFFFFFFFF )
223 {
f6bcfd97 224 wxLogLastError(wxT("GetMenuState"));
c2dcfdef
VZ
225 }
226 else
227 {
228 if ( IsSubMenu() )
229 {
230 // high byte contains the number of items in a submenu for submenus
231 flagsOld &= 0xFF;
232 flagsOld |= MF_POPUP;
233 }
234
837e5743 235 LPCTSTR data;
974e8d94 236
c2dcfdef
VZ
237#if wxUSE_OWNER_DRAWN
238 if ( IsOwnerDrawn() )
239 {
240 flagsOld |= MF_OWNERDRAW;
837e5743 241 data = (LPCTSTR)this;
c2dcfdef
VZ
242 }
243 else
244#endif //owner drawn
245 {
246 flagsOld |= MF_STRING;
f5166ed4 247 data = (wxChar*) text.c_str();
c2dcfdef
VZ
248 }
249
250 if ( ::ModifyMenu(hMenu, id,
251 MF_BYCOMMAND | flagsOld,
a17e237f 252 id, data) == (int)0xFFFFFFFF )
c2dcfdef 253 {
223d09f6 254 wxLogLastError(wxT("ModifyMenu"));
c2dcfdef
VZ
255 }
256 }
257}
2bda0e17 258
974e8d94
VZ
259void wxMenuItem::SetCheckable(bool checkable)
260{
261 wxMenuItemBase::SetCheckable(checkable);
262 OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) );
263}
264
265// ----------------------------------------------------------------------------
266// wxMenuItemBase
267// ----------------------------------------------------------------------------
268
269wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
270 int id,
271 const wxString& name,
272 const wxString& help,
273 bool isCheckable,
274 wxMenu *subMenu)
275{
276 return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
277}