Hardware defines spec.
[wxWidgets.git] / src / msw / wince / menuce.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/wince/menuce.cpp
3 // Purpose: Smartphone menus implementation
4 // Author: Wlodzimierz ABX Skiba
5 // Modified by:
6 // Created: 28.05.2004
7 // RCS-ID: $Id$
8 // Copyright: (c) Wlodzimierz Skiba
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "menuce"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/wx.h"
33 #endif
34
35 #ifndef WX_PRECOMP
36 #include "wx/app.h"
37 #include "wx/toplevel.h"
38 #include "wx/menu.h"
39 #endif //WX_PRECOMP
40
41 #if defined(__SMARTPHONE__) && defined(__WXWINCE__)
42
43 #include <windows.h>
44 #include <ole2.h>
45 #include <shellapi.h>
46 #include <aygshell.h>
47 #include "wx/msw/wince/missing.h"
48
49 #include "wx/msw/wince/resources.h"
50
51 wxTopLevelWindowMSW::ButtonMenu::ButtonMenu()
52 {
53 m_id = wxID_ANY;
54 m_label = wxEmptyString;
55 m_menu = NULL;
56 m_assigned = false;
57 }
58
59 wxTopLevelWindowMSW::ButtonMenu::~ButtonMenu()
60 {
61 if(m_menu)
62 {
63 delete m_menu;
64 m_menu = NULL;
65 };
66 }
67
68 void wxTopLevelWindowMSW::SetLeftMenu(int id, const wxString& label, wxMenu *subMenu)
69 {
70 m_LeftButton.SetButton(id, label, subMenu);
71 ReloadAllButtons();
72 }
73
74 void wxTopLevelWindowMSW::SetRightMenu(int id, const wxString& label, wxMenu *subMenu)
75 {
76 m_RightButton.SetButton(id, label, subMenu);
77 ReloadAllButtons();
78 }
79
80 void wxTopLevelWindowMSW::ButtonMenu::SetButton(int id, const wxString& label, wxMenu *subMenu)
81 {
82 m_assigned = true;
83 m_id = id;
84 m_label = label;
85 m_menu = subMenu;
86 }
87
88 wxMenu *wxTopLevelWindowMSW::ButtonMenu::DuplicateMenu(wxMenu *menu)
89 {
90 // This is required in case of converting wxMenuBar to wxMenu in wxFrame::SetMenuBar.
91 // All submenus has to be recreated because of new owner.
92
93 wxMenu *duplication = new wxMenu;
94
95 if (menu)
96 {
97 wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
98 while (node)
99 {
100 wxMenuItem *item = node->GetData();
101 if (item)
102 {
103 wxMenu *submenu = NULL;
104
105 if(item->IsSubMenu())
106 submenu = DuplicateMenu( item->GetSubMenu() );
107 else
108 submenu = NULL;
109
110 wxMenuItem *new_item = wxMenuItem::New(duplication, item->GetId(), item->GetLabel(), item->GetHelp(), item->GetKind(), submenu);
111
112 if( item->IsCheckable() )
113 new_item->Check(item->IsChecked());
114
115 new_item->Enable( item->IsEnabled() );
116
117 duplication->Append(new_item);
118 }
119 node = node->GetNext();
120 }
121
122 }
123
124 return duplication;
125 }
126
127 void wxMenuToHMenu(wxMenu* in, HMENU hMenu)
128 {
129 if(!in) return;
130
131 wxChar buf[256];
132
133 wxMenuItemList::compatibility_iterator node = in->GetMenuItems().GetFirst();
134 while ( node )
135 {
136 wxMenuItem *item = node->GetData();
137
138 UINT uFlags = 0;
139 UINT uIDNewItem;
140 LPCTSTR lpNewItem;
141
142 if( item->IsSeparator() )
143 {
144 uFlags |= MF_SEPARATOR;
145 uIDNewItem = (unsigned)wxID_ANY;
146 lpNewItem = NULL;
147 }
148 else
149 {
150 // label
151 uFlags |= MF_STRING;
152 wxStrcpy(buf, item->GetLabel().c_str());
153 lpNewItem = buf;
154
155 // state
156 uFlags |= ( item->IsEnabled() ? MF_ENABLED : MF_GRAYED );
157
158 // checked
159 uFlags |= ( item->IsChecked() ? MF_CHECKED : MF_UNCHECKED );
160
161 if( item->IsSubMenu() )
162 {
163 uFlags |= MF_POPUP;
164 HMENU hSubMenu = CreatePopupMenu();
165 wxMenuToHMenu(item->GetSubMenu(), hSubMenu);
166 uIDNewItem = (UINT) hSubMenu;
167 }
168 else
169 {
170 uIDNewItem = item->GetId();
171 }
172 }
173
174 AppendMenu(hMenu, uFlags, uIDNewItem, lpNewItem);
175
176 node = node->GetNext();
177 }
178 }
179
180 void wxTopLevelWindowMSW::ReloadButton(ButtonMenu& button, UINT menuID)
181 {
182 TBBUTTONINFO button_info;
183 wxChar buf[256];
184
185 // set button name
186 memset (&button_info, 0, sizeof (TBBUTTONINFO));
187 button_info.cbSize = sizeof(TBBUTTONINFO);
188 button_info.dwMask = TBIF_TEXT | TBIF_STATE;
189 button_info.fsState = TBSTATE_ENABLED;
190 wxStrcpy(buf, button.GetLabel().c_str());
191 button_info.pszText = buf;
192 ::SendMessage(m_MenuBarHWND, TB_SETBUTTONINFO, menuID, (LPARAM) &button_info);
193
194 if(button.IsMenu())
195 {
196 HMENU hPopupMenu = (HMENU) ::SendMessage(m_MenuBarHWND, SHCMBM_GETSUBMENU, 0, menuID);
197 RemoveMenu(hPopupMenu, 0, MF_BYPOSITION);
198 wxMenuToHMenu(button.GetMenu(), hPopupMenu);
199 }
200 }
201
202 void wxTopLevelWindowMSW::ReloadAllButtons()
203 {
204 // first reaload only after initialization of both buttons
205 // it should is done at the end of Create() of wxTLW
206 if(!m_LeftButton.IsAssigned() || !m_RightButton.IsAssigned())
207 return;
208
209 SHMENUBARINFO menu_bar;
210 wxString label;
211
212 memset (&menu_bar, 0, sizeof (SHMENUBARINFO));
213 menu_bar.cbSize = sizeof (SHMENUBARINFO);
214 menu_bar.hwndParent = (HWND) GetHWND();
215
216 if(m_LeftButton.IsMenu() && m_RightButton.IsMenu())
217 menu_bar.nToolBarId = IDR_MENUBAR_BOTH_MENUS;
218 else if(m_LeftButton.IsMenu())
219 menu_bar.nToolBarId = IDR_MENUBAR_LEFT_MENU;
220 else if(m_RightButton.IsMenu())
221 menu_bar.nToolBarId = IDR_MENUBAR_RIGHT_MENU;
222 else
223 menu_bar.nToolBarId = IDR_MENUBAR_ONE_BUTTON;
224
225 menu_bar.hInstRes = wxGetInstance();
226
227 if (!SHCreateMenuBar(&menu_bar))
228 {
229 wxFAIL_MSG( _T("SHCreateMenuBar failed") );
230 return;
231 }
232
233 HWND prev_MenuBar = m_MenuBarHWND;
234 m_MenuBarHWND = menu_bar.hwndMB;
235
236 ReloadButton(m_LeftButton, IDM_LEFT);
237 ReloadButton(m_RightButton, IDM_RIGHT);
238
239 // hide previous and show new menubar
240 if ( prev_MenuBar )
241 ::ShowWindow( prev_MenuBar, SW_HIDE );
242 ::ShowWindow( m_MenuBarHWND, SW_SHOW );
243
244 }
245
246 bool wxTopLevelWindowMSW::HandleCommand(WXWORD id, WXWORD WXUNUSED(cmd), WXHWND WXUNUSED(control))
247 {
248 // handle here commands from Smartphone menu bar
249 if ( id == IDM_LEFT || id == IDM_RIGHT )
250 {
251 int menuId = id == IDM_LEFT ? m_LeftButton.GetId() : m_RightButton.GetId() ;
252 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, menuId);
253 commandEvent.SetEventObject(this);
254 GetEventHandler()->ProcessEvent(commandEvent);
255 return true;
256 }
257 return false;
258 }
259
260 #endif // __SMARTPHONE__ && __WXWINCE__
261