]> git.saurik.com Git - wxWidgets.git/blob - src/msw/wince/menuce.cpp
Fixed a long-standing issue where wxSlider controls with a hardcoded size would mispl...
[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 #include "wx/stockitem.h"
52
53 wxTopLevelWindowMSW::ButtonMenu::ButtonMenu()
54 {
55 m_id = wxID_ANY;
56 m_label = wxEmptyString;
57 m_menu = NULL;
58 m_assigned = false;
59 }
60
61 wxTopLevelWindowMSW::ButtonMenu::~ButtonMenu()
62 {
63 if(m_menu)
64 {
65 delete m_menu;
66 m_menu = NULL;
67 };
68 }
69
70 void wxTopLevelWindowMSW::SetLeftMenu(int id, const wxString& label, wxMenu *subMenu)
71 {
72 m_LeftButton.SetButton(id, label, subMenu);
73 ReloadAllButtons();
74 }
75
76 void wxTopLevelWindowMSW::SetRightMenu(int id, const wxString& label, wxMenu *subMenu)
77 {
78 m_RightButton.SetButton(id, label, subMenu);
79 ReloadAllButtons();
80 }
81
82 void wxTopLevelWindowMSW::ButtonMenu::SetButton(int id, const wxString& label, wxMenu *subMenu)
83 {
84 m_assigned = true;
85 m_id = id;
86 if(label.empty() && wxIsStockID(id))
87 m_label = wxGetStockLabel(id);
88 else
89 m_label = label;
90 m_menu = subMenu;
91 }
92
93 wxMenu *wxTopLevelWindowMSW::ButtonMenu::DuplicateMenu(wxMenu *menu)
94 {
95 // This is required in case of converting wxMenuBar to wxMenu in wxFrame::SetMenuBar.
96 // All submenus has to be recreated because of new owner.
97
98 wxMenu *duplication = new wxMenu;
99
100 if (menu)
101 {
102 wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
103 while (node)
104 {
105 wxMenuItem *item = node->GetData();
106 if (item)
107 {
108 wxMenu *submenu = NULL;
109
110 if(item->IsSubMenu())
111 submenu = DuplicateMenu( item->GetSubMenu() );
112 else
113 submenu = NULL;
114
115 wxMenuItem *new_item = wxMenuItem::New(duplication, item->GetId(), item->GetLabel(), item->GetHelp(), item->GetKind(), submenu);
116
117 if( item->IsCheckable() )
118 new_item->Check(item->IsChecked());
119
120 new_item->Enable( item->IsEnabled() );
121
122 duplication->Append(new_item);
123 }
124 node = node->GetNext();
125 }
126
127 }
128
129 return duplication;
130 }
131
132 void wxMenuToHMenu(wxMenu* in, HMENU hMenu)
133 {
134 if(!in) return;
135
136 wxChar buf[256];
137
138 wxMenuItemList::compatibility_iterator node = in->GetMenuItems().GetFirst();
139 while ( node )
140 {
141 wxMenuItem *item = node->GetData();
142
143 UINT uFlags = 0;
144 UINT uIDNewItem;
145 LPCTSTR lpNewItem;
146
147 if( item->IsSeparator() )
148 {
149 uFlags |= MF_SEPARATOR;
150 uIDNewItem = (unsigned)wxID_ANY;
151 lpNewItem = NULL;
152 }
153 else
154 {
155 // label
156 uFlags |= MF_STRING;
157 wxStrcpy(buf, item->GetLabel().c_str());
158 lpNewItem = buf;
159
160 // state
161 uFlags |= ( item->IsEnabled() ? MF_ENABLED : MF_GRAYED );
162
163 // checked
164 uFlags |= ( item->IsChecked() ? MF_CHECKED : MF_UNCHECKED );
165
166 if( item->IsSubMenu() )
167 {
168 uFlags |= MF_POPUP;
169 HMENU hSubMenu = CreatePopupMenu();
170 wxMenuToHMenu(item->GetSubMenu(), hSubMenu);
171 uIDNewItem = (UINT) hSubMenu;
172 }
173 else
174 {
175 uIDNewItem = item->GetId();
176 }
177 }
178
179 AppendMenu(hMenu, uFlags, uIDNewItem, lpNewItem);
180
181 node = node->GetNext();
182 }
183 }
184
185 void wxTopLevelWindowMSW::ReloadButton(ButtonMenu& button, UINT menuID)
186 {
187 TBBUTTONINFO button_info;
188 wxChar buf[256];
189
190 // set button name
191 memset (&button_info, 0, sizeof (TBBUTTONINFO));
192 button_info.cbSize = sizeof(TBBUTTONINFO);
193 button_info.dwMask = TBIF_TEXT | TBIF_STATE;
194 button_info.fsState = TBSTATE_ENABLED;
195 wxStrcpy(buf, button.GetLabel().c_str());
196 button_info.pszText = buf;
197 ::SendMessage(m_MenuBarHWND, TB_SETBUTTONINFO, menuID, (LPARAM) &button_info);
198
199 if(button.IsMenu())
200 {
201 HMENU hPopupMenu = (HMENU) ::SendMessage(m_MenuBarHWND, SHCMBM_GETSUBMENU, 0, menuID);
202 RemoveMenu(hPopupMenu, 0, MF_BYPOSITION);
203 wxMenuToHMenu(button.GetMenu(), hPopupMenu);
204 }
205 }
206
207 void wxTopLevelWindowMSW::ReloadAllButtons()
208 {
209 // first reaload only after initialization of both buttons
210 // it should is done at the end of Create() of wxTLW
211 if(!m_LeftButton.IsAssigned() || !m_RightButton.IsAssigned())
212 return;
213
214 SHMENUBARINFO menu_bar;
215 wxString label;
216
217 memset (&menu_bar, 0, sizeof (SHMENUBARINFO));
218 menu_bar.cbSize = sizeof (SHMENUBARINFO);
219 menu_bar.hwndParent = (HWND) GetHWND();
220
221 if(m_LeftButton.IsMenu() && m_RightButton.IsMenu())
222 menu_bar.nToolBarId = IDR_MENUBAR_BOTH_MENUS;
223 else if(m_LeftButton.IsMenu())
224 menu_bar.nToolBarId = IDR_MENUBAR_LEFT_MENU;
225 else if(m_RightButton.IsMenu())
226 menu_bar.nToolBarId = IDR_MENUBAR_RIGHT_MENU;
227 else
228 menu_bar.nToolBarId = IDR_MENUBAR_ONE_BUTTON;
229
230 menu_bar.hInstRes = wxGetInstance();
231
232 if (!SHCreateMenuBar(&menu_bar))
233 {
234 wxFAIL_MSG( _T("SHCreateMenuBar failed") );
235 return;
236 }
237
238 HWND prev_MenuBar = m_MenuBarHWND;
239 m_MenuBarHWND = menu_bar.hwndMB;
240
241 ReloadButton(m_LeftButton, IDM_LEFT);
242 ReloadButton(m_RightButton, IDM_RIGHT);
243
244 // hide previous and show new menubar
245 if ( prev_MenuBar )
246 ::ShowWindow( prev_MenuBar, SW_HIDE );
247 ::ShowWindow( m_MenuBarHWND, SW_SHOW );
248
249 }
250
251 bool wxTopLevelWindowMSW::HandleCommand(WXWORD id, WXWORD WXUNUSED(cmd), WXHWND WXUNUSED(control))
252 {
253 // handle here commands from Smartphone menu bar
254 if ( id == IDM_LEFT || id == IDM_RIGHT )
255 {
256 int menuId = id == IDM_LEFT ? m_LeftButton.GetId() : m_RightButton.GetId() ;
257 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, menuId);
258 commandEvent.SetEventObject(this);
259 GetEventHandler()->ProcessEvent(commandEvent);
260 return true;
261 }
262 return false;
263 }
264
265 #endif // __SMARTPHONE__ && __WXWINCE__
266