]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/menuitem.cpp
1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMenuItem implementation
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
13 // headers & declarations
14 // ============================================================================
17 #pragma implementation "menuitem.h"
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
25 #include "wx/bitmap.h"
26 #include "wx/settings.h"
28 #include "wx/window.h"
31 #include "wx/string.h"
34 #include "wx/menuitem.h"
41 #include "wx/os2/private.h"
43 // ---------------------------------------------------------------------------
45 // ---------------------------------------------------------------------------
48 #define GetHMenuOf(menu) ((HMENU)menu->GetHMenu())
50 // conditional compilation
52 #define OWNER_DRAWN_ONLY( code ) if ( IsOwnerDrawn() ) code
53 #else // !wxUSE_OWNER_DRAWN
54 #define OWNER_DRAWN_ONLY( code )
55 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
57 // ----------------------------------------------------------------------------
58 // static function for translating menu labels
59 // ----------------------------------------------------------------------------
61 static wxString
TextToLabel(
62 const wxString
& rsTitle
68 if (rsTitle
.IsEmpty())
71 for (zPc
= rsTitle
.c_str(); *zPc
!= wxT('\0'); zPc
++)
75 if (*(zPc
+ 1) == wxT('&'))
85 if ( *zPc
== wxT('~'))
88 // Tildes must be doubled to prevent them from being
89 // interpreted as accelerator character prefix by PM ???
97 } // end of TextToLabel
99 // ============================================================================
101 // ============================================================================
103 // ----------------------------------------------------------------------------
104 // dynamic classes implementation
105 // ----------------------------------------------------------------------------
107 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
, wxObject
)
109 // ----------------------------------------------------------------------------
111 // ----------------------------------------------------------------------------
116 wxMenuItem::wxMenuItem(
119 , const wxString
& rsText
120 , const wxString
& rsHelp
124 : wxMenuItemBase( pParentMenu
131 #if wxUSE_OWNER_DRAWN
132 , wxOwnerDrawn( TextToLabel(rsText
)
133 ,eKind
== wxITEM_CHECK
135 #endif // owner drawn
137 wxASSERT_MSG(pParentMenu
!= NULL
, wxT("a menu item should have a parent"));
140 } // end of wxMenuItem::wxMenuItem
142 wxMenuItem::wxMenuItem(
145 , const wxString
& rsText
146 , const wxString
& rsHelp
150 : wxMenuItemBase( pParentMenu
154 ,bIsCheckable
? wxITEM_CHECK
: wxITEM_NORMAL
157 #if wxUSE_OWNER_DRAWN
158 , wxOwnerDrawn( TextToLabel(rsText
)
161 #endif // owner drawn
163 wxASSERT_MSG(pParentMenu
!= NULL
, wxT("a menu item should have a parent"));
164 memset(&m_vMenuData
, '\0', sizeof(m_vMenuData
));
165 m_vMenuData
.id
= (USHORT
)nId
;
168 } // end of wxMenuItem::wxMenuItem
170 void wxMenuItem::Init()
172 m_vRadioGroup
.m_nStart
= -1;
173 m_bIsRadioGroupStart
= FALSE
;
175 #if wxUSE_OWNER_DRAWN
177 // Set default menu colors
179 #define SYS_COLOR(c) (wxSystemSettings::GetColour(wxSYS_COLOUR_##c))
181 SetTextColour(SYS_COLOR(MENUTEXT
));
182 SetBackgroundColour(SYS_COLOR(MENU
));
185 // We don't want normal items be owner-drawn
191 // Tell the owner drawing code to to show the accel string as well
193 SetAccelString(m_text
.AfterFirst(_T('\t')));
194 #endif // wxUSE_OWNER_DRAWN
195 } // end of wxMenuItem::Init
197 wxMenuItem::~wxMenuItem()
199 } // end of wxMenuItem::~wxMenuItem
206 // Return the id for calling Win32 API functions
208 int wxMenuItem::GetRealId() const
210 return m_subMenu
? (int)m_subMenu
->GetHMenu() : GetId();
211 } // end of wxMenuItem::GetRealId
216 bool wxMenuItem::IsChecked() const
218 USHORT uFlag
= SHORT1FROMMR(::WinSendMsg( GetHMenuOf(m_parentMenu
)
220 ,MPFROM2SHORT(GetId(), TRUE
)
221 ,MPFROMSHORT(MIA_CHECKED
)
224 return (uFlag
& MIA_CHECKED
);
225 } // end of wxMenuItem::IsChecked
227 wxString
wxMenuItemBase::GetLabelFromText(
228 const wxString
& rsText
233 for (const char* zPc
= rsText
.c_str(); *zPc
; zPc
++)
235 if (*zPc
== wxT('~') || *zPc
== wxT('&'))
238 // '~' is the escape character for OS/2PM and '&' is the one for
239 // wxWindows - skip both of them
246 } // end of wxMenuItemBase::GetLabelFromText
252 void wxMenuItem::SetAsRadioGroupStart()
254 m_bIsRadioGroupStart
= TRUE
;
255 } // end of wxMenuItem::SetAsRadioGroupStart
257 void wxMenuItem::SetRadioGroupStart(
261 wxASSERT_MSG( !m_bIsRadioGroupStart
262 ,_T("should only be called for the next radio items")
265 m_vRadioGroup
.m_nStart
= nStart
;
266 } // wxMenuItem::SetRadioGroupStart
268 void wxMenuItem::SetRadioGroupEnd(
272 wxASSERT_MSG( m_bIsRadioGroupStart
273 ,_T("should only be called for the first radio item")
275 m_vRadioGroup
.m_nEnd
= nEnd
;
276 } // end of wxMenuItem::SetRadioGroupEnd
281 void wxMenuItem::Enable(
287 if (m_isEnabled
== bEnable
)
290 bOk
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
)
292 ,MPFROM2SHORT(GetRealId(), TRUE
)
293 ,MPFROM2SHORT(MIA_DISABLED
, FALSE
)
296 bOk
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
)
298 ,MPFROM2SHORT(GetRealId(), TRUE
)
299 ,MPFROM2SHORT(MIA_DISABLED
, MIA_DISABLED
)
303 wxLogLastError("EnableMenuItem");
305 wxMenuItemBase::Enable(bEnable
);
306 } // end of wxMenuItem::Enable
308 void wxMenuItem::Check(
314 wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
315 if (m_isChecked
== bCheck
)
318 HMENU hMenu
= GetHmenuOf(m_parentMenu
);
320 if (GetKind() == wxITEM_RADIO
)
323 // It doesn't make sense to uncheck a radio item - what would this do?
329 // Get the index of this item in the menu
331 const wxMenuItemList
& rItems
= m_parentMenu
->GetMenuItems();
332 int nPos
= rItems
.IndexOf(this);
334 wxCHECK_RET( nPos
!= wxNOT_FOUND
335 ,_T("menuitem not found in the menu items list?")
339 // Get the radio group range
344 if (m_bIsRadioGroupStart
)
347 // We already have all information we need
350 nEnd
= m_vRadioGroup
.m_nEnd
;
352 else // next radio group item
355 // Get the radio group end from the start item
357 nStart
= m_vRadioGroup
.m_nStart
;
358 nEnd
= rItems
.Item(nStart
)->GetData()->m_vRadioGroup
.m_nEnd
;
362 // Also uncheck all the other items in this radio group
364 wxMenuItemList::Node
* pNode
= rItems
.Item(nStart
);
366 for (int n
= nStart
; n
<= nEnd
&& pNode
; n
++)
372 ,MPFROM2SHORT(n
, TRUE
)
373 ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
)
378 pNode
->GetData()->m_isChecked
= FALSE
;
381 ,MPFROM2SHORT(n
, TRUE
)
382 ,MPFROM2SHORT(MIA_CHECKED
, FALSE
)
385 pNode
= pNode
->GetNext();
391 bOk
= (bool)::WinSendMsg( hMenu
393 ,MPFROM2SHORT(GetRealId(), TRUE
)
394 ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
)
397 bOk
= (bool)::WinSendMsg( hMenu
399 ,MPFROM2SHORT(GetRealId(), TRUE
)
400 ,MPFROM2SHORT(MIA_CHECKED
, FALSE
)
405 wxLogLastError("CheckMenuItem");
407 wxMenuItemBase::Check(bCheck
);
408 } // end of wxMenuItem::Check
410 void wxMenuItem::SetText(
411 const wxString
& rText
415 // Don't do anything if label didn't change
418 wxString sText
= TextToLabel(rText
);
422 wxMenuItemBase::SetText(sText
);
423 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetName(sText
));
425 HWND hMenu
= GetHmenuOf(m_parentMenu
);
427 wxCHECK_RET(hMenu
, wxT("menuitem without menu"));
430 m_parentMenu
->UpdateAccel(this);
431 #endif // wxUSE_ACCEL
433 USHORT uId
= GetRealId();
437 if (!::WinSendMsg( hMenu
439 ,MPFROM2SHORT(uId
, TRUE
)
443 wxLogLastError("GetMenuState");
447 uFlagsOld
= vItem
.afStyle
;
450 uFlagsOld
|= MIS_SUBMENU
;
455 #if wxUSE_OWNER_DRAWN
458 uFlagsOld
|= MIS_OWNERDRAW
;
464 uFlagsOld
|= MIS_TEXT
;
465 pData
= (BYTE
*)sText
.c_str();
471 if (!::WinSendMsg( hMenu
473 ,MPFROM2SHORT(uId
, TRUE
)
477 wxLogLastError(wxT("ModifyMenu"));
483 if (::WinSendMsg( hMenu
489 wxLogLastError(wxT("ModifyMenu"));
492 } // end of wxMenuItem::SetText
494 void wxMenuItem::SetCheckable(
498 wxMenuItemBase::SetCheckable(bCheckable
);
499 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetCheckable(bCheckable
));
500 } // end of wxMenuItem::SetCheckable
502 // ----------------------------------------------------------------------------
504 // ----------------------------------------------------------------------------
506 wxMenuItem
* wxMenuItemBase::New(
509 , const wxString
& rName
510 , const wxString
& rHelp
515 return new wxMenuItem( pParentMenu
522 } // end of wxMenuItemBase::New