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