menu.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/msw/menu.h
  3. // Purpose: wxMenu, wxMenuBar classes
  4. // Author: Julian Smart
  5. // Modified by: Vadim Zeitlin (wxMenuItem is now in separate file)
  6. // Created: 01/02/97
  7. // Copyright: (c) Julian Smart
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. #ifndef _WX_MENU_H_
  11. #define _WX_MENU_H_
  12. #if wxUSE_ACCEL
  13. #include "wx/accel.h"
  14. #include "wx/dynarray.h"
  15. WX_DEFINE_EXPORTED_ARRAY_PTR(wxAcceleratorEntry *, wxAcceleratorArray);
  16. #endif // wxUSE_ACCEL
  17. class WXDLLIMPEXP_FWD_CORE wxFrame;
  18. #if defined(__WXWINCE__) && wxUSE_TOOLBAR
  19. class WXDLLIMPEXP_FWD_CORE wxToolBar;
  20. #endif
  21. class wxMenuRadioItemsData;
  22. // Not using a combined wxToolBar/wxMenuBar? then use
  23. // a commandbar in WinCE .NET to implement the
  24. // menubar, since there is no ::SetMenu function.
  25. #if defined(__WXWINCE__)
  26. # if ((_WIN32_WCE >= 400) && !defined(__POCKETPC__) && !defined(__SMARTPHONE__)) || \
  27. defined(__HANDHELDPC__)
  28. # define WINCE_WITH_COMMANDBAR
  29. # else
  30. # define WINCE_WITHOUT_COMMANDBAR
  31. # endif
  32. #endif
  33. #include "wx/arrstr.h"
  34. // ----------------------------------------------------------------------------
  35. // Menu
  36. // ----------------------------------------------------------------------------
  37. class WXDLLIMPEXP_CORE wxMenu : public wxMenuBase
  38. {
  39. public:
  40. // ctors & dtor
  41. wxMenu(const wxString& title, long style = 0)
  42. : wxMenuBase(title, style) { Init(); }
  43. wxMenu(long style = 0) : wxMenuBase(style) { Init(); }
  44. virtual ~wxMenu();
  45. virtual void Break();
  46. virtual void SetTitle(const wxString& title);
  47. // MSW-only methods
  48. // ----------------
  49. // Create a new menu from the given native HMENU. Takes ownership of the
  50. // menu handle and will delete it when this object is destroyed.
  51. static wxMenu *MSWNewFromHMENU(WXHMENU hMenu) { return new wxMenu(hMenu); }
  52. #if wxABI_VERSION >= 30002
  53. // Detaches HMENU so that it isn't deleted when this object is destroyed.
  54. // Don't use this object after calling this method.
  55. WXHMENU MSWDetachHMENU() { WXHMENU m = m_hMenu; m_hMenu = NULL; return m; }
  56. #endif
  57. // implementation only from now on
  58. // -------------------------------
  59. bool MSWCommand(WXUINT param, WXWORD id);
  60. // get the native menu handle
  61. WXHMENU GetHMenu() const { return m_hMenu; }
  62. // Return the start and end position of the radio group to which the item
  63. // at the given position belongs. Returns false if there is no radio group
  64. // containing this position.
  65. bool MSWGetRadioGroupRange(int pos, int *start, int *end) const;
  66. #if wxUSE_ACCEL
  67. // called by wxMenuBar to build its accel table from the accels of all menus
  68. bool HasAccels() const { return !m_accels.empty(); }
  69. size_t GetAccelCount() const { return m_accels.size(); }
  70. size_t CopyAccels(wxAcceleratorEntry *accels) const;
  71. // called by wxMenuItem when its accels changes
  72. void UpdateAccel(wxMenuItem *item);
  73. // helper used by wxMenu itself (returns the index in m_accels)
  74. int FindAccel(int id) const;
  75. // used only by wxMDIParentFrame currently but could be useful elsewhere:
  76. // returns a new accelerator table with accelerators for just this menu
  77. // (shouldn't be called if we don't have any accelerators)
  78. wxAcceleratorTable *CreateAccelTable() const;
  79. #endif // wxUSE_ACCEL
  80. #if wxUSE_OWNER_DRAWN
  81. int GetMaxAccelWidth()
  82. {
  83. if (m_maxAccelWidth == -1)
  84. CalculateMaxAccelWidth();
  85. return m_maxAccelWidth;
  86. }
  87. void ResetMaxAccelWidth()
  88. {
  89. m_maxAccelWidth = -1;
  90. }
  91. // get the menu with given handle (recursively)
  92. wxMenu* MSWGetMenu(WXHMENU hMenu);
  93. private:
  94. void CalculateMaxAccelWidth();
  95. #endif // wxUSE_OWNER_DRAWN
  96. protected:
  97. virtual wxMenuItem* DoAppend(wxMenuItem *item);
  98. virtual wxMenuItem* DoInsert(size_t pos, wxMenuItem *item);
  99. virtual wxMenuItem* DoRemove(wxMenuItem *item);
  100. private:
  101. // This constructor is private, use MSWNewFromHMENU() to use it.
  102. wxMenu(WXHMENU hMenu);
  103. // Common part of all ctors, it doesn't create a new HMENU.
  104. void InitNoCreate();
  105. // Common part of all ctors except of the one above taking a native menu
  106. // handler: calls InitNoCreate() and also creates a new menu.
  107. void Init();
  108. // common part of Append/Insert (behaves as Append is pos == (size_t)-1)
  109. bool DoInsertOrAppend(wxMenuItem *item, size_t pos = (size_t)-1);
  110. // This variable contains the description of the radio item groups and
  111. // allows to find whether an item at the given position is part of the
  112. // group and also where its group starts and ends.
  113. //
  114. // It is initially NULL and only allocated if we have any radio items.
  115. wxMenuRadioItemsData *m_radioData;
  116. // if true, insert a breal before appending the next item
  117. bool m_doBreak;
  118. // the menu handle of this menu
  119. WXHMENU m_hMenu;
  120. #if wxUSE_ACCEL
  121. // the accelerators for our menu items
  122. wxAcceleratorArray m_accels;
  123. #endif // wxUSE_ACCEL
  124. #if wxUSE_OWNER_DRAWN
  125. // true if the menu has any ownerdrawn items
  126. bool m_ownerDrawn;
  127. // the max width of menu items bitmaps
  128. int m_maxBitmapWidth;
  129. // the max width of menu items accels
  130. int m_maxAccelWidth;
  131. #endif // wxUSE_OWNER_DRAWN
  132. DECLARE_DYNAMIC_CLASS_NO_COPY(wxMenu)
  133. };
  134. // ----------------------------------------------------------------------------
  135. // Menu Bar (a la Windows)
  136. // ----------------------------------------------------------------------------
  137. class WXDLLIMPEXP_CORE wxMenuBar : public wxMenuBarBase
  138. {
  139. public:
  140. // ctors & dtor
  141. // default constructor
  142. wxMenuBar();
  143. // unused under MSW
  144. wxMenuBar(long style);
  145. // menubar takes ownership of the menus arrays but copies the titles
  146. wxMenuBar(size_t n, wxMenu *menus[], const wxString titles[], long style = 0);
  147. virtual ~wxMenuBar();
  148. // menubar construction
  149. virtual bool Append( wxMenu *menu, const wxString &title );
  150. virtual bool Insert(size_t pos, wxMenu *menu, const wxString& title);
  151. virtual wxMenu *Replace(size_t pos, wxMenu *menu, const wxString& title);
  152. virtual wxMenu *Remove(size_t pos);
  153. virtual void EnableTop( size_t pos, bool flag );
  154. virtual bool IsEnabledTop(size_t pos) const;
  155. virtual void SetMenuLabel( size_t pos, const wxString& label );
  156. virtual wxString GetMenuLabel( size_t pos ) const;
  157. // implementation from now on
  158. WXHMENU Create();
  159. virtual void Detach();
  160. virtual void Attach(wxFrame *frame);
  161. #if defined(__WXWINCE__) && wxUSE_TOOLBAR
  162. // Under WinCE, a menubar is owned by the frame's toolbar
  163. void SetToolBar(wxToolBar* toolBar) { m_toolBar = toolBar; }
  164. wxToolBar* GetToolBar() const { return m_toolBar; }
  165. #endif
  166. #ifdef WINCE_WITH_COMMANDBAR
  167. WXHWND GetCommandBar() const { return m_commandBar; }
  168. bool AddAdornments(long style);
  169. #endif
  170. #if wxUSE_ACCEL
  171. // update the accel table (must be called after adding/deleting a menu)
  172. void RebuildAccelTable();
  173. #endif // wxUSE_ACCEL
  174. // get the menu handle
  175. WXHMENU GetHMenu() const { return m_hMenu; }
  176. // if the menubar is modified, the display is not updated automatically,
  177. // call this function to update it (m_menuBarFrame should be !NULL)
  178. void Refresh();
  179. // To avoid compile warning
  180. void Refresh( bool eraseBackground,
  181. const wxRect *rect = (const wxRect *) NULL ) { wxWindow::Refresh(eraseBackground, rect); }
  182. // get the menu with given handle (recursively)
  183. wxMenu* MSWGetMenu(WXHMENU hMenu);
  184. protected:
  185. // common part of all ctors
  186. void Init();
  187. WXHMENU m_hMenu;
  188. // Return the MSW position for a wxMenu which is sometimes different from
  189. // the wxWidgets position.
  190. int MSWPositionForWxMenu(wxMenu *menu, int wxpos);
  191. #if defined(__WXWINCE__) && wxUSE_TOOLBAR
  192. wxToolBar* m_toolBar;
  193. #endif
  194. #ifdef WINCE_WITH_COMMANDBAR
  195. WXHWND m_commandBar;
  196. bool m_adornmentsAdded;
  197. #endif
  198. private:
  199. DECLARE_DYNAMIC_CLASS_NO_COPY(wxMenuBar)
  200. };
  201. #endif // _WX_MENU_H_