home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
srcos2
/
vmenu.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-11
|
11KB
|
318 lines
//===============================================================
// vMenu.cxx - vMenuPane class functions - X11R5
//
// Copyright (C) 1995,1996,1997,1998 Bruce E. Wampler
//
// This file is part of the V C++ GUI Framework, and is covered
// under the terms of the GNU Library General Public License,
// Version 2. This library has NO WARRANTY. See the source file
// vapp.cxx for more complete information about license terms.
//===============================================================
#include <v/vos2.h> // for OS/2 stuff
#include <v/vmenu.h> // our header
#include <v/vcmdwin.h> // we need access to vcmdwin
#include <stdlib.h>
// Define static data of the class
static char curLbl[100]; // for fixed labels
//==================>>> vMenuPane::vMenuPane <<<===========================
vMenuPane::vMenuPane(VCONST vMenu* menu) : vPane(P_Menu)
{
int i;
char *ch;
// set up menus -----------------------------------------------
SysDebug(Constructor,"vMenuPane::vMenuPane() constructor\n")
_nextMenuButton = 0; // no menus defined so far
for (i = 0 ; i < MAX_MENU_BUTTONS ; ++i)
{
_mb[i].label[0] = 0; // null out menu button array
_mb[i].menuId = 0;
_mb[i].SubMenu = 0;
_mb[i].hPullDown = 0;
}
// copy the menus as defined to our array
for (i = 0 ; i < MAX_MENU_BUTTONS && &menu[i] != 0 && menu[i].label; ++i)
{
// _mb[i].label = menu[i].label;
strcpy(_mb[i].label, menu[i].label);
_mb[i].menuId = menu[i].menuId;
_mb[i].SubMenu = menu[i].SubMenu;
// translate V '&' for OS/2 '~' in labels for menu accelerators
for (ch = _mb[i].label; *ch != 0; ch++)
{
if (*ch == '&')
*ch = '~';
}
}
_nextSubMenu = i; // we will start submenus here
_nextMenuButton = i; // this many menus defined
_topLevelMenu = 0;
}
//==================>>> vMenuPane::vMenuPane <<<===========================
vMenuPane::vMenuPane(const vMenuPane& m) : vPane(m)
{
vSysError("V Semantics do not allow copy constructors.");
}
//====================>>> vMenuPane::~vMenuPane <<<=======================
vMenuPane::~vMenuPane() // destructor
{
SysDebug(Destructor,"vMenuPane::~vMenuPane() destructor\n")
WinDestroyWindow(_topLevelMenu); // Start with the top
for (int i = _nextSubMenu - 1 ; i >= 0 ; --i) // all menus
{
WinDestroyWindow(_mb[i].hPullDown);
delete _mb[i].mInfo; // free the space
}
}
//======================>>> vMenuPane::initialize <<<=======================
void vMenuPane::initialize(vWindow* pWin, HWND hMenu)
{
vPane::initialize(pWin, hMenu); // initialize these
_topLevelMenu = (HWND)hMenu; // handle to menu bar
// Now we have to add our menus
for (int i = 0 ; i < _nextMenuButton ; ++i)
{
doAddMenu(i, _topLevelMenu);
}
// pWin->_WindowMenuIndex = _nextMenuButton - 1; // Window menu for MDI
}
//======================>>> vMenuPane::fixLabel <<<========================
void vMenuPane::fixLabel(VCONST char* lbl, VCONST char* key)
{
// copy label to global curLbl
VCONST char* cp;
int ix = 0;
for (cp = lbl ; *cp && ix < 99 ; ++cp) // Scan label
{
curLbl[ix++] = *cp;
}
if (key && *key)
{
curLbl[ix++] = ' '; curLbl[ix++] = ' '; curLbl[ix++] = '\t';
for (cp = key ; *cp && ix < 99 ; ++cp)
{
curLbl[ix++] = *cp;
}
}
curLbl[ix] = 0; // finish off
// translate V '&' for OS/2 '~' in labels for menu accelerators
char *ch;
for (ch = curLbl; *ch != 0; ch++)
{
if (*ch == '&')
*ch = '~';
}
}
//======================>>> vMenuPane::doAddMenu <<<========================
void vMenuPane::doAddMenu(int id, HWND parent)
{
MENUITEM mi;
// create a drop down window on the menu bar
_mb[id].hPullDown = WinCreateWindow (HWND_OBJECT, WC_MENU, NULL,
WS_CLIPSIBLINGS, 0, 0, 0, 0, HWND_OBJECT,
HWND_BOTTOM, _mb[id].menuId, NULL, NULL);
// loop through the list
_mb[id].mInfo = 0; // empty list so far
vMenu* item = _mb[id].SubMenu; // The first item in list
MenuInfo* info; // for current info
for (int ix = 0 ; item[ix].label != 0 ; ++ix)
{
info = new MenuInfo; // new space for current item
info->NxtInfo = _mb[id].mInfo; // add to front of list
_mb[id].mInfo = info; // fix front pointer
info->ItemIndex = ix; // index to item list
info->SubMenuIndex = 0; // no submenu normally
if (item[ix].menuId == M_Line)
{
mi.iPosition = MIT_END;
mi.afStyle = MIS_SEPARATOR;
mi.afAttribute = 0;
mi.id = 0;
mi.hwndSubMenu = NULLHANDLE;
mi.hItem = 0;
WinSendMsg (_mb[id].hPullDown, MM_INSERTITEM, (MPARAM) &mi, NULL);
}
else if (item[ix].SubMenu != 0) // a submenu
{
if(_nextSubMenu >= MAX_MENU_BUTTONS)
{
SysDebug(BadVals,"Too many submenus!\n");
continue;
}
// we will create a submenu
// copy the definitions, track the new index
int sub = _nextSubMenu++; // get our index, bump for next time
// _mb[sub].label = item[ix].label;
strcpy(_mb[sub].label, item[ix].label);
// translate V '&' for OS/2 '~' in labels for menu accelerators
char *ch;
for (ch = _mb[sub].label; *ch != 0; ch++)
{
if (*ch == '&')
*ch = '~';
}
_mb[sub].menuId = item[ix].menuId;
_mb[sub].SubMenu = item[ix].SubMenu;
info->SubMenuIndex = sub;
// Now, recursively call doAddMenu with the submenu
doAddMenu(sub, _mb[id].hPullDown);
}
else
{
// create the item
fixLabel(item[ix].label,item[ix].keyLabel);
mi.iPosition = MIT_END;
mi.afStyle = MIS_TEXT;
mi.afAttribute = 0;
mi.id = item[ix].menuId;
mi.hwndSubMenu = NULLHANDLE;
mi.hItem = 0;
WinSendMsg(_mb[id].hPullDown, MM_INSERTITEM,
(MPARAM) &mi, (MPARAM) curLbl);
WinCheckMenuItem(_mb[id].hPullDown,
item[ix].menuId,
(item[ix].checked ? TRUE : FALSE));
WinEnableMenuItem (_mb[id].hPullDown, item[ix].menuId,
item[ix].sensitive ? TRUE : FALSE);
}
}
mi.iPosition = MIT_END;
mi.afStyle = MIS_SUBMENU;
mi.afAttribute = 0;
mi.id = _mb[id].menuId;
mi.hwndSubMenu = _mb[id].hPullDown;
mi.hItem = 0;
WinSendMsg(parent, MM_INSERTITEM, (MPARAM) &mi, (MPARAM) _mb[id].label);
}
//====================>>> vMenuPane::CheckAccel <<<======================
int vMenuPane::CheckAccel(vKey vkey, unsigned int shift, ItemVal& id) VCONST
{
// scan all menus in this window to see if this keystroke
// matches an accelerator key
vMenu* item;
// Search all menus in this list
for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
{
MenuInfo* info; // for current info
// scan the list of info for each menu entry
for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
{
item = _mb[ix].SubMenu; // The current item in list
// see if its menuId is the same as the one we are setting
if (item[info->ItemIndex].accel == vkey
&& item[info->ItemIndex].kShift == shift)
{
id = item[info->ItemIndex].menuId;
return 1;
}
}
}
id = 0;
return 0; // assume 0 if not found
}
//====================>>> vMenuPane::GetPaneValue <<<======================
int vMenuPane::GetPaneValue(ItemVal id, int& val) VCONST
{
// scan all menus in this window to retrieve the what value
// then scan button bar if not found
vMenu* item;
// Search all menus in this list
for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
{
MenuInfo* info; // for current info
// scan the list of info for each menu entry
for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
{
item = _mb[ix].SubMenu; // The current item in list
// see if its menuId is the same as the one we are setting
if (item[info->ItemIndex].menuId == id)
{
// Ah Ha! We found the value we want
val = item[info->ItemIndex].checked;
return 1;
}
}
}
val = 0;
return 0; // assume 0 if not found
}
//==================>>> vMenuPane::SetPaneValue <<<========================
void vMenuPane::SetPaneValue(ItemVal id, int val, ItemSetType setType)
{
// Set the given item on or off
vMenu* item;
// Search all menus in this list
for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
{
MenuInfo* info; // for current info
// scan the list of info for each menu entry
for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
{
item = _mb[ix].SubMenu; // The current item in list
// see if its menuId is the same as the one we are setting
if (item[info->ItemIndex].menuId == id)
{
// Ah Ha! We found the value we want
switch (setType)
{
case Value: // check box
case Checked: // check box
{
item[info->ItemIndex].checked = val;
WinCheckMenuItem (_mb[ix].hPullDown,
item[info->ItemIndex].menuId,
val ? TRUE : FALSE);
break;
}
case Sensitive: // sensitive
{
item[info->ItemIndex].sensitive = val;
WinEnableMenuItem (_mb[ix].hPullDown,
item[info->ItemIndex].menuId,
val ? TRUE : FALSE);
break;
}
} // end switch
}
}
}
}
//================>>> vMenuPane::SetPaneString <<<========================
void vMenuPane::SetPaneString(ItemVal id, VCONST char* str)
{
// Set the given item on or off
vMenu* item;
// Search all menus in this window
for (int ix = 0 ; ix < _nextSubMenu ; ++ix)
{
MenuInfo* info; // for current info
// scan the list of info for each menu entry
for (info = _mb[ix].mInfo ; info != 0 ; info = info->NxtInfo)
{
item = _mb[ix].SubMenu; // The current item in list
if (item[info->ItemIndex].menuId == id)
{
// Ah Ha! We found the value we want
item[info->ItemIndex].label = str;
WinSetMenuItemText (_mb[ix].hPullDown, // the menu
item[info->ItemIndex].menuId, // same id
item[info->ItemIndex].label); // new label
WinSendMsg (theApp->_Frame, WM_UPDATEFRAME, MPFROMLONG(FCF_MENU), MPVOID);
}
}
}
}