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"
40 #include "wx/msw/wince/missing.h"
42 #include "wx/msw/wince/resources.h"
44 #include "wx/stockitem.h"
46 wxTopLevelWindowMSW
::ButtonMenu
::ButtonMenu()
49 m_label
= wxEmptyString
;
54 wxTopLevelWindowMSW
::ButtonMenu
::~ButtonMenu()
63 void wxTopLevelWindowMSW
::SetLeftMenu(int id
, const wxString
& label
, wxMenu
*subMenu
)
65 m_LeftButton
.SetButton(id
, label
, subMenu
);
69 void wxTopLevelWindowMSW
::SetRightMenu(int id
, const wxString
& label
, wxMenu
*subMenu
)
71 m_RightButton
.SetButton(id
, label
, subMenu
);
75 void wxTopLevelWindowMSW
::ButtonMenu
::SetButton(int id
, const wxString
& label
, wxMenu
*subMenu
)
79 if(label
.empty() && wxIsStockID(id
))
80 m_label
= wxGetStockLabel(id
, false);
86 wxMenu
*wxTopLevelWindowMSW
::ButtonMenu
::DuplicateMenu(wxMenu
*menu
)
88 // This is required in case of converting wxMenuBar to wxMenu in wxFrame::SetMenuBar.
89 // All submenus has to be recreated because of new owner.
91 wxMenu
*duplication
= new wxMenu
;
95 wxMenuItemList
::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
98 wxMenuItem
*item
= node
->GetData();
101 wxMenu
*submenu
= NULL
;
103 if(item
->IsSubMenu())
104 submenu
= DuplicateMenu( item
->GetSubMenu() );
108 wxMenuItem
*new_item
= wxMenuItem
::New(duplication
, item
->GetId(), item
->GetLabel(), item
->GetHelp(), item
->GetKind(), submenu
);
110 if( item
->IsCheckable() )
111 new_item
->Check(item
->IsChecked());
113 new_item
->Enable( item
->IsEnabled() );
115 duplication
->Append(new_item
);
117 node
= node
->GetNext();
125 void wxMenuToHMenu(wxMenu
* in
, HMENU hMenu
)
131 wxMenuItemList
::compatibility_iterator node
= in
->GetMenuItems().GetFirst();
134 wxMenuItem
*item
= node
->GetData();
140 if( item
->IsSeparator() )
142 uFlags
|= MF_SEPARATOR
;
143 uIDNewItem
= (unsigned)wxID_ANY
;
150 wxStrcpy(buf
, item
->GetLabel().c_str());
154 uFlags
|= ( item
->IsEnabled() ? MF_ENABLED
: MF_GRAYED
);
157 uFlags
|= ( item
->IsChecked() ? MF_CHECKED
: MF_UNCHECKED
);
159 if( item
->IsSubMenu() )
162 HMENU hSubMenu
= CreatePopupMenu();
163 wxMenuToHMenu(item
->GetSubMenu(), hSubMenu
);
164 uIDNewItem
= (UINT
) hSubMenu
;
168 uIDNewItem
= item
->GetId();
172 AppendMenu(hMenu
, uFlags
, uIDNewItem
, lpNewItem
);
174 node
= node
->GetNext();
178 void wxTopLevelWindowMSW
::ReloadButton(ButtonMenu
& button
, UINT menuID
)
180 TBBUTTONINFO button_info
;
184 memset (&button_info
, 0, sizeof (TBBUTTONINFO
));
185 button_info
.cbSize
= sizeof(TBBUTTONINFO
);
186 button_info
.dwMask
= TBIF_TEXT
| TBIF_STATE
;
187 button_info
.fsState
= TBSTATE_ENABLED
;
188 wxStrcpy(buf
, button
.GetLabel().c_str());
189 button_info
.pszText
= buf
;
190 ::SendMessage(m_MenuBarHWND
, TB_SETBUTTONINFO
, menuID
, (LPARAM
) &button_info
);
194 HMENU hPopupMenu
= (HMENU
) ::SendMessage(m_MenuBarHWND
, SHCMBM_GETSUBMENU
, 0, menuID
);
195 RemoveMenu(hPopupMenu
, 0, MF_BYPOSITION
);
196 wxMenuToHMenu(button
.GetMenu(), hPopupMenu
);
200 void wxTopLevelWindowMSW
::ReloadAllButtons()
202 // first reaload only after initialization of both buttons
203 // it should is done at the end of Create() of wxTLW
204 if(!m_LeftButton
.IsAssigned() || !m_RightButton
.IsAssigned())
207 SHMENUBARINFO menu_bar
;
210 memset (&menu_bar
, 0, sizeof (SHMENUBARINFO
));
211 menu_bar
.cbSize
= sizeof (SHMENUBARINFO
);
212 menu_bar
.hwndParent
= (HWND
) GetHWND();
214 if(m_LeftButton
.IsMenu() && m_RightButton
.IsMenu())
215 menu_bar
.nToolBarId
= IDR_MENUBAR_BOTH_MENUS
;
216 else if(m_LeftButton
.IsMenu())
217 menu_bar
.nToolBarId
= IDR_MENUBAR_LEFT_MENU
;
218 else if(m_RightButton
.IsMenu())
219 menu_bar
.nToolBarId
= IDR_MENUBAR_RIGHT_MENU
;
221 menu_bar
.nToolBarId
= IDR_MENUBAR_ONE_BUTTON
;
223 menu_bar
.hInstRes
= wxGetInstance();
225 if (!SHCreateMenuBar(&menu_bar
))
227 wxFAIL_MSG( _T("SHCreateMenuBar failed") );
231 HWND prev_MenuBar
= m_MenuBarHWND
;
232 m_MenuBarHWND
= menu_bar
.hwndMB
;
234 ReloadButton(m_LeftButton
, IDM_LEFT
);
235 ReloadButton(m_RightButton
, IDM_RIGHT
);
237 // hide previous and show new menubar
239 ::ShowWindow( prev_MenuBar
, SW_HIDE
);
240 ::ShowWindow( m_MenuBarHWND
, SW_SHOW
);
242 // Setup backspace key handling
243 SendMessage(m_MenuBarHWND
, SHCMBM_OVERRIDEKEY
, VK_TBACK
,
244 MAKELPARAM( SHMBOF_NODEFAULT
| SHMBOF_NOTIFY
,
245 SHMBOF_NODEFAULT
| SHMBOF_NOTIFY
));
248 bool wxTopLevelWindowMSW
::HandleCommand(WXWORD id
, WXWORD
WXUNUSED(cmd
), WXHWND
WXUNUSED(control
))
250 // handle here commands from Smartphone menu bar
251 if ( id
== IDM_LEFT
|| id
== IDM_RIGHT
)
253 int menuId
= id
== IDM_LEFT ? m_LeftButton
.GetId() : m_RightButton
.GetId() ;
254 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, menuId
);
255 commandEvent
.SetEventObject(this);
256 GetEventHandler()->ProcessEvent(commandEvent
);
262 bool wxTopLevelWindowMSW
::MSWShouldPreProcessMessage(WXMSG
* pMsg
)
264 MSG
*msg
= (MSG
*)pMsg
;
266 // Process back key to be like backspace.
267 if (msg
->message
== WM_HOTKEY
)
269 if (HIWORD(msg
->lParam
) == VK_TBACK
)
270 SHSendBackToFocusWindow(msg
->message
, msg
->wParam
, msg
->lParam
);
273 return wxTopLevelWindowBase
::MSWShouldPreProcessMessage(pMsg
);
276 #endif // __SMARTPHONE__ && __WXWINCE__