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