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