OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
menu.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1991, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of classes TMenu and TXMenu, Window Menu encapsulation class
7/// and its associated exception
8//----------------------------------------------------------------------------
9#include <owl/pch.h>
10#include <owl/menu.h>
11#include <owl/module.h>
12
13#if defined(__BORLANDC__)
14# pragma option -w-ccc // Disable "Condition is always true/false"
15#endif
16
17using namespace std;
18
19namespace owl {
20
22DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlMenu, 1, 0); // diag. group for menus
23DIAG_DECLARE_GROUP(OwlWin); // diag. group for windows
24
25//
26//
27//
29{
30 memset(LPMENUITEMINFO(this), 0, sizeof(MENUITEMINFO));
31 cbSize = sizeof(MENUITEMINFO);
32 fMask = msk;
33}
34
35//
36//
37//
39{
40 PRECONDITION(menu.GetHandle());
41 memset(LPMENUITEMINFO(this), 0, sizeof(MENUITEMINFO));
42 cbSize = sizeof(MENUITEMINFO);
43 fMask = msk;
44 menu.GetMenuItemInfo(posOrId, isPos ? TRUE : FALSE, *this);
45}
46
47//
48//
49//
51 void* buffer, uint size, uint msk)
52{
53 PRECONDITION(menu.GetHandle());
54 memset(LPMENUITEMINFO(this), 0, sizeof(MENUITEMINFO));
55 cbSize = sizeof(MENUITEMINFO);
56 fMask = msk;
58 cch = size;
59 menu.GetMenuItemInfo(posOrId, isPos ? TRUE : FALSE, *this);
60}
61
62
63//
64/// Creates an empty menu and sets autoDelete, by default, so that the menu is
65/// automatically deleted when the object is destroyed.
66//
68:
69 Handle(::CreateMenu()),
70 ShouldDelete(autoDelete)
71{
72 WARNX(OwlMenu, !Handle, 0, "Cannot Create Menu");
73 CheckValid();
74}
75
76//
77/// Creates a deep copy of an existing menu and sets autoDelete, by default, so
78/// that the menu is automatically deleted when the object is destroyed.
79//
81:
82 Handle(::CreateMenu()),
83 ShouldDelete(autoDelete)
84{
85 WARNX(OwlMenu, !Handle, 0, "Cannot Create Menu for Copy");
86 CheckValid();
87 DeepCopy(*this, original);
88}
89
90//
91/// Creates a menu object from an already loaded menu and sets autoDelete, by
92/// default, so the menu is not automatically deleted when the object is destroyed.
93//
95:
96 Handle(handle),
97 ShouldDelete(autoDelete)
98{
99}
100
101//
102/// Creates a menu object representing the window's current menu and sets
103/// autoDelete, by default, so that the menu is not automatically deleted when the
104/// object is destroyed.
105//
107:
108 Handle(::GetMenu(hWnd)),
109 ShouldDelete(autoDelete)
110{
112 WARNX(OwlMenu, !Handle, 0, "Cannot Get Menu from " << static_cast<void*>(hWnd));
113 CheckValid();
114}
115
116//
117/// Creates a menu object from a menu template in memory. This constructor is not
118/// available under Presentation Manager.
119//
121{
124 WARNX(OwlMenu, !Handle, 0, "Cannot Load Menu Indirect " << menuTemplate);
125 CheckValid();
126 ShouldDelete = true;
127}
128
129//
130/// Creates a menu object from a specified resource ID.
131//
133{
135 Handle = ::LoadMenu(resInstance, resId);
136 WARNX(OwlMenu, !Handle, 0, "Cannot Load Menu " << static_cast<void*>(resInstance) << " " << resId);
137 CheckValid();
138 ShouldDelete = true;
139}
140
141//
142/// Copies an existing menu onto this menu, using DeepCopy.
143//
144TMenu&
146{
147 // Delete all items and submenus
148 // Look at possible alternatives for !ShouldDelete menus? Maybe use Remove
149 // then?
150 //
151 while (GetMenuItemCount())
153 DeepCopy(*this, original);
154 return *this;
155}
156
157//
158// Destruct the menu by destroying the handle if appropriate.
159//
161{
162 if (ShouldDelete && Handle)
163 ::DestroyMenu(Handle);
164}
165
166//
167/// Returns the ID of the menu item at the position specified by posItem.
168/// If it's a regular menu item just returns its id.
169/// If the menu is a pop-up menu, first attempt to retrieve a user-specified Id
170/// via the MENUITEMINFO structure. Otherwise, use the Id of
171/// first menuitem minus 1.
172//
173uint
175{
176 // Retrieve identifier
177 //
178 uint id = ::GetMenuItemID(Handle, pos);
179 if (id != uint(-1)) {
180 TRACEX(OwlWin, 1, "GetMenuItemID at pos. " << pos << '=' << id);
181 return id;
182 }
183
184// !JGD Popups don't have separators
185// ! // Skip separators
186// ! //
187// ! uint state = GetMenuState(pos, MF_BYPOSITION);
188// ! if (state & MF_SEPARATOR) {
189// ! TRACEX(OwlWin, 1, "MenuItem at " << pos << "is a separator, id=0");
190// ! return 0;
191// ! }
192
193 // Try to retrieve a pop-up menu handle
194 //
196 if (popup) {
198
199 // Here could try to retrieve the 'true' id of the popup if the user
200 // provided one before proceeding with the 'Id of firt Item -1' OWL
201 // enhancement. Need more information about MENUITEMINFO etc.
202 // !!
203
204 // Recurse within sub menu to retrieve popup Id.
205 //
206 id = subMenu.GetMenuItemID(0) - 1;
207 TRACEX(OwlWin, 1, "TMenu::GetMenuItemID - returns faked [Id of first "\
208 "menu item - 1, id=" << dec << id);
209 return id;
210 }
211 TRACEX(OwlWin, 1, "TMenu::GetMenuItemID - unable to determine id - "\
212 "returns 0");
213 return 0;
214}
215
216//
217/// For use with CopyText
218//
219
220struct TMenuGetMenuString
221{
222 const TMenu& menu;
223 uint item;
224 uint flags;
225 TMenuGetMenuString(const TMenu& m, uint i, uint f) : menu(m), item(i), flags(f) {}
226
227 int operator()(LPTSTR buf, int bufSize)
228 {return menu.GetMenuString(item, buf, bufSize, flags);}
229};
230
231//
232/// String-aware overload
233//
236{
237 int length = ::GetMenuString(GetHandle(), item, nullptr, 0, flags);
238 return CopyText(length, TMenuGetMenuString(*this, item, flags));
239}
240
241#if !defined(BI_COMP_GNUC)
242#pragma warn -par // resId param is never used in small model
243#endif
244//
245/// Throws a TXMenu exception if the menu object is invalid.
246//
247void
249{
250 if (!Handle)
252}
253#if !defined(BI_COMP_GNUC)
254#pragma warn .par
255#endif
256
257//
258/// MeasureItem is used by owner-drawn controls to store the dimensions of the
259/// specified item.
260//
261void
265
266//
267/// DrawItem responds to a message forwarded to a drawable control by TWindow when
268/// the control needs to be drawn.
269//
270void
274
275//
276//
277//
278uint
280{
281 PRECONDITION(Handle);
282 return ::GetMenuDefaultItem(Handle, getPos ? TRUE : FALSE, flags);
283}
284
285//
286//
287//
288bool
290{
291 PRECONDITION(Handle);
292 return ::SetMenuDefaultItem(Handle, posOrId, isPos ? TRUE : FALSE);
293}
294
295//
296//
297//
298bool
300{
301 PRECONDITION(Handle);
302 return ::CheckMenuRadioItem(Handle, first, last, check, flags) != FALSE;
303}
304
305//
306//
307//
308bool
310{
311 PRECONDITION(Handle);
312 return ::GetMenuItemInfo(Handle, posOrId, isPos ? TRUE : FALSE, &mi) != FALSE;
313}
314
315//
316//
317//
318bool
320{
321 PRECONDITION(Handle);
322 return ::SetMenuItemInfo(Handle, posOrId, isPos ? TRUE : FALSE, &mi) != FALSE;
323}
324
325//
326//
327//
328bool
330{
331 PRECONDITION(Handle);
332 return ::InsertMenuItem(Handle, posOrId, isPos ? TRUE : FALSE, &mi) != FALSE;
333}
334
335//
336/// \overload
337//
338void TMenu::DeepCopy(TMenu& dst, const TMenu& src, int srcOffset, int itemCount)
339{
340 DeepCopy(dst, dst.GetMenuItemCount(), src, srcOffset, itemCount);
341}
342
343//
344/// Copies menu items from the \p src menu to the \p dst menu.
345///
346/// If \p itemCount is negative (the default), all of the source menu items from \p srcOffset
347/// onward are copied.
348///
349/// \note The function isn't doing a truly deep copy. Only a recursive shallow copy is made of the
350/// menu items and submenus. In particular, a deep copy of bitmaps is *not* made. The function only
351/// copies the handles as part of the menu item structure, which means that bitmaps are in effect
352/// shared between the \p src and \p dst menus after the copy.
353//
354void TMenu::DeepCopy(TMenu& dst, int dstOffset, const TMenu& src, int srcOffset, int itemCount)
355{
356 PRECONDITION(src.Handle);
357 PRECONDITION(dst.Handle);
359
360 if (dstOffset < 0)
361 dstOffset = dst.GetMenuItemCount(); // Effectively, this means we will append items.
362
363 if (itemCount < 0)
364 itemCount = src.GetMenuItemCount() - srcOffset;
365
366 for (int i = 0; i < itemCount; i++)
367 {
368 const uint srcPos = srcOffset + i;
369 const uint dstPos = dstOffset + i;
370
371 uint state = src.GetMenuState(srcPos, MF_BYPOSITION);
372 if (state == static_cast<uint>(-1)) // Item does not exist?
373 return;
374
375 tchar str[256];
376 src.GetMenuString(srcPos, str, COUNTOF(str), MF_BYPOSITION);
377
378 if (state & MF_POPUP)
379 {
380 state &= (MF_STRING | MF_POPUP);
381 TMenu subMenu(src.GetSubMenu(srcPos));
384 dst.InsertMenu(dstPos, state | MF_BYPOSITION, newSubMenu, str);
385 }
386 else
387 {
388 // Get all the known information about the item, except the string, which we have already got.
389 //
391 const bool ok = src.GetMenuItemInfo(srcPos, true, info);
392 WARNX(OwlMenu, !ok, 0, _T("TMenu::DeepCopy: GetMenuItemInfo failed!"));
393 if (!ok) continue;
394 info.dwTypeData = str;
395 info.fMask |= MIIM_STRING;
396
397 dst.InsertMenuItem(dstPos, true, info);
398 }
399 }
400}
401
402//----------------------------------------------------------------------------
403
404//
405/// Constructs a system menu object. If revert is true, then the menu created is a
406/// default system menu. Otherwise, it is the menu currently in the window.
407//
408TSystemMenu::TSystemMenu(HWND hWnd, bool revert)
409:
410 TMenu(::GetSystemMenu(hWnd, revert), NoAutoDelete)
411{
412}
413
414//----------------------------------------------------------------------------
415
416//
417/// Constructs an empty pop-up menu.
418//
424
425//
426/// Creates a popup menu based on an existing popup menu.
427//
433
434//
435/// Creates a popup menu from an existing menu.
436//
438:
440{
441 DeepCopy(*this, menu);
442}
443
444//----------------------------------------------------------------------------
445
446//
447/// Constructs a TXMenu exception object with a default IDS_GDIFAILURE message.
448//
450:
451 TXOwl(resId)
452{
453}
454
455
456//
457/// Create a copy of the TXMenu exception.
458/// It will be rethrown at a safer time.
459//
460TXMenu*
462{
463 return new TXMenu(*this);
464}
465
466
467//
468/// Throws a TXMenu exception.
469//
470void
472{
473 throw *this;
474}
475
476//
477/// Creates a TXMenu exception and throws it.
478//
479void
481{
482 TXMenu(resId).Throw();
483}
484
485
486} // OWL namespace
487/* ========================================================================== */
488
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define PRECONDITION(condition)
Definition checks.h:227
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define TRACEX(group, level, message)
Definition checks.h:263
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
The TMenu class encapsulates window menus.
Definition menu.h:77
virtual void MeasureItem(MEASUREITEMSTRUCT &measureItem)
MeasureItem is used by owner-drawn controls to store the dimensions of the specified item.
Definition menu.cpp:262
uint GetMenuItemCount() const
Returns the number of items in a top-level or pop-up menu.
Definition menu.h:395
uint GetMenuItemID(int posItem) const
Returns the ID of the menu item at the position specified by posItem.
Definition menu.cpp:174
bool DeleteMenu(uint item, uint flags)
Removes the menu item (item) from the menu or deletes the menu item if it's a pop-up menu.
Definition menu.h:375
TMenu(TAutoDelete autoDelete=AutoDelete)
Creates an empty menu and sets autoDelete, by default, so that the menu is automatically deleted when...
Definition menu.cpp:67
bool SetDefaultItem(uint posOrId, bool isPos)
Definition menu.cpp:289
virtual void DrawItem(DRAWITEMSTRUCT &drawItem)
DrawItem responds to a message forwarded to a drawable control by TWindow when the control needs to b...
Definition menu.cpp:271
virtual ~TMenu()
Definition menu.cpp:160
HMENU GetSubMenu(int posItem) const
Returns the handle of the menu specified by posItem.
Definition menu.h:446
void CheckValid(uint redId=IDS_MENUFAILURE)
Throws a TXMenu exception if the menu object is invalid.
Definition menu.cpp:248
int GetMenuString(uint item, TCHAR *str, int count, uint flags) const
Returns the label (str) of the menu item (item).
Definition menu.h:438
bool SetMenuItemInfo(uint posOrId, bool isPos, TMenuItemInfo &mi)
Definition menu.cpp:319
bool GetMenuItemInfo(uint posOrId, bool isPos, TMenuItemInfo &mi) const
Definition menu.cpp:309
bool CheckRadioItem(uint first, uint last, uint check, uint flags)
Definition menu.cpp:299
uint GetDefaultItem(bool getPos, uint flags) const
Definition menu.cpp:279
static void DeepCopy(TMenu &dst, const TMenu &src, int srcOffset=0, int itemCount=-1)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition menu.cpp:338
TMenu & operator=(const TMenu &)
Copies an existing menu onto this menu, using DeepCopy.
Definition menu.cpp:145
virtual HMENU GetHandle() const
Returns the handle to the menu.
Definition menu.h:310
bool InsertMenuItem(uint posOrId, bool isPos, TMenuItemInfo &mi)
Definition menu.cpp:329
TMenuItemInfo(uint msk=0)
Definition menu.cpp:28
TPopupMenu(TAutoDelete autoDelete=AutoDelete)
Constructs an empty pop-up menu.
Definition menu.cpp:419
A nested class, TXMenu describes an exception that occurs when a menu item cannot be constructed.
Definition menu.h:160
void Throw()
Throws a TXMenu exception.
Definition menu.cpp:471
static void Raise(uint resId=IDS_MENUFAILURE)
Creates a TXMenu exception and throws it.
Definition menu.cpp:480
TXMenu(uint resId=IDS_MENUFAILURE)
Constructs a TXMenu exception object with a default IDS_GDIFAILURE message.
Definition menu.cpp:449
TXMenu * Clone()
Create a copy of the TXMenu exception.
Definition menu.cpp:461
TXOwl is root class of the ObjectWindows exception hierarchy.
Definition except.h:38
#define _T(x)
Definition cygwin.h:51
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition gdibase.h:70
@ NoAutoDelete
Definition gdibase.h:70
Definition of Window Menu encapsulation class.
Definition of class TModule.
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
tstring CopyText(int size, TGetText get_text)
Copies text from a C-string (null-terminated character array) into a string object,...
Definition defs.h:317
OWL_DIAGINFO
Definition animctrl.cpp:14
std::string tstring
Definition defs.h:79
unsigned int uint
Definition number.h:25
#define OWL_INI
Definition defs.h:170
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition defs.h:376