home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
srcos2
/
vcmdpane.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-03
|
21KB
|
593 lines
//===============================================================
// vCommandPane - the command bar pane class used by the vWindow class
//
// 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/vcmdpane.h>
#include <v/vwindow.h> // we are part of a window
#include <v/vthislst.h> // For this list
// Define static data of the class
MRESULT EXPENTRY CPProcCB(HWND hDlg, ULONG uMsg, MPARAM mp1, MPARAM mp2);
static vThisList _thisList; // hide this in this file
//===================>>> vCommandPane::vCommandPane <<<====================
vCommandPane::vCommandPane(CommandObject* cList) :
vPane(P_Commands), vCmdParent(P_Commands)
{
SysDebug(Constructor,"vCommandPane::vCommandPane() constructor\n")
_origList = cList; // handle to list of commands
_dialogType = aCmdBar; // this is a command pane
_isDisplayed = 1; // Command bars visible by default
_cmdObj = 0; // no list
_cmdObjCount = 0;
_TextInActive = 0;
}
//===================>>> vCommandPane::vCommandPane <<<====================
// Constructor for vStatus type status bars
// the list of elements are assumed to be just text labels
// implemented here as vBoxedLabels
vCommandPane::vCommandPane(vStatus* s_bar) :
vPane(P_Status), vCmdParent(P_Status)
{
_dialogType = aStatBar; // this is really a command pane
_isDisplayed = 1; // Status bars visible by default
char* cp;
SysDebug(Constructor,"vStatusPane::vStatusPane() constructor\n")
// get number of objects in pane
for (_cmdObjCount = 1; s_bar[_cmdObjCount].label; ++_cmdObjCount);
_cmdObj = new CommandObject[_cmdObjCount+1];
for (int ix = 0; ix <= _cmdObjCount; ++ix)
{
if (!s_bar[ix].label) // end of list
{
_cmdObj[ix].cmdType = C_EndOfList;
_cmdObj[ix].title = 0;
break;
}
_cmdObj[ix].cmdType = C_BoxedLabel;
_cmdObj[ix].cmdId = s_bar[ix].statId;
_cmdObj[ix].Sensitive = s_bar[ix].sensitive;
_cmdObj[ix].retVal = 0;
cp = new char[strlen(s_bar[ix].label)+1]; // copy string
strcpy(cp, s_bar[ix].label);
_cmdObj[ix].title = cp;
_cmdObj[ix].itemList = 0;
_cmdObj[ix].attrs = s_bar[ix].attrs;
_cmdObj[ix].cFrame = 0;
_cmdObj[ix].cRightOf = 0;
_cmdObj[ix].cBelow = 0;
_cmdObj[ix].size = s_bar[ix].width;
_cmdObj[ix].tip = 0;
}
_origList = _cmdObj; // handle to list of commands
}
//===================>>> vCommandPane::~vCommandPane <<<====================
vCommandPane::~vCommandPane()
{
SysDebug(Destructor,"vCommandPane::~vCommandPane() destructor\n")
// theApp->unregisterCmdPane(this);
_parentWin->unregisterCmdPane(this); // vWindow is tracking pane
if (_hTemplate !=0)
{
DosFreeMem(_hTemplate);
_hTemplate = 0;
}
if (_cmdObj != 0)
{
for (int ix = 0 ; ix < _cmdObjCount ; ++ix)
{
if (_cmdObj[ix].title)
delete [] _cmdObj[ix].title; // free strings
}
delete [] _cmdObj; // free list
}
_thisList.Delete((ThisId)_barHwnd); // free the this ptr
}
//==================>>> vCommandPane::ProcessCmd <<<=======================
void vCommandPane::ProcessCmd(ItemVal id, ItemVal rv, CmdType ct)
{
// simple interface between command objects and the
// inherited vCmdParent ProcessCmd to the CommandObject which does the work
_parentWin->WindowCommand(id, rv, ct);
}
//====================>>> vCommandPane::GetPaneValue <<<======================
int vCommandPane::GetPaneValue(ItemVal id, int& val) VCONST
{
if (HasId(id)) // make sure the id is in the pane
{
val = GetValue(id);
return 1; // assume 0 if not found
}
else
return 0; // can't find this id
}
//===================>>> vCommandPane::SetPaneValue <<<========================
void vCommandPane::SetPaneValue(ItemVal id, int val, ItemSetType setType)
{
SetValue(id,val,setType);
}
//====================>>> vCommandPane::SetPaneString <<<======================
void vCommandPane::SetPaneString(ItemVal id, VCONST char* str)
{
SetString(id,str);
}
//====================>>> vCommandPane::ShowPane <<<======================
void vCommandPane::ShowPane(int OnOrOff) VCONST
{
if (OnOrOff != _isDisplayed) // only need to do something if changed
{
_isDisplayed = OnOrOff;
if (_isDisplayed)
{
WinShowWindow (_barHwnd, TRUE);
_parentWin->_numPanes++;
}
else
{
WinShowWindow (_barHwnd, FALSE);
_parentWin->_numPanes--;
}
_parentWin->AdjustSize(this);
}
}
//====================>>> vCommandPane::initialize <<<=======================
void vCommandPane::initialize(vWindow* pWin, HWND hOwner)
{
// now, build the menu items in the widget provided
DlgCmdList* curCmd;
vPane::initialize(pWin, hOwner); // initialize base class
_hOwner = hOwner;
// Now, build the initial in-memory dialog template using
// OS/2 Dialog template handle _hTemplate.
// Using 8,helv makes it ok to use 8 in calculating control sizes!
PPElement PPel[] = { {PP_FONTNAMESIZE,(ULONG) "8.Helv"}, {0}};
// int buildOK = CreateDlgTemplate(FCF_NOBYTEALIGN, WS_VISIBLE | WS_CLIPSIBLINGS,
int buildOK = CreateDlgTemplate(FCF_NOBYTEALIGN, WS_CLIPSIBLINGS,
0,0, 0,0, 0, "", "", "", AssyPresParams(PPel) );
if (!buildOK)
vSysError("vDialog - Unable to build dialog template");
int ix;
// Add each control to the template via AddCmd
for (ix = 0 ; _origList && (_origList[ix].cmdType != C_EndOfList) ; ++ix)
{
curCmd = new DlgCmdList; // get a new cell
curCmd->nextDCL = _cmdList; // add in at front
_cmdList = curCmd;
curCmd->cmdP = 0; // not added yet
curCmd->cmdP = AddCmd(&_origList[ix]);
}
DoneAddingControls(); // All finished adding controls
// Now ready to create the dialog
_barHwnd = WinCreateDlg(WinQueryWindow(hOwner, QW_PARENT), hOwner,
(PFNWP) &CPProcCB, _hTemplate, (PVOID) this);
SysDebug2(OS2Dev,"vCommandPane::initialize hOwner:%u _barHwnd:%u \n", hOwner, _barHwnd)
if( _barHwnd)
{
_wDialog = _barHwnd;
pWin->registerCmdPane(this); // if created ok, then register with vWindow
pWin->AdjustSize(this); // resize the frame to accomodate pane
}
DosFreeMem(_hTemplate);
_hTemplate = 0;
}
// ---------------------------------------------------------------------
//====================>>> DlgProc <<<=======================
MRESULT EXPENTRY CPProcCB(HWND hDlg, ULONG uMsg,
MPARAM mp1, MPARAM mp2)
{
vCommandPane* useThis;
if (uMsg == WM_INITDLG) // first time!
{
useThis = (vCommandPane*)mp2;
_thisList.Add((ThisId)hDlg, (void*)useThis);
}
else
useThis = (vCommandPane*)_thisList.GetThis((ThisId)hDlg);
if (!useThis)
return WinDefDlgProc(hDlg, uMsg, mp1, mp2);
return (MRESULT) useThis->DynamicDlgProc(hDlg, uMsg, mp1, mp2);
}
//====================>>> vCommandPane::OnInitDialog <<<==================
int vCommandPane::OnInitDialog(HWND hwnd, MPARAM mp1, MPARAM mp2)
{
// Changes here must have equivlalents in the vDialog.cpp code
for (DlgCmdList* cc = _cmdList ; cc != 0 ; cc = cc->nextDCL)
{
vCmd* cp = cc->cmdP;
// BEW - V 1.17 - Shouldn't have to do this, but the dynamic
// dialog creation somehow replaces characters > 128 with _.
// This fixes that problem.
if ((cp->dlgCmd)->cmdType == C_BoxedLabel ||
(cp->dlgCmd)->cmdType == C_Button ||
(cp->dlgCmd)->cmdType == C_CheckBox ||
(cp->dlgCmd)->cmdType == C_Label ||
(cp->dlgCmd)->cmdType == C_RadioButton ||
(cp->dlgCmd)->cmdType == C_TextIn)
{
cp->SetCmdStr((cp->dlgCmd)->title);
}
else if ((cp->dlgCmd)->cmdType == C_Text)
{
if (!(cp->dlgCmd)->itemList || (*(char *)(cp->dlgCmd)->itemList == 0))
cp->SetCmdStr((cp->dlgCmd)->title);
else
cp->SetCmdStr((char*)(cp->dlgCmd)->itemList);
}
if ((cp->dlgCmd)->cmdType == C_CheckBox && (cp->dlgCmd)->retVal)
cp->SetCmdVal(1,Checked);
if ((cp->dlgCmd)->cmdType == C_RadioButton && (cp->dlgCmd)->retVal)
cp->SetCmdVal(1,Checked);
if ((cp->dlgCmd)->cmdType == C_BoxedLabel)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
if ((cp->dlgCmd)->cmdType == C_Text)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
if ((cp->dlgCmd)->cmdType == C_ToggleButton)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
if ((cp->dlgCmd)->cmdType == C_ToggleIconButton)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
if ((cp->dlgCmd)->cmdType == C_Icon)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
if ((cp->dlgCmd)->cmdType == C_Slider || (cp->dlgCmd)->cmdType == C_Spinner)
cp->SetCmdVal(cp->GetCmdValue((cp->dlgCmd)->cmdId),Value);
if ((cp->dlgCmd)->cmdType == C_ProgressBar)
cp->SetCmdVal(cp->GetCmdValue((cp->dlgCmd)->cmdId),Value);
if (!(cp->dlgCmd)->Sensitive) // Make insensitive if it was
{
cp->SetCmdVal(0,Sensitive);
}
if ((cp->dlgCmd)->attrs & CA_Hidden) // Hide it!
{
cp->SetCmdVal(1,Hidden);
}
if ((cp->dlgCmd)->cmdType == C_List
|| (cp->dlgCmd)->cmdType == C_ComboBox
|| (cp->dlgCmd)->cmdType == C_SComboBox
|| (cp->dlgCmd)->cmdType == C_Spinner
|| (cp->dlgCmd)->cmdType == C_SList )
{
int curval = cp->GetCmdValue((cp->dlgCmd)->cmdId);
cp->SetCmdVal(curval,ChangeList);
}
if ((cp->dlgCmd)->cmdType == C_Icon || (cp->dlgCmd)->cmdType == C_Frame)
{
// cp->SetCmdVal(0,Sensitive); // Trick to avoid getting focus
}
// Now add ToolTip if it has a message
if ((cp->dlgCmd)->tip && *(cp->dlgCmd)->tip)
{
/* ToolTips code not implemented in OS/2 yet. More effort needed!!!
TOOLINFO ti;
char *cc = (char*) &ti;
int lim = sizeof (ti);
for (int i = 0 ; i++ < lim ; *cc++ = 0)
;
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
ti.hwnd = hwnd;
ti.uId = (UINT)GetDlgItem(hwnd,(cp->dlgCmd)->cmdId);
ti.lpszText = TEXT((cp->dlgCmd)->tip);
SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
*/
}
}
// _isShown = 1; // We will be shown now
RECTL rc; // to get our size
WinQueryWindowRect (_barHwnd, &rc); // the rect of the command bar
_windowY = 0; // put pane at bottom for now
_windowH = rc.yTop - rc.yBottom; // compute height
// WinEnableWindow(_barHwnd, TRUE);
return 0;
}
//====================>>> vCommandPane::OnEnable <<<==================
void vCommandPane::OnEnable(HWND hwnd, BOOL fEnable)
{
WinEnableWindow (hwnd, fEnable);
/*
// Make all child windows have the same status as the dialog box.
for (HWND hwndCtl = (HWND) WinQueryWindow (hwnd, QW_TOP); hwndCtl != NULLHANDLE ;
hwndCtl = (HWND) WinQueryWindow (hwnd, QW_NEXT))
{
WinEnableWindow (hwndCtl, fEnable);
}
*/
}
//====================>>> vCommandPane::OnPaint <<<==================
int vCommandPane::OnPaint(HWND hwnd)
{
// Paint dividing lines around command/status bar
RECTL rc, rcInner, rcGrip;
POINTL pnt = {0,0};
LINEBUNDLE ShadowPen, LightPen;
int borderH, borderV;
int gripPitch, frameV, frameH;
borderH = WinQuerySysValue (HWND_DESKTOP, SV_CYBORDER);
borderV = WinQuerySysValue (HWND_DESKTOP, SV_CXBORDER);
frameV = 0; // space from edge of bar to frame boundary
frameH = 1;
gripPitch = 2; // pitch of grip ribs
ShadowPen.lColor = SYSCLR_BUTTONDARK;
ShadowPen.usMixMode = FM_OVERPAINT;
ShadowPen.usType = LINETYPE_SOLID;
LightPen.lColor = SYSCLR_BUTTONLIGHT;
LightPen.usMixMode = FM_OVERPAINT;
LightPen.usType = LINETYPE_SOLID;
// begin painting here
HPS hdc = WinBeginPaint (_barHwnd, NULLHANDLE, &rc);
WinQueryWindowRect(_barHwnd, &rc);
WinFillRect(hdc, &rc, SYSCLR_BUTTONMIDDLE);
if (paneType() == P_Status) // Paint a status bar
{
rcInner.xLeft = rc.xLeft + frameH;
rcInner.xRight = rc.xRight - frameH +1;
rcInner.yBottom = rc.yBottom + frameV;
// to make it look centered, we need to add the border thickness to the top
rcInner.yTop = rc.yTop - frameV - 2*borderV;
WinDrawBorder(hdc,
&rcInner,
borderV,
borderH,
SYSCLR_BUTTONMIDDLE,
SYSCLR_BUTTONMIDDLE,
DB_DEPRESSED);
// Paint diagonal grip ribs on status pane
// draw grip area rectangle
rcGrip.xLeft = rcInner.xRight - 6*gripPitch;
rcGrip.yBottom = rcInner.yBottom;
rcGrip.xRight = rcInner.xRight;
rcGrip.yTop = rcInner.yBottom + 6*gripPitch;
WinFillRect(hdc, &rcGrip, SYSCLR_BUTTONMIDDLE);
// WinFillRect(hdc, &rcGrip, CLR_GREEN);
rcInner.xRight -= 1; // the drawing commands are inclusive
// draw bottom hash
pnt.x = rcInner.xRight -gripPitch;
pnt.y = rcInner.yBottom;
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
GpiSetCurrentPosition (hdc, &pnt);
pnt.x = rcInner.xRight;
pnt.y = rcInner.yBottom +gripPitch;
GpiLine (hdc, &pnt);
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
pnt.x = rcInner.xRight -2*gripPitch;
pnt.y = rcInner.yBottom;
GpiSetCurrentPosition (hdc, &pnt);
pnt.x = rcInner.xRight;
pnt.y = rcInner.yBottom +2*gripPitch;
GpiLine (hdc, &pnt);
// draw middle hash
pnt.x = rcInner.xRight -3*gripPitch;
pnt.y = rcInner.yBottom;
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
GpiSetCurrentPosition (hdc, &pnt);
pnt.x = rcInner.xRight;
pnt.y = rcInner.yBottom +3*gripPitch;
GpiLine (hdc, &pnt);
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
pnt.x = rcInner.xRight -4*gripPitch;
pnt.y = rcInner.yBottom;
GpiSetCurrentPosition (hdc, &pnt);
pnt.x = rcInner.xRight;
pnt.y = rcInner.yBottom +4*gripPitch;
GpiLine (hdc, &pnt);
// draw top hash
pnt.x = rcInner.xRight -5*gripPitch;
pnt.y = rcInner.yBottom;
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
GpiSetCurrentPosition (hdc, &pnt);
pnt.x = rcInner.xRight;
pnt.y = rcInner.yBottom +5*gripPitch;
GpiLine (hdc, &pnt);
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
pnt.x = rcInner.xRight -6*gripPitch;
pnt.y = rcInner.yBottom;
GpiSetCurrentPosition (hdc, &pnt);
pnt.x = rcInner.xRight;
pnt.y = rcInner.yBottom +6*gripPitch;
GpiLine (hdc, &pnt);
}
else // Paint a command bar
{
GpiSetCurrentPosition (hdc, &pnt);
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
pnt.x = rc.xRight;
pnt.y = 0;
GpiLine (hdc, &pnt);
GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
pnt.x = 0;
pnt.y = _windowH - borderH;
GpiSetCurrentPosition (hdc, &pnt);
pnt.x = rc.xRight;
pnt.y = _windowH - borderH;
GpiLine (hdc, &pnt);
}
WinEndPaint (hdc);
return 0;
}
//====================>>> vCommandPane::OnCommand <<<==================
void vCommandPane::OnCommand (vCmd *UseThis, int uMsg, MPARAM mp1,
MPARAM mp2)
{
// A very dangerous thing can happen here if the button causes
// vApp::Exit to be called. This can cause things to be destructed,
// which means that the command object goes away, which means
// that UseThis no longer points to something valid, which is of
// course a problem. Exit can get called in CmdCallback, so we
// will remember the command type first for the test after the call.
CmdType ct = (UseThis->dlgCmd)->cmdType; // will be ok still
UseThis->CmdCallback(uMsg, mp1, mp2);
// We need a SetFocus to get the focus back to the
// canvas so that cursor will work, but for
// lists and combos, SetFocus breaks them. Also, we don't
// want timer updates to text controls to cause focus grabbing
// so we have to check for them too.
if ((ct == C_ComboBox || ct == C_SComboBox) && SHORT2FROMMP(mp1) != CBN_ENTER)
return;
if ((ct == C_List || ct == C_SList)
&& SHORT2FROMMP(mp1) != LN_ENTER && SHORT2FROMMP(mp1) != LN_SELECT)
return;
if (ct == C_BoxedLabel || ct == C_ColorLabel || ct == C_Label || ct == C_ProgressBar
|| ct == C_Text || ct == C_Icon)
{
return;
}
// we need to flag when the user is inputing data into a text in box
// so that we can know not to mess with the focus when the mouse
// buttons are being clicked
if (ct == C_TextIn)
{
if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
_TextInActive = 1;
else if(SHORT2FROMMP(mp1) == EN_KILLFOCUS)
_TextInActive = 0;
return;
}
// The idea here is that we change the focus back to the client after
// any WM_CONTROL/WM_COMMAND message occurs, but we only do this if the
// app is currently active. If it is not, then we do nothing which prevents
// automatic timer updates of things like text boxes from yanking away focus
// from another app that is curently active.
// note: parent of cmdpane should be our frame
if ( WinQueryActiveWindow(HWND_DESKTOP) == WinQueryWindow(_barHwnd, QW_PARENT) )
{
WinFocusChange(HWND_DESKTOP, WinQueryWindow(_barHwnd, QW_OWNER),
FC_NOSETACTIVE | FC_NOSETSELECTION);
}
}
//====================>>> vCommandPane::DynamicDlgProc <<<==================
int vCommandPane::DynamicDlgProc(HWND hDlg, UINT uMsg,MPARAM mp1, MPARAM mp2)
{
switch (uMsg)
{
case WM_INITDLG:
_barHwnd = hDlg;
_wDialog = hDlg; // used by vCmdParent
return OnInitDialog(hDlg, mp1, mp2);
/*
case WM_ENABLE:
OnEnable(hDlg, (BOOL) SHORT1FROMMP(mp1));
break;
*/
case WM_PAINT:
return OnPaint(hDlg);
case WM_CONTROL:
case WM_COMMAND:
{
vCmd* UseThis = (vCmd *) getThisFromId((ItemVal)SHORT1FROMMP(mp1));
if (!UseThis)
{
return 0;
}
OnCommand(UseThis, uMsg, mp1, mp2);
return 0;
}
// we need to monitor if the cmdpane gets focus and then send the
// focus right back to the client
case WM_BUTTON1UP:
case WM_BUTTON2UP:
case WM_BUTTON3UP:
case WM_CONTEXTMENU:
case WM_BEGINSELECT:
case WM_SINGLESELECT:
{
// if the user is inputing text into a textin box, then we
// don't want to mess with the focus when user clicks the mouse
// in the command bar (yes, it's a kludge!!!)
if (_TextInActive == 1)
return 0;
WinFocusChange(HWND_DESKTOP, WinQueryWindow(_barHwnd ,QW_OWNER),
FC_NOSETACTIVE | FC_NOSETSELECTION);
break;
}
default:
break;
}
return (int) WinDefDlgProc(hDlg, uMsg, mp1, mp2);
}