]>
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"));
138 memset(&m_vMenuData
, '\0', sizeof(m_vMenuData
));
139 m_vMenuData
.id
= (USHORT
)nId
;
142 } // end of wxMenuItem::wxMenuItem
144 wxMenuItem::wxMenuItem(
147 , const wxString
& rsText
148 , const wxString
& rsHelp
152 : wxMenuItemBase( pParentMenu
156 ,bIsCheckable
? wxITEM_CHECK
: wxITEM_NORMAL
159 #if wxUSE_OWNER_DRAWN
160 , wxOwnerDrawn( TextToLabel(rsText
)
163 #endif // owner drawn
165 wxASSERT_MSG(pParentMenu
!= NULL
, wxT("a menu item should have a parent"));
166 memset(&m_vMenuData
, '\0', sizeof(m_vMenuData
));
167 m_vMenuData
.id
= (USHORT
)nId
;
170 } // end of wxMenuItem::wxMenuItem
172 void wxMenuItem::Init()
174 m_vRadioGroup
.m_nStart
= -1;
175 m_bIsRadioGroupStart
= FALSE
;
177 #if wxUSE_OWNER_DRAWN
179 // Set default menu colors
181 #define SYS_COLOR(c) (wxSystemSettings::GetColour(wxSYS_COLOUR_##c))
183 SetTextColour(SYS_COLOR(MENUTEXT
));
184 SetBackgroundColour(SYS_COLOR(MENU
));
187 // We don't want normal items be owner-drawn
193 // Tell the owner drawing code to to show the accel string as well
195 SetAccelString(m_text
.AfterFirst(_T('\t')));
196 #endif // wxUSE_OWNER_DRAWN
197 } // end of wxMenuItem::Init
199 wxMenuItem::~wxMenuItem()
201 } // end of wxMenuItem::~wxMenuItem
208 // Return the id for calling Win32 API functions
210 int wxMenuItem::GetRealId() const
212 return m_subMenu
? (int)m_subMenu
->GetHMenu() : GetId();
213 } // end of wxMenuItem::GetRealId
218 bool wxMenuItem::IsChecked() const
220 USHORT uFlag
= SHORT1FROMMR(::WinSendMsg( GetHMenuOf(m_parentMenu
)
222 ,MPFROM2SHORT(GetId(), TRUE
)
223 ,MPFROMSHORT(MIA_CHECKED
)
226 return (uFlag
& MIA_CHECKED
);
227 } // end of wxMenuItem::IsChecked
229 wxString
wxMenuItemBase::GetLabelFromText(
230 const wxString
& rsText
235 for (const char* zPc
= rsText
.c_str(); *zPc
; zPc
++)
237 if (*zPc
== wxT('~') || *zPc
== wxT('&'))
240 // '~' is the escape character for OS/2PM and '&' is the one for
241 // wxWindows - skip both of them
248 } // end of wxMenuItemBase::GetLabelFromText
254 void wxMenuItem::SetAsRadioGroupStart()
256 m_bIsRadioGroupStart
= TRUE
;
257 } // end of wxMenuItem::SetAsRadioGroupStart
259 void wxMenuItem::SetRadioGroupStart(
263 wxASSERT_MSG( !m_bIsRadioGroupStart
264 ,_T("should only be called for the next radio items")
267 m_vRadioGroup
.m_nStart
= nStart
;
268 } // wxMenuItem::SetRadioGroupStart
270 void wxMenuItem::SetRadioGroupEnd(
274 wxASSERT_MSG( m_bIsRadioGroupStart
275 ,_T("should only be called for the first radio item")
277 m_vRadioGroup
.m_nEnd
= nEnd
;
278 } // end of wxMenuItem::SetRadioGroupEnd
283 void wxMenuItem::Enable(
289 if (m_isEnabled
== bEnable
)
292 bOk
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
)
294 ,MPFROM2SHORT(GetRealId(), TRUE
)
295 ,MPFROM2SHORT(MIA_DISABLED
, FALSE
)
298 bOk
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
)
300 ,MPFROM2SHORT(GetRealId(), TRUE
)
301 ,MPFROM2SHORT(MIA_DISABLED
, MIA_DISABLED
)
305 wxLogLastError("EnableMenuItem");
307 wxMenuItemBase::Enable(bEnable
);
308 } // end of wxMenuItem::Enable
310 void wxMenuItem::Check(
316 wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
317 if (m_isChecked
== bCheck
)
320 HMENU hMenu
= GetHmenuOf(m_parentMenu
);
322 if (GetKind() == wxITEM_RADIO
)
325 // It doesn't make sense to uncheck a radio item - what would this do?
331 // Get the index of this item in the menu
333 const wxMenuItemList
& rItems
= m_parentMenu
->GetMenuItems();
334 int nPos
= rItems
.IndexOf(this);
336 wxCHECK_RET( nPos
!= wxNOT_FOUND
337 ,_T("menuitem not found in the menu items list?")
341 // Get the radio group range
346 if (m_bIsRadioGroupStart
)
349 // We already have all information we need
352 nEnd
= m_vRadioGroup
.m_nEnd
;
354 else // next radio group item
357 // Get the radio group end from the start item
359 nStart
= m_vRadioGroup
.m_nStart
;
360 nEnd
= rItems
.Item(nStart
)->GetData()->m_vRadioGroup
.m_nEnd
;
364 // Also uncheck all the other items in this radio group
366 wxMenuItemList::Node
* pNode
= rItems
.Item(nStart
);
368 for (int n
= nStart
; n
<= nEnd
&& pNode
; n
++)
374 ,MPFROM2SHORT(n
, TRUE
)
375 ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
)
380 pNode
->GetData()->m_isChecked
= FALSE
;
383 ,MPFROM2SHORT(n
, TRUE
)
384 ,MPFROM2SHORT(MIA_CHECKED
, FALSE
)
387 pNode
= pNode
->GetNext();
393 bOk
= (bool)::WinSendMsg( hMenu
395 ,MPFROM2SHORT(GetRealId(), TRUE
)
396 ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
)
399 bOk
= (bool)::WinSendMsg( hMenu
401 ,MPFROM2SHORT(GetRealId(), TRUE
)
402 ,MPFROM2SHORT(MIA_CHECKED
, FALSE
)
407 wxLogLastError("CheckMenuItem");
409 wxMenuItemBase::Check(bCheck
);
410 } // end of wxMenuItem::Check
412 void wxMenuItem::SetText(
413 const wxString
& rText
417 // Don't do anything if label didn't change
420 wxString sText
= TextToLabel(rText
);
424 wxMenuItemBase::SetText(sText
);
425 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetName(sText
));
426 #if wxUSE_OWNER_DRAWN
427 SetAccelString(rText
.AfterFirst(_T('\t')));
428 #endif // wxUSE_OWNER_DRAWN
430 HWND hMenu
= GetHmenuOf(m_parentMenu
);
432 wxCHECK_RET(hMenu
, wxT("menuitem without menu"));
435 m_parentMenu
->UpdateAccel(this);
436 #endif // wxUSE_ACCEL
438 USHORT uId
= GetRealId();
442 if (!::WinSendMsg( hMenu
444 ,MPFROM2SHORT(uId
, TRUE
)
448 wxLogLastError("GetMenuState");
452 uFlagsOld
= vItem
.afStyle
;
455 uFlagsOld
|= MIS_SUBMENU
;
460 #if wxUSE_OWNER_DRAWN
463 uFlagsOld
|= MIS_OWNERDRAW
;
469 uFlagsOld
|= MIS_TEXT
;
470 pData
= (BYTE
*)sText
.c_str();
476 if (!::WinSendMsg( hMenu
478 ,MPFROM2SHORT(uId
, TRUE
)
482 wxLogLastError(wxT("ModifyMenu"));
488 if (::WinSendMsg( hMenu
494 wxLogLastError(wxT("ModifyMenu"));
497 } // end of wxMenuItem::SetText
499 void wxMenuItem::SetCheckable(
503 wxMenuItemBase::SetCheckable(bCheckable
);
504 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetCheckable(bCheckable
));
505 } // end of wxMenuItem::SetCheckable
507 // ----------------------------------------------------------------------------
509 // ----------------------------------------------------------------------------
511 wxMenuItem
* wxMenuItemBase::New(
514 , const wxString
& rName
515 , const wxString
& rHelp
520 return new wxMenuItem( pParentMenu
527 } // end of wxMenuItemBase::New