]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/menuitem.cpp
3e0f891a09bc8022a9a2739544eaf981511e2e1f
   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(const wxString
& rTitle
) 
  65     for (pc 
= rTitle
.c_str(); *pc 
!= wxT('\0'); pc
++ ) 
  69             if (*(pc
+1) == wxT('&')) 
  79             if ( *pc 
== wxT('~') ) 
  81                 // tildes must be doubled to prevent them from being 
  82                 // interpreted as accelerator character prefix by PM ??? 
  91 // ============================================================================ 
  93 // ============================================================================ 
  95 // ---------------------------------------------------------------------------- 
  96 // dynamic classes implementation 
  97 // ---------------------------------------------------------------------------- 
  99 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
, wxObject
) 
 101 // ---------------------------------------------------------------------------- 
 103 // ---------------------------------------------------------------------------- 
 108 wxMenuItem::wxMenuItem( 
 111 , const wxString
&                   rsText
 
 112 , const wxString
&                   rsHelp
 
 116 : wxMenuItemBase( pParentMenu
 
 123 #if wxUSE_OWNER_DRAWN 
 124 ,  wxOwnerDrawn( TextToLabel(rsText
) 
 125                 ,eKind 
== wxITEM_CHECK
 
 127 #endif // owner drawn 
 129     wxASSERT_MSG(pParentMenu 
!= NULL
, wxT("a menu item should have a parent")); 
 132 } // end of wxMenuItem::wxMenuItem 
 134 wxMenuItem::wxMenuItem( 
 137 , const wxString
&                   rsText
 
 138 , const wxString
&                   rsHelp
 
 142 : wxMenuItemBase( pParentMenu
 
 146                  ,bIsCheckable 
? wxITEM_CHECK 
: wxITEM_NORMAL
 
 149 #if wxUSE_OWNER_DRAWN 
 150 ,  wxOwnerDrawn( TextToLabel(rsText
) 
 153 #endif // owner drawn 
 155     wxASSERT_MSG(pParentMenu 
!= NULL
, wxT("a menu item should have a parent")); 
 158 } // end of wxMenuItem::wxMenuItem 
 160 void wxMenuItem::Init() 
 162     m_vRadioGroup
.m_nStart 
= -1; 
 163     m_bIsRadioGroupStart 
= FALSE
; 
 165 #if  wxUSE_OWNER_DRAWN 
 167     // Set default menu colors 
 169     #define SYS_COLOR(c) (wxSystemSettings::GetColour(wxSYS_COLOUR_##c)) 
 171     SetTextColour(SYS_COLOR(MENUTEXT
)); 
 172     SetBackgroundColour(SYS_COLOR(MENU
)); 
 177     // We don't want normal items be owner-drawn 
 182     // Tell the owner drawing code to to show the accel string as well 
 184     SetAccelString(m_text
.AfterFirst(_T('\t'))); 
 185 #endif // wxUSE_OWNER_DRAWN 
 186 } // end of wxMenuItem::Init 
 188 wxMenuItem::~wxMenuItem() 
 190 } // end of wxMenuItem::~wxMenuItem 
 197 // Return the id for calling Win32 API functions 
 199 int wxMenuItem::GetRealId() const 
 201     return m_subMenu 
? (int)m_subMenu
->GetHMenu() : GetId(); 
 202 } // end of wxMenuItem::GetRealId 
 207 bool wxMenuItem::IsChecked() const 
 209     USHORT                          uFlag 
= SHORT1FROMMR(::WinSendMsg( GetHMenuOf(m_parentMenu
) 
 211                                                                       ,MPFROM2SHORT(GetId(), TRUE
) 
 212                                                                       ,MPFROMSHORT(MIA_CHECKED
) 
 215     return (uFlag 
& MIA_CHECKED
); 
 216 } // end of wxMenuItem::IsChecked 
 218 wxString 
wxMenuItemBase::GetLabelFromText( 
 219   const wxString
&                   rText
 
 223     for ( const wxChar 
*pc 
= rText
.c_str(); *pc
; pc
++ ) 
 225         if ( *pc 
== wxT('~') || *pc 
== wxT('&') ) 
 227             // '~' is the escape character for GTK+ and '&' is the one for 
 228             // wxWindows - skip both of them 
 240 void wxMenuItem::SetAsRadioGroupStart() 
 242     m_bIsRadioGroupStart 
= TRUE
; 
 243 } // end of wxMenuItem::SetAsRadioGroupStart 
 245 void wxMenuItem::SetRadioGroupStart( 
 249     wxASSERT_MSG( !m_bIsRadioGroupStart
, 
 250                   _T("should only be called for the next radio items") ); 
 252     m_vRadioGroup
.m_nStart 
= nStart
; 
 253 } // end of wxMenuItem::SetRadioGroupStart 
 255 void wxMenuItem::SetRadioGroupEnd( 
 259     wxASSERT_MSG( m_bIsRadioGroupStart
, 
 260                   _T("should only be called for the first radio item") ); 
 262     m_vRadioGroup
.m_nEnd 
= nEnd
; 
 263 } // end of wxMenuItem::SetRadioGroupEnd 
 268 void wxMenuItem::Enable( 
 274     if (m_isEnabled 
== bEnable
) 
 277         bOk 
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
) 
 279                                  ,MPFROM2SHORT(GetRealId(), TRUE
) 
 280                                  ,MPFROM2SHORT(MIA_DISABLED
, FALSE
) 
 283         bOk 
= (bool)::WinSendMsg( GetHMenuOf(m_parentMenu
) 
 285                                  ,MPFROM2SHORT(GetRealId(), TRUE
) 
 286                                  ,MPFROM2SHORT(MIA_DISABLED
, MIA_DISABLED
) 
 290         wxLogLastError("EnableMenuItem"); 
 292     wxMenuItemBase::Enable(bEnable
); 
 293 } // end of wxMenuItem::Enable 
 295 void wxMenuItem::Check( 
 301     wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") ); 
 302     if (m_isChecked 
== bCheck
) 
 305     HMENU                           hMenu 
= GetHmenuOf(m_parentMenu
); 
 307     if ( GetKind() == wxITEM_RADIO 
) 
 310         // It doesn't make sense to uncheck a radio item - what would this do? 
 316         // Get the index of this item in the menu 
 318         const wxMenuItemList
&       rItems 
= m_parentMenu
->GetMenuItems(); 
 319         int                         nPos 
= rItems
.IndexOf(this); 
 323         wxCHECK_RET( nPos 
!= wxNOT_FOUND
, 
 324                      _T("menuitem not found in the menu items list?") ); 
 327         // Get the radio group range 
 330         if (m_bIsRadioGroupStart
) 
 332             // we already have all information we need 
 334             nEnd 
= m_vRadioGroup
.m_nEnd
; 
 336         else // Next radio group item 
 339             // Get the radio group end from the start item 
 341             nStart 
= m_vRadioGroup
.m_nStart
; 
 342             nEnd 
= rItems
.Item(nStart
)->GetData()->m_vRadioGroup
.m_nEnd
; 
 346         // Also uncheck all the other items in this radio group 
 348         wxMenuItemList::Node
*       pNode 
= rItems
.Item(nStart
); 
 350         for (int n 
= nStart
; n 
<= nEnd 
&& pNode
; n
++) 
 354                 pNode
->GetData()->m_isChecked 
= FALSE
; 
 359                 bOk 
= (bool)::WinSendMsg( hMenu
 
 361                                          ,MPFROM2SHORT(n
, TRUE
) 
 362                                          ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
) 
 367                 bOk 
= (bool)::WinSendMsg( hMenu
 
 369                                          ,MPFROM2SHORT(n
, TRUE
) 
 370                                          ,MPFROM2SHORT(MIA_CHECKED
, FALSE
) 
 373             pNode 
= pNode
->GetNext(); 
 379             bOk 
= (bool)::WinSendMsg( hMenu
 
 381                                      ,MPFROM2SHORT(GetRealId(), TRUE
) 
 382                                      ,MPFROM2SHORT(MIA_CHECKED
, MIA_CHECKED
) 
 385             bOk 
= (bool)::WinSendMsg( hMenu
 
 387                                      ,MPFROM2SHORT(GetRealId(), TRUE
) 
 388                                      ,MPFROM2SHORT(MIA_CHECKED
, FALSE
) 
 393         wxLogLastError("CheckMenuItem"); 
 395     wxMenuItemBase::Check(bCheck
); 
 396 } // end of wxMenuItem::Check 
 398 void wxMenuItem::SetText( 
 399   const wxString
&                   rText
 
 403     // Don't do anything if label didn't change 
 406     wxString                        sText 
= TextToLabel(rText
); 
 410     wxMenuItemBase::SetText(sText
); 
 411     OWNER_DRAWN_ONLY(wxOwnerDrawn::SetName(sText
)); 
 413     HWND                            hMenu 
= GetHmenuOf(m_parentMenu
); 
 415     wxCHECK_RET(hMenu
, wxT("menuitem without menu")); 
 418     m_parentMenu
->UpdateAccel(this); 
 419 #endif // wxUSE_ACCEL 
 421     USHORT                          uId 
= GetRealId(); 
 425     if (!::WinSendMsg( hMenu
 
 427                       ,MPFROM2SHORT(uId
, TRUE
) 
 431         wxLogLastError("GetMenuState"); 
 435         uFlagsOld 
= vItem
.afStyle
; 
 438             uFlagsOld 
|= MIS_SUBMENU
; 
 443 #if wxUSE_OWNER_DRAWN 
 446             uFlagsOld 
|= MIS_OWNERDRAW
; 
 452             uFlagsOld 
|= MIS_TEXT
; 
 453             pData 
= (BYTE
*)sText
.c_str(); 
 459         if (!::WinSendMsg( hMenu
 
 461                           ,MPFROM2SHORT(uId
, TRUE
) 
 465             wxLogLastError(wxT("ModifyMenu")); 
 471         if (::WinSendMsg( hMenu
 
 477             wxLogLastError(wxT("ModifyMenu")); 
 480 } // end of wxMenuItem::SetText 
 482 void wxMenuItem::SetCheckable( 
 486     wxMenuItemBase::SetCheckable(bCheckable
); 
 487     OWNER_DRAWN_ONLY(wxOwnerDrawn::SetCheckable(bCheckable
)); 
 488 } // end of wxMenuItem::SetCheckable 
 490 // ---------------------------------------------------------------------------- 
 492 // ---------------------------------------------------------------------------- 
 494 wxMenuItem
* wxMenuItemBase::New( 
 497 , const wxString
&                   rName
 
 498 , const wxString
&                   rHelp
 
 503     return new wxMenuItem( pParentMenu
 
 510 } // end of wxMenuItemBase::New