1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/menuitem.cpp
3 // Purpose: wxMenuItem implementation
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
13 // headers & declarations
14 // ============================================================================
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
19 #include "wx/menuitem.h"
23 #include "wx/bitmap.h"
24 #include "wx/settings.h"
25 #include "wx/window.h"
28 #include "wx/string.h"
36 #include "wx/os2/private.h"
38 // ---------------------------------------------------------------------------
40 // ---------------------------------------------------------------------------
43 #define GetHMenuOf(menu) ((HMENU)menu->GetHMenu())
45 // conditional compilation
47 #define OWNER_DRAWN_ONLY( code ) if ( IsOwnerDrawn() ) code
48 #else // !wxUSE_OWNER_DRAWN
49 #define OWNER_DRAWN_ONLY( code )
50 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
52 // ============================================================================
54 // ============================================================================
56 // ----------------------------------------------------------------------------
57 // dynamic classes implementation
58 // ----------------------------------------------------------------------------
60 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
, wxObject
)
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
69 wxMenuItem::wxMenuItem(
72 , const wxString
& rsText
73 , const wxString
& rsHelp
77 : wxMenuItemBase( pParentMenu
79 ,wxPMTextToLabel(rsText
)
85 , wxOwnerDrawn( wxPMTextToLabel(rsText
)
86 ,eKind
== wxITEM_CHECK
90 wxASSERT_MSG(pParentMenu
!= NULL
, wxT("a menu item should have a parent"));
91 memset(&m_vMenuData
, '\0', sizeof(m_vMenuData
));
92 m_vMenuData
.id
= (USHORT
)nId
;
95 } // end of wxMenuItem::wxMenuItem
97 wxMenuItem::wxMenuItem(
100 , const wxString
& rsText
101 , const wxString
& rsHelp
105 : wxMenuItemBase( pParentMenu
107 ,wxPMTextToLabel(rsText
)
109 ,bIsCheckable
? wxITEM_CHECK
: wxITEM_NORMAL
112 #if wxUSE_OWNER_DRAWN
113 , wxOwnerDrawn( wxPMTextToLabel(rsText
)
116 #endif // owner drawn
118 wxASSERT_MSG(pParentMenu
!= NULL
, wxT("a menu item should have a parent"));
119 memset(&m_vMenuData
, '\0', sizeof(m_vMenuData
));
120 m_vMenuData
.id
= (USHORT
)nId
;
123 } // end of wxMenuItem::wxMenuItem
125 void wxMenuItem::Init()
127 m_vRadioGroup
.m_nStart
= -1;
128 m_bIsRadioGroupStart
= FALSE
;
130 #if wxUSE_OWNER_DRAWN
132 // Set default menu colors
134 #define SYS_COLOR(c) (wxSystemSettings::GetColour(wxSYS_COLOUR_##c))
136 SetTextColour(SYS_COLOR(MENUTEXT
));
137 SetBackgroundColour(SYS_COLOR(MENU
));
140 // We don't want normal items be owner-drawn
146 // Tell the owner drawing code to to show the accel string as well
148 SetAccelString(m_text
.AfterFirst(_T('\t')));
149 #endif // wxUSE_OWNER_DRAWN
150 } // end of wxMenuItem::Init
152 wxMenuItem::~wxMenuItem()
154 } // end of wxMenuItem::~wxMenuItem
161 // Return the id for calling Win32 API functions
163 int wxMenuItem::GetRealId() const
165 return m_subMenu
? (int)m_subMenu
->GetHMenu() : GetId();
166 } // end of wxMenuItem::GetRealId
171 bool wxMenuItem::IsChecked() const
173 USHORT uFlag
= SHORT1FROMMR(::WinSendMsg( GetHMenuOf(m_parentMenu
)
175 ,MPFROM2SHORT(GetId(), TRUE
)
176 ,MPFROMSHORT(MIA_CHECKED
)
179 return (uFlag
& MIA_CHECKED
) == MIA_CHECKED
;
180 } // end of wxMenuItem::IsChecked
182 wxString
wxMenuItemBase::GetLabelFromText(
183 const wxString
& rsText
188 for (const wxChar
* zPc
= rsText
.c_str(); *zPc
; zPc
++)
190 if (*zPc
== wxT('~') || *zPc
== wxT('&'))
193 // '~' is the escape character for OS/2PM and '&' is the one for
194 // wxWidgets - skip both of them
201 } // end of wxMenuItemBase::GetLabelFromText
207 void wxMenuItem::SetAsRadioGroupStart()
209 m_bIsRadioGroupStart
= true;
210 } // end of wxMenuItem::SetAsRadioGroupStart
212 void wxMenuItem::SetRadioGroupStart(
216 wxASSERT_MSG( !m_bIsRadioGroupStart
217 ,_T("should only be called for the next radio items")
220 m_vRadioGroup
.m_nStart
= nStart
;
221 } // wxMenuItem::SetRadioGroupStart
223 void wxMenuItem::SetRadioGroupEnd(
227 wxASSERT_MSG( m_bIsRadioGroupStart
228 ,_T("should only be called for the first radio item")
230 m_vRadioGroup
.m_nEnd
= nEnd
;
231 } // end of wxMenuItem::SetRadioGroupEnd
236 void wxMenuItem::Enable(
242 if (m_isEnabled
== bEnable
)
245 bOk
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
)
247 ,MPFROM2SHORT(GetRealId(), TRUE
)
248 ,MPFROM2SHORT(MIA_DISABLED
, FALSE
)
251 bOk
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
)
253 ,MPFROM2SHORT(GetRealId(), TRUE
)
254 ,MPFROM2SHORT(MIA_DISABLED
, MIA_DISABLED
)
258 wxLogLastError(wxT("EnableMenuItem"));
260 wxMenuItemBase::Enable(bEnable
);
261 } // end of wxMenuItem::Enable
263 void wxMenuItem::Check(
269 wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
270 if (m_isChecked
== bCheck
)
273 HMENU hMenu
= GetHmenuOf(m_parentMenu
);
275 if (GetKind() == wxITEM_RADIO
)
278 // It doesn't make sense to uncheck a radio item - what would this do?
284 // Get the index of this item in the menu
286 const wxMenuItemList
& rItems
= m_parentMenu
->GetMenuItems();
287 int nPos
= rItems
.IndexOf(this);
289 wxCHECK_RET( nPos
!= wxNOT_FOUND
290 ,_T("menuitem not found in the menu items list?")
294 // Get the radio group range
299 if (m_bIsRadioGroupStart
)
302 // We already have all information we need
305 nEnd
= m_vRadioGroup
.m_nEnd
;
307 else // next radio group item
310 // Get the radio group end from the start item
312 nStart
= m_vRadioGroup
.m_nStart
;
313 nEnd
= rItems
.Item(nStart
)->GetData()->m_vRadioGroup
.m_nEnd
;
317 // Also uncheck all the other items in this radio group
319 wxMenuItemList::compatibility_iterator node
= rItems
.Item(nStart
);
321 for (int n
= nStart
; n
<= nEnd
&& node
; n
++)
327 ,MPFROM2SHORT(n
, TRUE
)
328 ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
)
333 node
->GetData()->m_isChecked
= FALSE
;
336 ,MPFROM2SHORT(n
, TRUE
)
337 ,MPFROM2SHORT(MIA_CHECKED
, FALSE
)
340 node
= node
->GetNext();
346 bOk
= (bool)::WinSendMsg( hMenu
348 ,MPFROM2SHORT(GetRealId(), TRUE
)
349 ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
)
352 bOk
= (bool)::WinSendMsg( hMenu
354 ,MPFROM2SHORT(GetRealId(), TRUE
)
355 ,MPFROM2SHORT(MIA_CHECKED
, FALSE
)
360 wxLogLastError(wxT("CheckMenuItem"));
362 wxMenuItemBase::Check(bCheck
);
363 } // end of wxMenuItem::Check
365 void wxMenuItem::SetText( const wxString
& rText
)
368 // Don't do anything if label didn't change
371 wxString sText
= wxPMTextToLabel(rText
);
375 wxMenuItemBase::SetText(sText
);
376 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetName(sText
));
377 #if wxUSE_OWNER_DRAWN
378 SetAccelString(rText
.AfterFirst(_T('\t')));
379 #endif // wxUSE_OWNER_DRAWN
381 HWND hMenu
= GetHmenuOf(m_parentMenu
);
383 wxCHECK_RET(hMenu
, wxT("menuitem without menu"));
386 m_parentMenu
->UpdateAccel(this);
387 #endif // wxUSE_ACCEL
389 USHORT uId
= (USHORT
)GetRealId();
393 if (!::WinSendMsg( hMenu
395 ,MPFROM2SHORT(uId
, TRUE
)
399 wxLogLastError(wxT("GetMenuState"));
403 uFlagsOld
= vItem
.afStyle
;
406 uFlagsOld
|= MIS_SUBMENU
;
411 #if wxUSE_OWNER_DRAWN
414 uFlagsOld
|= MIS_OWNERDRAW
;
420 uFlagsOld
|= MIS_TEXT
;
421 pData
= (BYTE
*)sText
.c_str();
427 if (!::WinSendMsg( hMenu
429 ,MPFROM2SHORT(uId
, TRUE
)
433 wxLogLastError(wxT("ModifyMenu"));
439 if (::WinSendMsg( hMenu
445 wxLogLastError(wxT("ModifyMenu"));
448 } // end of wxMenuItem::SetText
450 void wxMenuItem::SetCheckable(
454 wxMenuItemBase::SetCheckable(bCheckable
);
455 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetCheckable(bCheckable
));
456 } // end of wxMenuItem::SetCheckable
458 // ----------------------------------------------------------------------------
460 // ----------------------------------------------------------------------------
462 wxMenuItem
* wxMenuItemBase::New(
465 , const wxString
& rName
466 , const wxString
& rHelp
471 return new wxMenuItem( pParentMenu
478 } // end of wxMenuItemBase::New