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