]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: menu.cpp | |
3 | // Purpose: wxMenu, wxMenuBar, wxMenuItem | |
4 | // Author: William Osborne | |
5 | // Modified by: | |
6 | // Created: 10/12/04 | |
7 | // RCS-ID: $Id: | |
8 | // Copyright: (c) William Osborne | |
9 | // Licence: 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 "menu.h" | |
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 | #if wxUSE_MENUS | |
32 | ||
33 | #ifndef WX_PRECOMP | |
34 | #include "wx/frame.h" | |
35 | #include "wx/menu.h" | |
36 | #include "wx/utils.h" | |
37 | #include "wx/intl.h" | |
38 | #include "wx/log.h" | |
39 | #endif | |
40 | ||
41 | #if wxUSE_OWNER_DRAWN | |
42 | #include "wx/ownerdrw.h" | |
43 | #endif | |
44 | ||
45 | // other standard headers | |
46 | #include <string.h> | |
47 | ||
48 | #ifdef __PALMOS__ | |
49 | #include <PalmOS.h> | |
50 | #include <Menu.h> | |
51 | #endif | |
52 | ||
53 | // ---------------------------------------------------------------------------- | |
54 | // global variables | |
55 | // ---------------------------------------------------------------------------- | |
56 | ||
57 | extern wxMenu *wxCurrentPopupMenu; | |
58 | ||
59 | // ---------------------------------------------------------------------------- | |
60 | // constants | |
61 | // ---------------------------------------------------------------------------- | |
62 | ||
63 | // the (popup) menu title has this special id | |
64 | static const int idMenuTitle = -3; | |
65 | ||
66 | // ---------------------------------------------------------------------------- | |
67 | // private functions | |
68 | // ---------------------------------------------------------------------------- | |
69 | ||
70 | // ============================================================================ | |
71 | // implementation | |
72 | // ============================================================================ | |
73 | ||
74 | #include <wx/listimpl.cpp> | |
75 | ||
76 | WX_DEFINE_LIST( wxMenuInfoList ) ; | |
77 | ||
78 | #if wxUSE_EXTENDED_RTTI | |
79 | ||
80 | WX_DEFINE_FLAGS( wxMenuStyle ) | |
81 | ||
82 | wxBEGIN_FLAGS( wxMenuStyle ) | |
83 | wxFLAGS_MEMBER(wxMENU_TEAROFF) | |
84 | wxEND_FLAGS( wxMenuStyle ) | |
85 | ||
86 | IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenu, wxEvtHandler,"wx/menu.h") | |
87 | ||
88 | wxCOLLECTION_TYPE_INFO( wxMenuItem * , wxMenuItemList ) ; | |
89 | ||
90 | template<> void wxCollectionToVariantArray( wxMenuItemList const &theList, wxxVariantArray &value) | |
91 | { | |
92 | wxListCollectionToVariantArray<wxMenuItemList::compatibility_iterator>( theList , value ) ; | |
93 | } | |
94 | ||
95 | wxBEGIN_PROPERTIES_TABLE(wxMenu) | |
96 | wxEVENT_PROPERTY( Select , wxEVT_COMMAND_MENU_SELECTED , wxCommandEvent) | |
97 | wxPROPERTY( Title, wxString , SetTitle, GetTitle, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) | |
98 | wxREADONLY_PROPERTY_FLAGS( MenuStyle , wxMenuStyle , long , GetStyle , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style | |
99 | wxPROPERTY_COLLECTION( MenuItems , wxMenuItemList , wxMenuItem* , Append , GetMenuItems , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
100 | wxEND_PROPERTIES_TABLE() | |
101 | ||
102 | wxBEGIN_HANDLERS_TABLE(wxMenu) | |
103 | wxEND_HANDLERS_TABLE() | |
104 | ||
105 | wxDIRECT_CONSTRUCTOR_2( wxMenu , wxString , Title , long , MenuStyle ) | |
106 | ||
107 | WX_DEFINE_FLAGS( wxMenuBarStyle ) | |
108 | ||
109 | wxBEGIN_FLAGS( wxMenuBarStyle ) | |
110 | wxFLAGS_MEMBER(wxMB_DOCKABLE) | |
111 | wxEND_FLAGS( wxMenuBarStyle ) | |
112 | ||
113 | // the negative id would lead the window (its superclass !) to vetoe streaming out otherwise | |
114 | bool wxMenuBarStreamingCallback( const wxObject *WXUNUSED(object), wxWriter * , wxPersister * , wxxVariantArray & ) | |
115 | { | |
116 | return true ; | |
117 | } | |
118 | ||
119 | IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuBar, wxWindow ,"wx/menu.h",wxMenuBarStreamingCallback) | |
120 | ||
121 | IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenuInfo, wxObject , "wx/menu.h" ) | |
122 | ||
123 | wxBEGIN_PROPERTIES_TABLE(wxMenuInfo) | |
124 | wxREADONLY_PROPERTY( Menu , wxMenu* , GetMenu , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
125 | wxREADONLY_PROPERTY( Title , wxString , GetTitle , wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
126 | wxEND_PROPERTIES_TABLE() | |
127 | ||
128 | wxBEGIN_HANDLERS_TABLE(wxMenuInfo) | |
129 | wxEND_HANDLERS_TABLE() | |
130 | ||
131 | wxCONSTRUCTOR_2( wxMenuInfo , wxMenu* , Menu , wxString , Title ) | |
132 | ||
133 | wxCOLLECTION_TYPE_INFO( wxMenuInfo * , wxMenuInfoList ) ; | |
134 | ||
135 | template<> void wxCollectionToVariantArray( wxMenuInfoList const &theList, wxxVariantArray &value) | |
136 | { | |
137 | wxListCollectionToVariantArray<wxMenuInfoList::compatibility_iterator>( theList , value ) ; | |
138 | } | |
139 | ||
140 | wxBEGIN_PROPERTIES_TABLE(wxMenuBar) | |
141 | wxPROPERTY_COLLECTION( MenuInfos , wxMenuInfoList , wxMenuInfo* , Append , GetMenuInfos , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
142 | wxEND_PROPERTIES_TABLE() | |
143 | ||
144 | wxBEGIN_HANDLERS_TABLE(wxMenuBar) | |
145 | wxEND_HANDLERS_TABLE() | |
146 | ||
147 | wxCONSTRUCTOR_DUMMY( wxMenuBar ) | |
148 | ||
149 | #else | |
150 | IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler) | |
151 | IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxWindow) | |
152 | IMPLEMENT_DYNAMIC_CLASS(wxMenuInfo, wxObject) | |
153 | #endif | |
154 | ||
155 | const wxMenuInfoList& wxMenuBar::GetMenuInfos() const | |
156 | { | |
157 | wxMenuInfoList* list = const_cast< wxMenuInfoList* >( &m_menuInfos ) ; | |
158 | WX_CLEAR_LIST( wxMenuInfoList , *list ) ; | |
159 | for( size_t i = 0 ; i < GetMenuCount() ; ++i ) | |
160 | { | |
161 | wxMenuInfo* info = new wxMenuInfo() ; | |
162 | info->Create( const_cast<wxMenuBar*>(this)->GetMenu(i) , GetLabelTop(i) ) ; | |
163 | list->Append( info ) ; | |
164 | } | |
165 | return m_menuInfos ; | |
166 | } | |
167 | ||
168 | // --------------------------------------------------------------------------- | |
169 | // wxMenu construction, adding and removing menu items | |
170 | // --------------------------------------------------------------------------- | |
171 | ||
172 | // Construct a menu with optional title (then use append) | |
173 | void wxMenu::Init() | |
174 | { | |
175 | } | |
176 | ||
177 | // The wxWindow destructor will take care of deleting the submenus. | |
178 | wxMenu::~wxMenu() | |
179 | { | |
180 | } | |
181 | ||
182 | void wxMenu::Break() | |
183 | { | |
184 | } | |
185 | ||
186 | void wxMenu::Attach(wxMenuBarBase *menubar) | |
187 | { | |
188 | wxMenuBase::Attach(menubar); | |
189 | } | |
190 | ||
191 | #if wxUSE_ACCEL | |
192 | ||
193 | int wxMenu::FindAccel(int id) const | |
194 | { | |
195 | return wxNOT_FOUND; | |
196 | } | |
197 | ||
198 | void wxMenu::UpdateAccel(wxMenuItem *item) | |
199 | { | |
200 | } | |
201 | ||
202 | #endif // wxUSE_ACCEL | |
203 | ||
204 | // append a new item or submenu to the menu | |
205 | bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) | |
206 | { | |
207 | if ( IsAttached() && GetMenuBar()->IsAttached() ) | |
208 | { | |
209 | // Regenerate the menu resource | |
210 | GetMenuBar()->Refresh(); | |
211 | } | |
212 | ||
213 | return TRUE; | |
214 | } | |
215 | ||
216 | void wxMenu::EndRadioGroup() | |
217 | { | |
218 | } | |
219 | ||
220 | wxMenuItem* wxMenu::DoAppend(wxMenuItem *item) | |
221 | { | |
222 | wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") ); | |
223 | ||
224 | if(!wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item)) | |
225 | { | |
226 | return NULL; | |
227 | } | |
228 | else if(IsAttached() && GetMenuBar()->IsAttached()) | |
229 | { | |
230 | // Regenerate the menu resource | |
231 | GetMenuBar()->Refresh(); | |
232 | } | |
233 | ||
234 | return item; | |
235 | } | |
236 | ||
237 | wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item) | |
238 | { | |
239 | if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos)) | |
240 | return item; | |
241 | else | |
242 | return NULL; | |
243 | } | |
244 | ||
245 | wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) | |
246 | { | |
247 | // we need to find the items position in the child list | |
248 | size_t pos; | |
249 | wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); | |
250 | for ( pos = 0; node; pos++ ) | |
251 | { | |
252 | if ( node->GetData() == item ) | |
253 | break; | |
254 | ||
255 | node = node->GetNext(); | |
256 | } | |
257 | ||
258 | // DoRemove() (unlike Remove) can only be called for existing item! | |
259 | wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") ); | |
260 | ||
261 | // remove the item from the menu | |
262 | wxMenuItem *ret=wxMenuBase::DoRemove(item); | |
263 | ||
264 | if ( IsAttached() && GetMenuBar()->IsAttached() ) | |
265 | { | |
266 | // Regenerate the menu resource | |
267 | GetMenuBar()->Refresh(); | |
268 | } | |
269 | ||
270 | return ret; | |
271 | } | |
272 | ||
273 | // --------------------------------------------------------------------------- | |
274 | // accelerator helpers | |
275 | // --------------------------------------------------------------------------- | |
276 | ||
277 | #if wxUSE_ACCEL | |
278 | ||
279 | // create the wxAcceleratorEntries for our accels and put them into provided | |
280 | // array - return the number of accels we have | |
281 | size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const | |
282 | { | |
283 | size_t count = GetAccelCount(); | |
284 | for ( size_t n = 0; n < count; n++ ) | |
285 | { | |
286 | *accels++ = *m_accels[n]; | |
287 | } | |
288 | ||
289 | return count; | |
290 | } | |
291 | ||
292 | #endif // wxUSE_ACCEL | |
293 | ||
294 | // --------------------------------------------------------------------------- | |
295 | // set wxMenu title | |
296 | // --------------------------------------------------------------------------- | |
297 | ||
298 | void wxMenu::SetTitle(const wxString& label) | |
299 | { | |
300 | m_title = label; | |
301 | ||
302 | if ( IsAttached() && GetMenuBar()->IsAttached() ) | |
303 | { | |
304 | // Regenerate the menu resource | |
305 | GetMenuBar()->Refresh(); | |
306 | } | |
307 | } | |
308 | ||
309 | // --------------------------------------------------------------------------- | |
310 | // event processing | |
311 | // --------------------------------------------------------------------------- | |
312 | ||
313 | bool wxMenu::PalmCommand(WXUINT WXUNUSED(param), WXWORD id) | |
314 | { | |
315 | return false; | |
316 | } | |
317 | ||
318 | // --------------------------------------------------------------------------- | |
319 | // other | |
320 | // --------------------------------------------------------------------------- | |
321 | ||
322 | wxWindow *wxMenu::GetWindow() const | |
323 | { | |
324 | return NULL; | |
325 | } | |
326 | ||
327 | // --------------------------------------------------------------------------- | |
328 | // Menu Bar | |
329 | // --------------------------------------------------------------------------- | |
330 | ||
331 | void wxMenuBar::Init() | |
332 | { | |
333 | } | |
334 | ||
335 | wxMenuBar::wxMenuBar() | |
336 | { | |
337 | } | |
338 | ||
339 | wxMenuBar::wxMenuBar( long WXUNUSED(style) ) | |
340 | { | |
341 | } | |
342 | ||
343 | wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[]) | |
344 | { | |
345 | } | |
346 | ||
347 | wxMenuBar::~wxMenuBar() | |
348 | { | |
349 | } | |
350 | ||
351 | // --------------------------------------------------------------------------- | |
352 | // wxMenuBar helpers | |
353 | // --------------------------------------------------------------------------- | |
354 | ||
355 | void wxMenuBar::Refresh() | |
356 | { | |
357 | wxCHECK_RET( IsAttached(), wxT("can't refresh unattached menubar") ); | |
358 | ||
359 | // Regenerate the menu resource | |
360 | LoadMenu(); | |
361 | } | |
362 | ||
363 | WXHMENU wxMenuBar::Create() | |
364 | { | |
365 | return NULL; | |
366 | } | |
367 | ||
368 | int wxMenuBar::PalmPositionForWxMenu(wxMenu *menu, int wxpos) | |
369 | { | |
370 | return -1; | |
371 | } | |
372 | ||
373 | // --------------------------------------------------------------------------- | |
374 | // wxMenuBar functions to work with the top level submenus | |
375 | // --------------------------------------------------------------------------- | |
376 | ||
377 | void wxMenuBar::EnableTop(size_t pos, bool enable) | |
378 | { | |
379 | // Palm OS does not have support for grayed or disabled items | |
380 | } | |
381 | ||
382 | void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) | |
383 | { | |
384 | wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") ); | |
385 | ||
386 | m_titles[pos]=wxStripMenuCodes(label); | |
387 | ||
388 | if ( !IsAttached() ) | |
389 | { | |
390 | return; | |
391 | } | |
392 | ||
393 | // Regenerate the menu resource | |
394 | Refresh(); | |
395 | } | |
396 | ||
397 | wxString wxMenuBar::GetLabelTop(size_t pos) const | |
398 | { | |
399 | wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString, | |
400 | wxT("invalid menu index in wxMenuBar::GetLabelTop") ); | |
401 | ||
402 | return wxMenuItem::GetLabelFromText(m_titles[pos]); | |
403 | } | |
404 | ||
405 | // --------------------------------------------------------------------------- | |
406 | // wxMenuBar construction | |
407 | // --------------------------------------------------------------------------- | |
408 | ||
409 | wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) | |
410 | { | |
411 | wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title); | |
412 | if ( !menuOld ) | |
413 | return NULL; | |
414 | ||
415 | m_titles[pos]=wxStripMenuCodes(title); | |
416 | ||
417 | if ( IsAttached() ) | |
418 | { | |
419 | // Regenerate the menu resource | |
420 | Refresh(); | |
421 | } | |
422 | ||
423 | return menuOld; | |
424 | } | |
425 | ||
426 | bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) | |
427 | { | |
428 | if ( !wxMenuBarBase::Insert(pos, menu, title) ) | |
429 | return FALSE; | |
430 | ||
431 | m_titles.Insert(wxStripMenuCodes(title), pos); | |
432 | ||
433 | if ( IsAttached() ) | |
434 | { | |
435 | // Regenerate the menu resource | |
436 | Refresh(); | |
437 | } | |
438 | ||
439 | return TRUE; | |
440 | } | |
441 | ||
442 | bool wxMenuBar::Append(wxMenu *menu, const wxString& title) | |
443 | { | |
444 | if ( !wxMenuBarBase::Append(menu, title) ) | |
445 | return FALSE; | |
446 | ||
447 | m_titles.Add(wxStripMenuCodes(title)); | |
448 | ||
449 | if(IsAttached()) | |
450 | { | |
451 | // Regenerate the menu resource | |
452 | Refresh(); | |
453 | } | |
454 | ||
455 | return TRUE; | |
456 | } | |
457 | ||
458 | wxMenu *wxMenuBar::Remove(size_t pos) | |
459 | { | |
460 | wxMenu *menu = wxMenuBarBase::Remove(pos); | |
461 | if ( !menu ) | |
462 | return NULL; | |
463 | ||
464 | m_titles.RemoveAt(pos); | |
465 | ||
466 | if (IsAttached()) | |
467 | { | |
468 | // Regenerate the menu resource | |
469 | Refresh(); | |
470 | } | |
471 | ||
472 | return menu; | |
473 | } | |
474 | ||
475 | #if wxUSE_ACCEL | |
476 | ||
477 | void wxMenuBar::RebuildAccelTable() | |
478 | { | |
479 | } | |
480 | ||
481 | #endif // wxUSE_ACCEL | |
482 | ||
483 | int wxMenuBar::ProcessCommand(int ItemID) | |
484 | { | |
485 | if(!IsAttached()) | |
486 | return -1; | |
487 | ||
488 | int MenuNum=(ItemID/1000)-1; | |
489 | int ItemNum=(ItemID-(1000*(MenuNum+1))); | |
490 | ||
491 | // Should never happen, but it doesn't hurt to check anyway. | |
492 | if(MenuNum>GetMenuCount()) | |
493 | return -1; | |
494 | ||
495 | // Get the menu | |
496 | wxMenu *ActiveMenu=GetMenu(MenuNum); | |
497 | ||
498 | // Make sure this is a valid item. | |
499 | if(ItemNum>ActiveMenu->GetMenuItemCount()) | |
500 | return -1; | |
501 | ||
502 | // Get the item | |
503 | wxMenuItem *ActiveItem=ActiveMenu->FindItemByPosition(ItemNum); | |
504 | int ActiveID=ActiveItem->GetId(); | |
505 | ||
506 | return ActiveID; | |
507 | } | |
508 | ||
509 | /* Palm OS does not have good dynamic menu support. About all you can do with | |
510 | * the standard API calls is to add new items to an existing drop-down menu and | |
511 | * hide/show items in a drop-down menu. It is impossible to add, hide, or | |
512 | * change the label on a drop-down menu. | |
513 | * | |
514 | * The easiest and simplest way around this limitation is to modify the Palm OS | |
515 | * MenuBarType structure directly. This gives limited ability to change the | |
516 | * label on a drop-down menu. I have not been able to find a safe way to add, | |
517 | * delete, or resize drop-down menus in OS 6. | |
518 | * | |
519 | * The following routine attempt to work around these limitations present in the | |
520 | * Palm OS API to provide limited dynamic menu support. This solution is far | |
521 | * from perfect, but the only other option is to wait for PalmSource to add full | |
522 | * dynamic menu support, or to recreate the Palm OS menu system from scratch. | |
523 | * | |
524 | * This system is limited in that no more than 4 drop-down menus are allowed per | |
525 | * menu bar, and the label for each drop-down menu is limited to 8 characters of | |
526 | * text. However, this menu system should work for most applications. | |
527 | * | |
528 | * Basically the menu routines select one of four menu bars, depending on | |
529 | * whether or not the requested menu bar has one, two, three, or four drop-down | |
530 | * menus. | |
531 | * | |
532 | * These four "template" menu bars contain one, two, three, or four drop-down | |
533 | * menus. Each menu has a dummy menu item attached to it to allow the Palm OS | |
534 | * MenuAddItem function to add the real items. | |
535 | * | |
536 | * The labels on the drop-down menus are then replaced with the labels of the | |
537 | * real menus. | |
538 | * | |
539 | * The menu is then attached to the active window and the MenuAddItem API | |
540 | * function is called to add the items to each drop-down menu. Finally, | |
541 | * MenuHideItem is called to remove the dummy items from each drop-down menu. | |
542 | */ | |
543 | void wxMenuBar::LoadMenu() | |
544 | { | |
545 | int i=0; | |
546 | int j=0; | |
547 | ||
548 | // Handle to the currently running application database | |
549 | DmOpenRef AppDB; | |
550 | ||
551 | // Get app database reference - needed for some Palm OS Menu API calls. | |
552 | SysGetModuleDatabase(SysGetRefNum(), NULL, &AppDB); | |
553 | ||
554 | // Get the number of menus | |
555 | int NumMenus=GetMenuCount(); | |
556 | ||
557 | // Set up the pointers and handles | |
558 | char *PalmOSMenuBarPtr; | |
559 | MemHandle PalmOSMenuBar; | |
560 | ||
561 | // Load the menu template and set up the menu pointers | |
562 | if(NumMenus==1) | |
563 | { | |
564 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',1000); | |
565 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
566 | ||
567 | PalmOSMenuBarPtr+=74; | |
568 | } | |
569 | else if(NumMenus==2) | |
570 | { | |
571 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',2000); | |
572 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
573 | ||
574 | PalmOSMenuBarPtr+=116; | |
575 | } | |
576 | else if(NumMenus==3) | |
577 | { | |
578 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',3000); | |
579 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
580 | ||
581 | PalmOSMenuBarPtr+=158; | |
582 | } | |
583 | else | |
584 | { | |
585 | // We support a maximum of 4 menus, so make sure that do not create | |
586 | // more than we can handle. | |
587 | NumMenus=4; | |
588 | ||
589 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',4000); | |
590 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
591 | ||
592 | PalmOSMenuBarPtr+=200; | |
593 | } | |
594 | ||
595 | // Set the proper names for the drop-down triggers. | |
596 | for(i=0;i<NumMenus;i++) | |
597 | { | |
598 | // Clear out the old label | |
599 | char buffer[8]={' ',' ',' ',' ',' ',' ',' ',' '}; | |
600 | MemMove(PalmOSMenuBarPtr,buffer,8); | |
601 | ||
602 | wxString MenuTitle=m_titles.Item(i); | |
603 | ||
604 | // Make sure we don't copy more than 8 bytes for the label | |
605 | int LengthToCopy=MenuTitle.length(); | |
606 | if(LengthToCopy>8) | |
607 | LengthToCopy=8; | |
608 | ||
609 | MemMove(PalmOSMenuBarPtr,MenuTitle,LengthToCopy); | |
610 | PalmOSMenuBarPtr+=11; | |
611 | } | |
612 | ||
613 | // We are done with the menu pointer. | |
614 | MemHandleUnlock(PalmOSMenuBar); | |
615 | DmReleaseResource(PalmOSMenuBar); | |
616 | ||
617 | // We must make the menu active before we can add items to the drop-down | |
618 | // triggers. | |
619 | FrmSetMenu(FrmGetActiveForm(),AppDB,NumMenus*1000); | |
620 | ||
621 | /* Add the menu items to the drop-down triggers. This must be done after | |
622 | * setting the triggers, because setting the names of drop-down triggers | |
623 | * that have a variable number of items requires carefull calculation of | |
624 | * the offsets in the MenuBarType structure. Setting the triggers first | |
625 | * avoids this. | |
626 | */ | |
627 | for(i=0;i<NumMenus;i++) | |
628 | { | |
629 | wxMenu *CurrentMenu=GetMenu(i); | |
630 | ||
631 | for(j=0;j<CurrentMenu->GetMenuItemCount();j++) | |
632 | { | |
633 | wxMenuItem *CurrentItem=CurrentMenu->FindItemByPosition(j); | |
634 | wxString ItemLabel=CurrentItem->GetLabel(); | |
635 | ||
636 | if(CurrentItem->IsSeparator()==true) | |
637 | { | |
638 | char Separator=MenuSeparatorChar; | |
639 | if(j==0) | |
640 | MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,&Separator); | |
641 | else | |
642 | MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,&Separator); | |
643 | } | |
644 | else | |
645 | { | |
646 | if(j==0) | |
647 | MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,ItemLabel); | |
648 | else | |
649 | MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,ItemLabel); | |
650 | } | |
651 | } | |
652 | ||
653 | // Hide the dummy menu item, since we don't need it anymore. | |
654 | MenuHideItem(9000+i); | |
655 | } | |
656 | } | |
657 | ||
658 | void wxMenuBar::Attach(wxFrame *frame) | |
659 | { | |
660 | wxMenuBarBase::Attach(frame); | |
661 | ||
662 | LoadMenu(); | |
663 | } | |
664 | ||
665 | #if defined(__WXWINCE__) && (_WIN32_WCE >= 400 && !defined(__POCKETPC__) && !defined(__SMARTPHONE__)) | |
666 | bool wxMenuBar::AddAdornments(long style) | |
667 | { | |
668 | return false; | |
669 | } | |
670 | #endif | |
671 | ||
672 | void wxMenuBar::Detach() | |
673 | { | |
674 | wxMenuBarBase::Detach(); | |
675 | } | |
676 | ||
677 | #endif // wxUSE_MENUS |