OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
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