1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/wince/menuce.cpp 
   3 // Purpose:     Smartphone menus implementation 
   4 // Author:      Wlodzimierz ABX Skiba 
   8 // Copyright:   (c) Wlodzimierz Skiba 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  27 #if defined(__SMARTPHONE__) && defined(__WXWINCE__) 
  31     #include "wx/toplevel.h" 
  41 #include "wx/msw/wince/missing.h" 
  43 #include "wx/msw/wince/resources.h" 
  45 #include "wx/stockitem.h" 
  47 wxTopLevelWindowMSW::ButtonMenu::ButtonMenu() 
  50     m_label 
= wxEmptyString
; 
  55 wxTopLevelWindowMSW::ButtonMenu::~ButtonMenu() 
  64 void wxTopLevelWindowMSW::SetLeftMenu(int id
, const wxString
& label
, wxMenu 
*subMenu
) 
  66     m_LeftButton
.SetButton(id
, label
, subMenu
); 
  70 void wxTopLevelWindowMSW::SetRightMenu(int id
, const wxString
& label
, wxMenu 
*subMenu
) 
  72     m_RightButton
.SetButton(id
, label
, subMenu
); 
  76 void wxTopLevelWindowMSW::ButtonMenu::SetButton(int id
, const wxString
& label
, wxMenu 
*subMenu
) 
  80     if(label
.empty() && wxIsStockID(id
)) 
  81         m_label 
= wxGetStockLabel(id
, false); 
  87 wxMenu 
*wxTopLevelWindowMSW::ButtonMenu::DuplicateMenu(wxMenu 
*menu
) 
  89     // This is required in case of converting wxMenuBar to wxMenu in wxFrame::SetMenuBar. 
  90     // All submenus has to be recreated because of new owner. 
  92     wxMenu 
*duplication 
= new wxMenu
; 
  96         wxMenuItemList::compatibility_iterator node 
= menu
->GetMenuItems().GetFirst(); 
  99             wxMenuItem 
*item 
= node
->GetData(); 
 102                 wxMenu 
*submenu 
= NULL
; 
 104                 if(item
->IsSubMenu()) 
 105                     submenu 
= DuplicateMenu( item
->GetSubMenu() ); 
 109                 wxMenuItem 
*new_item 
= wxMenuItem::New(duplication
, item
->GetId(), item
->GetLabel(), item
->GetHelp(), item
->GetKind(), submenu
); 
 111                 if( item
->IsCheckable() ) 
 112                     new_item
->Check(item
->IsChecked()); 
 114                 new_item
->Enable( item
->IsEnabled() ); 
 116                 duplication
->Append(new_item
); 
 118             node 
= node
->GetNext(); 
 126 void wxMenuToHMenu(wxMenu
* in
, HMENU hMenu
) 
 132     wxMenuItemList::compatibility_iterator node 
= in
->GetMenuItems().GetFirst(); 
 135         wxMenuItem 
*item 
= node
->GetData(); 
 141         if( item
->IsSeparator() ) 
 143             uFlags 
|= MF_SEPARATOR
; 
 144             uIDNewItem 
= (unsigned)wxID_ANY
; 
 151             wxStrcpy(buf
, item
->GetLabel().c_str()); 
 155             uFlags 
|= ( item
->IsEnabled() ? MF_ENABLED 
: MF_GRAYED 
); 
 158             uFlags 
|= ( item
->IsChecked() ? MF_CHECKED 
: MF_UNCHECKED 
); 
 160             if( item
->IsSubMenu() ) 
 163                 HMENU hSubMenu 
= CreatePopupMenu(); 
 164                 wxMenuToHMenu(item
->GetSubMenu(), hSubMenu
); 
 165                 uIDNewItem 
= (UINT
) hSubMenu
; 
 169                 uIDNewItem 
= item
->GetId(); 
 173         AppendMenu(hMenu
, uFlags
, uIDNewItem
, lpNewItem
); 
 175         node 
= node
->GetNext(); 
 179 void wxTopLevelWindowMSW::ReloadButton(ButtonMenu
& button
, UINT menuID
) 
 181     TBBUTTONINFO  button_info
; 
 185     memset (&button_info
, 0, sizeof (TBBUTTONINFO
)); 
 186     button_info
.cbSize 
= sizeof(TBBUTTONINFO
); 
 187     button_info
.dwMask 
= TBIF_TEXT 
| TBIF_STATE
; 
 188     button_info
.fsState 
= TBSTATE_ENABLED
; 
 189     wxStrcpy(buf
, button
.GetLabel().c_str()); 
 190     button_info
.pszText 
= buf
; 
 191     ::SendMessage(m_MenuBarHWND
, TB_SETBUTTONINFO
, menuID
, (LPARAM
) &button_info
); 
 195         HMENU hPopupMenu 
= (HMENU
) ::SendMessage(m_MenuBarHWND
, SHCMBM_GETSUBMENU
, 0, menuID
); 
 196         RemoveMenu(hPopupMenu
, 0, MF_BYPOSITION
); 
 197         wxMenuToHMenu(button
.GetMenu(), hPopupMenu
); 
 201 void wxTopLevelWindowMSW::ReloadAllButtons() 
 203     // first reaload only after initialization of both buttons 
 204     // it should is done at the end of Create() of wxTLW 
 205     if(!m_LeftButton
.IsAssigned() || !m_RightButton
.IsAssigned()) 
 208     SHMENUBARINFO menu_bar
; 
 211     memset (&menu_bar
,    0, sizeof (SHMENUBARINFO
)); 
 212     menu_bar
.cbSize     
= sizeof (SHMENUBARINFO
); 
 213     menu_bar
.hwndParent 
= (HWND
) GetHWND(); 
 215     if(m_LeftButton
.IsMenu() && m_RightButton
.IsMenu()) 
 216         menu_bar
.nToolBarId 
= IDR_MENUBAR_BOTH_MENUS
; 
 217     else if(m_LeftButton
.IsMenu()) 
 218         menu_bar
.nToolBarId 
= IDR_MENUBAR_LEFT_MENU
; 
 219     else if(m_RightButton
.IsMenu()) 
 220         menu_bar
.nToolBarId 
= IDR_MENUBAR_RIGHT_MENU
; 
 222         menu_bar
.nToolBarId 
= IDR_MENUBAR_ONE_BUTTON
; 
 224     menu_bar
.hInstRes 
= wxGetInstance(); 
 226     if (!SHCreateMenuBar(&menu_bar
)) 
 228         wxFAIL_MSG( _T("SHCreateMenuBar failed") ); 
 232     HWND prev_MenuBar 
= m_MenuBarHWND
; 
 233     m_MenuBarHWND 
= menu_bar
.hwndMB
; 
 235     ReloadButton(m_LeftButton
, IDM_LEFT
); 
 236     ReloadButton(m_RightButton
, IDM_RIGHT
); 
 238     // hide previous and show new menubar 
 240         ::ShowWindow( prev_MenuBar
, SW_HIDE 
); 
 241     ::ShowWindow( m_MenuBarHWND
, SW_SHOW 
); 
 243     // Setup backspace key handling 
 244     SendMessage(m_MenuBarHWND
, SHCMBM_OVERRIDEKEY
, VK_TBACK
, 
 245                 MAKELPARAM( SHMBOF_NODEFAULT 
| SHMBOF_NOTIFY
, 
 246                             SHMBOF_NODEFAULT 
| SHMBOF_NOTIFY 
)); 
 249 bool wxTopLevelWindowMSW::HandleCommand(WXWORD id
, WXWORD 
WXUNUSED(cmd
), WXHWND 
WXUNUSED(control
)) 
 251     // handle here commands from Smartphone menu bar 
 252     if ( id 
== IDM_LEFT 
|| id 
== IDM_RIGHT 
) 
 254         int menuId 
= id 
== IDM_LEFT 
? m_LeftButton
.GetId() : m_RightButton
.GetId() ; 
 255         wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, menuId
); 
 256         commandEvent
.SetEventObject(this); 
 257         GetEventHandler()->ProcessEvent(commandEvent
); 
 263 bool wxTopLevelWindowMSW::MSWShouldPreProcessMessage(WXMSG
* pMsg
) 
 265     MSG 
*msg 
= (MSG 
*)pMsg
; 
 267     // Process back key to be like backspace. 
 268     if (msg
->message 
== WM_HOTKEY
) 
 270         if (HIWORD(msg
->lParam
) == VK_TBACK
) 
 271             SHSendBackToFocusWindow(msg
->message
, msg
->wParam
, msg
->lParam
); 
 274     return wxTopLevelWindowBase::MSWShouldPreProcessMessage(pMsg
); 
 277 #endif // __SMARTPHONE__ && __WXWINCE__