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