home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
srcos2
/
vbtncmd.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-25
|
15KB
|
442 lines
//===============================================================
// vbtncmd.cpp - button Cmd - Windows
//
// Copyright (C) 1995-1999 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/vbtncmd.h> // our definitions
#include <v/vcmdprnt.h> // a command parent
#include <v/vutil.h>
#include <v/vicon.h>
#include <v/vapp.h>
// Toggle buttons are subclassed to this procedure
MRESULT EXPENTRY BtnToggleProc(HWND hDlg, ULONG uMsg, MPARAM mp1, MPARAM mp2);
// this is a pointer to the original button procedure that is subclassed
PFNWP orgBtnProc;
//====================>>> vButtonCmd::vButtonCmd <<<=======================
vButtonCmd::vButtonCmd(vCmdParent* dp, CommandObject* dc) :
vCmd(dp, dc)
{
initialize();
}
//====================>>> vButtonCmd::~vButtonCmd <<<=======================
vButtonCmd::~vButtonCmd()
{
SysDebug(Destructor,"vButtonCmd::~vButtonCmd() destructor\n")
}
//=====================>>> vButtonCmd::initialize <<<=======================
void vButtonCmd::initialize()
{
// build a button command for use in a parent window
SysDebug(Constructor,"vButtonCmd::vButtonCmd() constructor\n")
long style;
// set the Pres Params to the system default color
_PPColor[0].PPtype = PP_BACKGROUNDCOLORINDEX;
_PPColor[0].PPval.color = SYSCLR_BUTTONMIDDLE;
_PPColor[1].PPtype = PP_FOREGROUNDCOLORINDEX;
_PPColor[1].PPval.color = SYSCLR_MENUTEXT;
_PPColor[2].PPtype = 0; // end of array marker
if (_parentWin->_dialogType != aCmdBar)
style = WS_TABSTOP | WS_GROUP; // default for a dialog button
else
style = WS_GROUP | BS_NOPOINTERFOCUS;
CopyToLocal(); // Make local copies of CmdObject
if (!(dlgCmd->attrs & CA_Hidden)) // Check for Hidden
style |= WS_VISIBLE;
if ((dlgCmd->cmdType == C_IconButton || dlgCmd->cmdType == C_ToggleIconButton)
&& _itemList != 0) // icon
{
initIconButton(style); // Special init if icon
return;
}
if (dlgCmd->cmdType == C_ColorButton) // just set PPs to get a color button
{
style |= BS_PUSHBUTTON;
initColorButton();
}
else if (dlgCmd->cmdType == C_ToggleButton) // noop for toggle
style |= BS_PUSHBUTTON;
else if ((dlgCmd->attrs & CA_DefaultButton)) // default button?
style |= BS_DEFAULT;
else
style |= BS_PUSHBUTTON; // Plain old button
_w = LabelWidth(_title)+14; // set my width
_h = LabelHeight() + 5; // was _h = 14;
if ((dlgCmd->cmdType == C_Button || dlgCmd->cmdType == C_ToggleButton)
&& dlgCmd->size > 0)
{
// make sure button is big enough to hold text
int w = LabelWidth(_title)+14; // set my width
if (w < dlgCmd->size)
{
_w = dlgCmd->size;
}
}
else if ( dlgCmd->cmdType == C_ColorButton && dlgCmd->size > 0)
{
// each y dialog unit is 1/8 the max system font height and
// each x dialog unit is 1/4 max system font width. The system
// proportional font is 8x20 so in pixels one x dialog unit = 2 pixels
// and one y dialog unit = 2.5 pixels. Since we want square
// buttons we need to multiply y by 4/5 to get same size as
// x on the screen. We then multiply by 1/2 to convert to
// pixels as desired.
_w = dlgCmd->size*5/4; // size - square (color buttons)
_h = dlgCmd->size; // simulate pixels using dialog units
}
else if (dlgCmd->size > 0) // size - square (icons)
{
_w = dlgCmd->size*5/4;
_h = dlgCmd->size;
}
_parentWin->SetPosition(_x, _y, _w, _h, dlgCmd->cFrame, dlgCmd->cRightOf,
dlgCmd->cBelow);
/*
if (dlgCmd->cmdType == C_Button || dlgCmd->cmdType == C_ToggleButton)
{
_y += 1; // center better
}
*/
_CtrlOffset = _parentWin->AddDlgControl(_x, _y, _w, _h, _cmdId,
style, WC_BUTTON, _title, _parentWin->AssyPresParams(_PPColor), 0, NULL);
}
//=====================>>> vButtonCmd::initColorButton <<<=======================
void vButtonCmd::initColorButton(void)
{
// wCmd is the widget of this button
_origColor = 0;
if (_itemList != 0) // an RGB provided
{
_origColor = (vColor*)_itemList; // point to the rgb
_color = *_origColor;
}
// set the Pres Params to the specified color
// we use the RGB version for the background
_PPColor[0].PPtype = PP_BACKGROUNDCOLOR;
_PPColor[0].PPval.color = (LONG) _color.pixel();
_PPColor[1].PPtype = PP_FOREGROUNDCOLORINDEX;
_PPColor[1].PPval.color = SYSCLR_MENUTEXT;
_PPColor[2].PPtype = 0; // end of array marker
}
//=====================>>> vButtonCmd::initIconButton <<<====================
void vButtonCmd::initIconButton(long style)
{
style |= BS_BITMAP;
_ip = (vIcon *) _itemList; // to access bitmap
_h = LONG( (_ip->height / 2.5) + 6 );
_w = LONG( (_ip->width / 2) + 6 );
// build up the button control data to point to the desired bitmap
_btncData.cb = sizeof(BTNCDATA);
_btncData.fsCheckState = 0;
_btncData.fsHiliteState = 0;
// get icon HBITMAP
_btncData.hImage = _ip->GetIconDLG(dlgCmd->cmdType, SYSCLR_BUTTONMIDDLE);
_parentWin->SetPosition(_x, _y, _w, _h, dlgCmd->cFrame,
dlgCmd->cRightOf, dlgCmd->cBelow);
/*
// set the Pres Params to the specified color
// we use the RGB version for the background
_PPColor[0].PPtype = 13;
_PPColor[0].PPval.color = SETRGB(0,0,0);
_PPColor[1].PPtype = 1;
_PPColor[1].PPval.color = SETRGB(0,0,0);
_PPColor[2].PPtype = 0; // end of array marker
_CtrlOffset = _parentWin->AddDlgControl(_x, _y , _w, _h, _cmdId,
style, WC_BUTTON, "", _parentWin->AssyPresParams(_PPColor),
_btncData.cb, &_btncData);
*/
_CtrlOffset = _parentWin->AddDlgControl(_x, _y , _w, _h, _cmdId,
style, WC_BUTTON, "", NULL, _btncData.cb, &_btncData);
}
//==================>>> vButtonCmd::GetCmdValue <<<=========================
int vButtonCmd::GetCmdValue(ItemVal id) VCONST
{
if (id != _cmdId)
return -1;
return _retVal;
}
//==================>>> vButtonCmd::GetCmdValue <<<=========================
int vButtonCmd::GetOwnCmdValue(void)
{
// subclassed toggle buttons call this method to determine
// the buttons current state. Unfortunately it cannot be
// private, so... security through obscurity.
return _retVal;
}
//================>>> vButtonCmd::ResetItemValue <<<======================
void vButtonCmd::ResetItemValue(void)
{
// We have to toggle things
if (dlgCmd->cmdType != C_ToggleIconButton &&
dlgCmd->cmdType != C_ToggleButton)
return;
if (_retVal == _origVal) // No op if no change
return;
_retVal = _origVal; // restore
if (_retVal) // depends on state
{
SetCmdVal(1, Checked);
}
else
{
SetCmdVal(0, Checked);
}
// HWND myHwnd = GetMyHwnd(_cmdId);
// WinShowWindow (myHwnd, FALSE); // trick to repaint button
// WinShowWindow (myHwnd, TRUE);
// let parent window handle now
_parentWin->ProcessCmd(_cmdId, _retVal, dlgCmd->cmdType);
}
//================>>> vButtonCmd::SetCmdVal <<<============================
void vButtonCmd::SetCmdVal(ItemVal val, ItemSetType st)
{
SysDebug1(Misc,"vButtonCmd::SetCmdVal(val:%d)\n",val)
HWND myHwnd = GetMyHwnd(_cmdId);
switch (st)
{
case Sensitive:
_Sensitive = val; // set
WinEnableWindow (myHwnd, val);
break;
case Hidden:
if (val)
{
WinShowWindow (myHwnd, FALSE);
}
else
{
WinShowWindow (myHwnd, TRUE);
}
break;
case Value:
case Checked:
_retVal = val; // set
if (dlgCmd->cmdType != C_ToggleIconButton && // only toggles need attention
dlgCmd->cmdType != C_ToggleButton)
return;
// WinCheckButton(_parentWin->getParent(),_cmdId, val);
SysDebug2(OS2Dev,"--> val:%d _retVal:%d \n",val, _retVal)
WinSendDlgItemMsg(_parentWin->getParent(), _cmdId,
BM_SETHILITE, MPFROMSHORT(val), (MPARAM)NULL);
// HWND myHwnd = GetMyHwnd(_cmdId);
break;
case ChangeColor: // changed original vColor
{
_color = *_origColor; // recopy color
// set the Pres Params to the specified color
// we use the RGB version of the PP_
_PPColor[0].PPtype = PP_BACKGROUNDCOLOR;
_PPColor[0].PPval.color = (LONG) _color.pixel();
// if the user calls ChangeColor before the dialog is
// displayed then the control won't exist and WinSetPresParams
// will fail. We need to check for this and change the dialog
// template PresParams instead if the dialog has not been created.
if (myHwnd)
{
WinSetPresParam(myHwnd, _PPColor[0].PPtype, (ULONG) sizeof(RGB),
(PVOID) &_PPColor[0].PPval.color);
}
else
{
_parentWin->ChangeDlgTButtonColor(_CtrlOffset, _cmdId,
_PPColor[0].PPval.color );
}
break;
}
case Red:
_color.SetR(val);
break;
case Green:
_color.SetG(val);
break;
case Blue:
{
_color.SetB(val);
_PPColor[0].PPtype = PP_BACKGROUNDCOLOR;
_PPColor[0].PPval.color = (LONG) _color.pixel();
WinSetPresParam(myHwnd, _PPColor[0].PPtype, (ULONG) sizeof(RGB),
(PVOID) &_PPColor[0].PPval.color);
break;
}
}
}
//==================>>> vButtonCmd::ToggleCmdValue <<<=========================
int vButtonCmd::ToggleCmdValue(void)
{
SysDebug1(OS2Dev,"ToggleCmdValue org _retVal:%d \n",_retVal)
SetCmdVal(!_retVal, Checked);
return _retVal;
}
//==================>>> vButtonCmd::userClick <<<=========================
int vButtonCmd::userClick(int clicked)
{
// This routine lets the first BM_SETHILITE message sent
// after a user clicks on the button to be passed
// through to the button control unaltered. This is
// necessary so that the button can change state and issue
// the required WM_COMMAND. All BM_SETHILITE messages after
// the first one are filtered and set to _retVal
SysDebug1(OS2Dev,"Userclick click:%d \n",_click)
if (clicked)
{
_click = 1;
return _click;
}
else
{
if (_click)
{
_click = 0;
return 1;
}
return 0;
}
}
//================>>> vButtonCmd::SetCmdStr <<<============================
void vButtonCmd::SetCmdStr(char* str)
{
// Set the string value of button
SysDebug1(Misc,"vButtonCmd::SetCmdStr(str:%s)\n",str)
WinSetDlgItemText(_parentWin->getParent(),_cmdId, str);
_title = str;
}
//================>>> vButtonCmd::DRAWITEM <<<============================
int vButtonCmd::DRAWITEM(int id, OWNERITEM* poi)
{
// This really has nothing to do with DRAWITEM, but its
// an unused procedure that we can hijak and use to subclass
// toggle buttons during the WM_INITDLG setup
if (dlgCmd->cmdType == C_ToggleIconButton ||
dlgCmd->cmdType == C_ToggleButton)
{
// This is called during WM_INITDLG for toggle buttons
// so we can subclass the button procedure
// HWND hBtn = WinWindowFromID((HWND)poi, id);
HWND hBtn = GetMyHwnd(id);
WinSetWindowULong(hBtn, QWL_USER, (LONG) this);
WinSendMsg(hBtn, BM_SETHILITE, MPFROMSHORT(_retVal), (MPARAM)NULL);
_orgBtnProc = WinSubclassWindow(hBtn, BtnToggleProc);
SysDebug2(OS2Dev,"DRAWITEM this:%x hBtn:%x \n", this, hBtn)
// HWND myHwnd = GetMyHwnd(_cmdId);
// if (SHORT1FROMMP((MPARAM) poi) == FALSE) // losing focus
// WinPostMsg(myHwnd, BM_SETHILITE, MPFROMSHORT(_retVal), (MPARAM)NULL);
}
return (0);
}
//====================>>> BtnToggleProc <<<=======================
// we subclass the C_ToggleButton so we can control its
// hilited state and stop the WC_FRAME class from interfering
MRESULT EXPENTRY BtnToggleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
vButtonCmd* thisCmd = (vButtonCmd*) WinQueryWindowULong( hwnd, QWL_USER ); // Pointer from window word
if (!thisCmd)
{
return (MRESULT) WinDefDlgProc(hwnd, msg, mp1, mp2);
}
else
return (MRESULT) thisCmd->vBtnToggleProc(hwnd, msg, mp1, mp2);
}
//====================>>> vBtnToggleProc <<<=======================
// we subclass the C_ToggleButton so we can control its
// hilited state and stop the WC_FRAME class from interfering
MRESULT vButtonCmd::vBtnToggleProc(HWND hBtn, ULONG uMsg, MPARAM mp1, MPARAM mp2)
{
// set the original frame procedure
orgBtnProc = (PFNWP) _orgBtnProc;
switch (uMsg)
{
case BM_SETHILITE:
{
// prevent frame from altering toggle button state
// by trapping any attempt to alter buttons state
// with its private BM_SETHILITE messages and replacing
// it with the desired state
if (!userClick(0)) // check if pending click
mp1 = MPFROMSHORT(GetOwnCmdValue());
SysDebug3(OS2Dev,"BtnToggleProc this:%x hBtn:%x mp1:%x \n", this, hBtn, mp1)
}
break;
case WM_BUTTON1DOWN:
{
// user has clicked on the button, so toggle the button state
// so that _retVal gets updated befor the BM_SETHILITE is sent
userClick(1); // button is clicked so pass through next
// BM_SETHILITE
}
break;
}
return orgBtnProc(hBtn, uMsg, mp1, mp2);
}
//====================>>> vButtondCmd::CmdCallback <<<=======================
void vButtonCmd::CmdCallback(UINT uMsg, MPARAM mp1, MPARAM mp2)
{
if (uMsg == WM_COMMAND)
{
if (dlgCmd->cmdType == C_ToggleIconButton || // depends on state
dlgCmd->cmdType == C_ToggleButton)
{
SysDebug3(OS2Dev,"CmdCallBack uMsg:%x mp1:%x mp2:%x \n", uMsg, mp1, mp2)
SetCmdVal(!_retVal, Checked);
}
}
// let parent window handle now
_parentWin->ProcessCmd(_cmdId, _retVal, dlgCmd->cmdType);
}