OWLNext
7.0
Borland's Object Windows Library for the modern age
Toggle main menu visibility
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
17
using namespace
std;
18
19
namespace
owl
{
20
21
OWL_DIAGINFO
;
22
DIAG_DEFINE_GROUP_INIT
(
OWL_INI
, OwlMenu, 1, 0);
// diag. group for menus
23
DIAG_DECLARE_GROUP
(OwlWin);
// diag. group for windows
24
25
//
26
//
27
//
28
TMenuItemInfo::TMenuItemInfo
(
uint
msk)
29
{
30
memset(LPMENUITEMINFO(
this
), 0,
sizeof
(MENUITEMINFO));
31
cbSize =
sizeof
(MENUITEMINFO);
32
fMask = msk;
33
}
34
35
//
36
//
37
//
38
TMenuItemInfo::TMenuItemInfo
(
TMenu
& menu,
uint
posOrId,
bool
isPos,
uint
msk)
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
//
50
TMenuItemInfo::TMenuItemInfo
(
TMenu
& menu,
uint
posOrId,
bool
isPos,
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;
57
dwTypeData = LPTSTR(buffer);
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
//
67
TMenu::TMenu
(
TAutoDelete
autoDelete)
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
//
80
TMenu::TMenu
(
const
TMenu
& original,
TAutoDelete
autoDelete)
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
//
94
TMenu::TMenu
(HMENU handle,
TAutoDelete
autoDelete)
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
//
106
TMenu::TMenu
(HWND hWnd,
TAutoDelete
autoDelete)
107
:
108
Handle(::GetMenu(hWnd)),
109
ShouldDelete(autoDelete)
110
{
111
PRECONDITION
(hWnd);
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
//
120
TMenu::TMenu
(
const
void
* menuTemplate)
121
{
122
PRECONDITION
(menuTemplate);
123
Handle = ::LoadMenuIndirect(menuTemplate);
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
//
132
TMenu::TMenu
(HINSTANCE resInstance,
TResId
resId)
133
{
134
PRECONDITION
(resInstance && resId);
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
//
144
TMenu
&
145
TMenu::operator =
(
const
TMenu
& original)
146
{
147
// Delete all items and submenus
148
// Look at possible alternatives for !ShouldDelete menus? Maybe use Remove
149
// then?
150
//
151
while
(
GetMenuItemCount
())
152
DeleteMenu
(0, MF_BYPOSITION);
153
DeepCopy
(*
this
, original);
154
return
*
this
;
155
}
156
157
//
158
// Destruct the menu by destroying the handle if appropriate.
159
//
160
TMenu::~TMenu
()
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
//
173
uint
174
TMenu::GetMenuItemID
(
int
pos)
const
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
//
195
HMENU popup =
GetSubMenu
(pos);
196
if
(popup) {
197
TMenu
subMenu(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
220
struct
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
//
234
tstring
235
TMenu::GetMenuString
(
uint
item,
uint
flags)
const
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
//
247
void
248
TMenu::CheckValid
(
uint
resId)
249
{
250
if
(!Handle)
251
TXMenu::Raise
(resId);
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
//
261
void
262
TMenu::MeasureItem
(MEASUREITEMSTRUCT &)
263
{
264
}
265
266
//
267
/// DrawItem responds to a message forwarded to a drawable control by TWindow when
268
/// the control needs to be drawn.
269
//
270
void
271
TMenu::DrawItem
(DRAWITEMSTRUCT &)
272
{
273
}
274
275
//
276
//
277
//
278
uint
279
TMenu::GetDefaultItem
(
bool
getPos,
uint
flags)
const
280
{
281
PRECONDITION
(Handle);
282
return ::GetMenuDefaultItem(Handle, getPos ? TRUE : FALSE, flags);
283
}
284
285
//
286
//
287
//
288
bool
289
TMenu::SetDefaultItem
(
uint
posOrId,
bool
isPos)
290
{
291
PRECONDITION
(Handle);
292
return ::SetMenuDefaultItem(Handle, posOrId, isPos ? TRUE : FALSE);
293
}
294
295
//
296
//
297
//
298
bool
299
TMenu::CheckRadioItem
(
uint
first,
uint
last,
uint
check,
uint
flags)
300
{
301
PRECONDITION
(Handle);
302
return ::CheckMenuRadioItem(Handle, first, last, check, flags) != FALSE;
303
}
304
305
//
306
//
307
//
308
bool
309
TMenu::GetMenuItemInfo
(
uint
posOrId,
bool
isPos,
TMenuItemInfo
& mi)
const
310
{
311
PRECONDITION
(Handle);
312
return ::GetMenuItemInfo(Handle, posOrId, isPos ? TRUE : FALSE, &mi) != FALSE;
313
}
314
315
//
316
//
317
//
318
bool
319
TMenu::SetMenuItemInfo
(
uint
posOrId,
bool
isPos,
TMenuItemInfo
& mi)
320
{
321
PRECONDITION
(Handle);
322
return ::SetMenuItemInfo(Handle, posOrId, isPos ? TRUE : FALSE, &mi) != FALSE;
323
}
324
325
//
326
//
327
//
328
bool
329
TMenu::InsertMenuItem
(
uint
posOrId,
bool
isPos,
TMenuItemInfo
& mi)
330
{
331
PRECONDITION
(Handle);
332
return ::InsertMenuItem(Handle, posOrId, isPos ? TRUE : FALSE, &mi) != FALSE;
333
}
334
335
//
336
/// \overload
337
//
338
void
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
//
354
void
TMenu::DeepCopy
(
TMenu
& dst,
int
dstOffset,
const
TMenu
& src,
int
srcOffset,
int
itemCount)
355
{
356
PRECONDITION
(src.Handle);
357
PRECONDITION
(dst.Handle);
358
PRECONDITION
(srcOffset >= 0);
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));
382
TMenu
newSubMenu(
NoAutoDelete
);
383
DeepCopy
(newSubMenu, subMenu);
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
//
390
TMenuItemInfo
info(MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_BITMAP | MIIM_FTYPE);
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
//
408
TSystemMenu::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
//
419
TPopupMenu::TPopupMenu
(
TAutoDelete
autoDelete)
420
:
421
TMenu
(::CreatePopupMenu(), autoDelete)
422
{
423
}
424
425
//
426
/// Creates a popup menu based on an existing popup menu.
427
//
428
TPopupMenu::TPopupMenu
(HMENU handle,
TAutoDelete
autoDelete)
429
:
430
TMenu
(handle, autoDelete)
431
{
432
}
433
434
//
435
/// Creates a popup menu from an existing menu.
436
//
437
TPopupMenu::TPopupMenu
(
const
TMenu
& menu,
TAutoDelete
autoDelete)
438
:
439
TMenu
(::CreatePopupMenu(), autoDelete)
440
{
441
DeepCopy
(*
this
, menu);
442
}
443
444
//----------------------------------------------------------------------------
445
446
//
447
/// Constructs a TXMenu exception object with a default IDS_GDIFAILURE message.
448
//
449
TXMenu::TXMenu
(
uint
resId)
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
//
460
TXMenu
*
461
TXMenu::Clone
()
462
{
463
return
new
TXMenu
(*
this
);
464
}
465
466
467
//
468
/// Throws a TXMenu exception.
469
//
470
void
471
TXMenu::Throw
()
472
{
473
throw
*
this
;
474
}
475
476
//
477
/// Creates a TXMenu exception and throws it.
478
//
479
void
480
TXMenu::Raise
(
uint
resId)
481
{
482
TXMenu
(resId).Throw();
483
}
484
485
486
}
// OWL namespace
487
/* ========================================================================== */
488
WARNX
#define WARNX(group, condition, level, message)
Definition
checks.h:277
PRECONDITION
#define PRECONDITION(condition)
Definition
checks.h:227
TRACEX
#define TRACEX(group, level, message)
Definition
checks.h:263
owl::TMenu
The TMenu class encapsulates window menus.
Definition
menu.h:77
owl::TMenu::MeasureItem
virtual void MeasureItem(MEASUREITEMSTRUCT &measureItem)
MeasureItem is used by owner-drawn controls to store the dimensions of the specified item.
Definition
menu.cpp:262
owl::TMenu::GetMenuItemCount
uint GetMenuItemCount() const
Returns the number of items in a top-level or pop-up menu.
Definition
menu.h:395
owl::TMenu::GetMenuItemID
uint GetMenuItemID(int posItem) const
Returns the ID of the menu item at the position specified by posItem.
Definition
menu.cpp:174
owl::TMenu::InsertMenu
bool InsertMenu(uint item, uint flags, TMenuItem newItem=-1, LPCTSTR newStr=nullptr)
Inserts a new text menu item or pop-up menu into the menu after the menu item specified in item.
Definition
menu.h:458
owl::TMenu::DeleteMenu
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
owl::TMenu::TMenu
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
owl::TMenu::SetDefaultItem
bool SetDefaultItem(uint posOrId, bool isPos)
Definition
menu.cpp:289
owl::TMenu::DrawItem
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
owl::TMenu::GetMenuState
uint GetMenuState(uint item, uint flags) const
Returns the menu flags for the menu item specified by item.
Definition
menu.h:430
owl::TMenu::~TMenu
virtual ~TMenu()
Definition
menu.cpp:160
owl::TMenu::GetSubMenu
HMENU GetSubMenu(int posItem) const
Returns the handle of the menu specified by posItem.
Definition
menu.h:446
owl::TMenu::CheckValid
void CheckValid(uint redId=IDS_MENUFAILURE)
Throws a TXMenu exception if the menu object is invalid.
Definition
menu.cpp:248
owl::TMenu::GetMenuString
int GetMenuString(uint item, TCHAR *str, int count, uint flags) const
Returns the label (str) of the menu item (item).
Definition
menu.h:438
owl::TMenu::SetMenuItemInfo
bool SetMenuItemInfo(uint posOrId, bool isPos, TMenuItemInfo &mi)
Definition
menu.cpp:319
owl::TMenu::GetMenuItemInfo
bool GetMenuItemInfo(uint posOrId, bool isPos, TMenuItemInfo &mi) const
Definition
menu.cpp:309
owl::TMenu::CheckRadioItem
bool CheckRadioItem(uint first, uint last, uint check, uint flags)
Definition
menu.cpp:299
owl::TMenu::GetDefaultItem
uint GetDefaultItem(bool getPos, uint flags) const
Definition
menu.cpp:279
owl::TMenu::DeepCopy
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
owl::TMenu::operator=
TMenu & operator=(const TMenu &)
Copies an existing menu onto this menu, using DeepCopy.
Definition
menu.cpp:145
owl::TMenu::GetHandle
virtual HMENU GetHandle() const
Returns the handle to the menu.
Definition
menu.h:310
owl::TMenu::InsertMenuItem
bool InsertMenuItem(uint posOrId, bool isPos, TMenuItemInfo &mi)
Definition
menu.cpp:329
owl::TMenuItemInfo
Definition
menu.h:46
owl::TMenuItemInfo::TMenuItemInfo
TMenuItemInfo(uint msk=0)
Definition
menu.cpp:28
owl::TPopupMenu::TPopupMenu
TPopupMenu(TAutoDelete autoDelete=AutoDelete)
Constructs an empty pop-up menu.
Definition
menu.cpp:419
owl::TResId
Definition
wsyscls.h:206
owl::TSystemMenu::TSystemMenu
TSystemMenu(HWND wnd, bool revert=false)
Constructs a system menu object.
Definition
menu.cpp:408
owl::TXMenu
A nested class, TXMenu describes an exception that occurs when a menu item cannot be constructed.
Definition
menu.h:160
owl::TXMenu::Throw
void Throw()
Throws a TXMenu exception.
Definition
menu.cpp:471
owl::TXMenu::Raise
static void Raise(uint resId=IDS_MENUFAILURE)
Creates a TXMenu exception and throws it.
Definition
menu.cpp:480
owl::TXMenu::TXMenu
TXMenu(uint resId=IDS_MENUFAILURE)
Constructs a TXMenu exception object with a default IDS_GDIFAILURE message.
Definition
menu.cpp:449
owl::TXMenu::Clone
TXMenu * Clone()
Create a copy of the TXMenu exception.
Definition
menu.cpp:461
_T
#define _T(x)
Definition
cygwin.h:51
owl::TAutoDelete
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition
gdibase.h:70
owl::NoAutoDelete
@ NoAutoDelete
Definition
gdibase.h:70
owl::TXOwl::TXOwl
TXOwl(const tstring &msg, uint resId=0)
An OWL exception with a given message for displaying and an unsigned Id that can be used for identifi...
Definition
except.cpp:123
pch.h
menu.h
Definition of Window Menu encapsulation class.
module.h
Definition of class TModule.
owl
Object Windows Library (OWLNext Core).
Definition
animctrl.h:22
owl::tchar
char tchar
Definition
defs.h:77
owl::CopyText
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::OWL_DIAGINFO
OWL_DIAGINFO
Definition
animctrl.cpp:14
owl::tstring
std::string tstring
Definition
defs.h:79
owl::uint
unsigned int uint
Definition
number.h:25
owl::DIAG_DEFINE_GROUP_INIT
DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlApp, 1, 0)
owl::DIAG_DECLARE_GROUP
DIAG_DECLARE_GROUP(OwlThread)
OWL_INI
#define OWL_INI
Definition
defs.h:170
COUNTOF
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition
defs.h:376
source
owlcore
menu.cpp
Generated by
1.18.0