home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
srcos2
/
vdialog.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-03
|
17KB
|
540 lines
//===============================================================
// vdialog.cxx - vDialog class - OS/2
//
// 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/vdialog.h> // our header
#include <v/vapp.h>
#include <v/vthislst.h> // For this list
// Define static data of the class
MRESULT EXPENTRY DlgProcCB(HWND hDlg, ULONG uMsg, MPARAM mp1, MPARAM mp2);
static vThisList _thisList; // hide this in this file
vDialog* vDialog::_curModal = 0; // V:1.13
//===================>>> vDialog::vDialog <<<=======================
vDialog::vDialog(const vDialog& d) : vBaseWindow(d),
vCmdParent(P_Dialog)
{
vSysError("vDialog - V semantics do not support copy constructors!");
_oldModal = 0; // V:1.13
}
//=================>>> vDialog::~vDialog <<<=======================
vDialog::~vDialog()
{
SysDebug(Destructor,"vDialog::~vDialog() destructor\n")
_IsDisplayed = 0; // The dialog is not up
if (_hTemplate != 0)
{
::DosFreeMem(_hTemplate);
_hTemplate = 0;
}
closeBaseWindow(); // close this window
_thisList.Delete((ThisId)_wDialog); // free the this ptr
}
//===================>>> vDialog::vDialog <<<=======================
vDialog::vDialog(vBaseWindow* creator, int modal, VCONST char* title) :
vBaseWindow(title), vCmdParent(P_Dialog) // constructor
{
_parentHWND = creator->winHwnd(); // track parent's HWND
init(modal,title); // finish construction
}
//===================>>> vDialog::vDialog <<<=======================
vDialog::vDialog(vApp* creator, int modal, VCONST char* title) :
vBaseWindow(title), vCmdParent(P_Dialog) // constructor
{
_parentHWND = creator->winHwnd(); // track parent's HWND
init(modal,title); // finish construction
}
//===================>>> vDialog::vDialog <<<=======================
void vDialog::init(int modal, VCONST char* title)
{
// Initialize dialog box
_modal = modal; // settable modal
SysDebug(Constructor,"vDialog::vDialog() constructor\n")
_wType = DIALOG; // a dialog
_dialogType = aDialog; // This is a dialog
_IsDisplayed = 0; // The dialog is not up
_wDialog = 0; // haven't created the dialog yet...
hwndToolTip = 0;
// Now, build the initial in-memory dialog template using
// DLGTEMPLATE pointer _hTemplate.
int buildOK;
// Using 8,helv makes it ok to use 8 in calculating control sizes!
#ifdef ALLOW_BOLD_FONT
// get screen width in pels
int horRes;
HDC hDevCxt = GpiQueryDevice(WinGetScreenPS(HWND_DESKTOP));
DevQueryCaps(hDevCxt, CAPS_WIDTH, 1L, &horRes);
char *fntname = (horRes <= 800) ? "8.Helv" : "8.HelvBold";
#else
char *fntname = "8.Helv";
#endif
// PPElement PPel[] = { {PP_FONTNAMESIZE,(ULONG) "8.Helv"}, {0}};
PPElement PPel[] = { {PP_FONTNAMESIZE,(ULONG) fntname}, {0}};
if (_modal)
buildOK = CreateDlgTemplate( FCF_TITLEBAR | FCF_DLGBORDER |
// FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS,
10,25, 1,1, 0, "", "", _name, AssyPresParams(PPel) );
else
buildOK = CreateDlgTemplate( FCF_TITLEBAR | FCF_DLGBORDER |
// FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS,
10,25, 1,1, 0, "", "", _name, AssyPresParams(PPel) );
if (!buildOK)
vSysError("vDialog - Unable to build dialog template");
_DefaultButton = 0; // No default button described
_FirstTextIn = 0; // No text in field
}
//===================>>> vDialog::AddDialogCmds <<<========================
void vDialog::AddDialogCmds(CommandObject* cList) // add commands
{
// This is called to add commands from the supplied
// CommandObject list.
vCmd* defButton = 0;
DlgCmdList* curCmd;
// scan the entire list
for (int ix = 0 ; cList && (cList[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(&cList[ix]);
// Track default button
if (cList[ix].attrs & CA_DefaultButton)
{
defButton = curCmd->cmdP;
}
if (cList[ix].cmdType == C_TextIn)
{
if (_FirstTextIn == 0)
_FirstTextIn = curCmd->cmdP;
}
}
if (defButton) // we have a default
{
_DefaultButton = defButton; // Track the default button
}
DoneAddingControls(); // all finished with controls
}
//===================>>> vDialog::AddDialogCmdObj <<<========================
void vDialog::AddDialogCmdObj(CommandObject* Cmd, vCmd* CmdInstance)
{
// This is called to add an already instantiated command object to the
// CommandObject list.
DlgCmdList* curCmd = new DlgCmdList; // get a new cell
curCmd->nextDCL = _cmdList; // add in at front of list
_cmdList = curCmd;
curCmd->cmdP = CmdInstance; // point to the object
// Track default button
if (Cmd->attrs & CA_DefaultButton)
{
_DefaultButton = CmdInstance; // This is the default button
// This lets us use Enter to activate the default button.
}
}
//====================>>> vDialog::CancelDialog <<<=======================
void vDialog::CancelDialog(void)
{
// Cancel selected - reset all values to original values
SysDebug(CmdEvents,"vDialog::CancelDialog()\n")
for (DlgCmdList* cc = _cmdList ; cc != 0 ; cc = cc->nextDCL)
{
(cc->cmdP)->ResetItemValue();
}
// And close the dialog
CloseDialog();
}
//====================>>> vDialog::CloseDialog <<<=======================
void vDialog::CloseDialog(void)
{
SysDebug(Build,"vDialog::CloseDialog()\n")
_IsDisplayed = 0; // The dialog is not up
if (!_modal) // destroy if not modal
WinDestroyWindow(_wDialog);
_thisList.Delete((ThisId)_wDialog); // free the this ptr
}
//====================>>> vDialog::DialogCommand <<<=======================
void vDialog::DialogCommand(ItemVal id, ItemVal retval, CmdType ctype)
{
// After the user has selected a command from the dialog,
// this routine is called with the value
SysDebug2(CmdEvents,"vDialog::DialogCommand(id:%d, val:%d)\n",id, retval)
switch (id) // We will do some things depending on value
{
case M_Cancel:
CancelDialog();
break;
case M_Done: // default, close dialog
case M_OK:
{
CloseDialog();
break;
}
}
}
//====================>>> vDialog::DialogDisplayed <<<=======================
void vDialog::DialogDisplayed()
{
}
//==================>>> vDialog::ProcessCmd <<<=======================
void vDialog::ProcessCmd(ItemVal id, ItemVal rv, CmdType ct)
{
// simple interface between command objects and the
// inherited vCmdParent ProcessCmd to the CommandObject which does the work
DialogCommand(id, rv, ct);
}
//====================>>> vDialog::SetDialogTitle <<<=======================
void vDialog::SetDialogTitle(VCONST char* title)
{
WinSetWindowText(_wDialog, title);
}
//================>>> vDialog::GetDialogPosition <<<========================
void vDialog::GetDialogPosition(int& left, int& top, int& width, int& height) VCONST
{
RECTL rct;
WinQueryWindowRect (_wDialog, &rct);
WinMapWindowPoints (_wDialog ,HWND_DESKTOP, (PPOINTL) &rct, 2);
LONG DisplayHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
// in OS/2 the origin is at the bottom left corner whereas V has the
// origin in the top left corner. We need to transform coords from
// os/2 to V space to get the right results
// CAUTION: WinQuery return rc coords are inclusive/exclusive
top = (DisplayHeight-1) - rct.yTop;
left = rct.xLeft;
width = rct.xRight - rct.xLeft;
height = rct.yTop - rct.yBottom;
}
//====================>>> vDialog::SetDialogPosition <<<=======================
//
// position is relative to the screen, not the application
//
void vDialog::SetDialogPosition(int left, int top)
{
RECTL ar;
WinQueryWindowRect (_wDialog, &ar);
int height = ar.yTop - ar.yBottom;
LONG DisplayHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
// in OS/2 the origin is at the bottom left corner whereas V has the
// origin in the top left corner. We need to transform coords from
// V to os/2 space to get the right results
top = (DisplayHeight-1) - top;
// CAUTION: WinSetWindowPos rc coords are inclusive/exclusive
// and use the bottom left corner
int bottom = top - height;
WinSetWindowPos (_wDialog, HWND_TOP,
left, bottom,
0,0,
SWP_MOVE);
}
//====================>>> vDialog::ShowDialog <<<=======================
void vDialog::ShowDialog(VCONST char* msg)
{
// Show the dialog with the default message
// We will control the position of the dialog box based on
// the parent's location. The user can move the dialog later.
SysDebug1(Build,"vDialog::ShowDialog(%s) \n",msg)
if (_IsDisplayed)
return; // make this a no-op
// First, get the values from our parent
// set the message field -- have to move to the dlgproc init case
if (msg && *msg)
{
for (DlgCmdList* cc = _cmdList ; cc != 0 ; cc = cc->nextDCL)
{
if (((cc->cmdP)->dlgCmd)->attrs & CA_MainMsg)
{
((cc->cmdP)->dlgCmd)->title = msg; // repoint to the message
}
}
}
// Since the dialog isn't necessarily re-created each time it is
// popped up, we need to loop through now to set the original values
for (DlgCmdList* cc = _cmdList ; cc != 0 ; cc = cc->nextDCL)
{
(cc->cmdP)->SaveItemValue();
}
// Now ready to popup the dialog
_IsDisplayed = 1; // The dialog is up
if (_modal)
{
_wDialog = WinCreateDlg(HWND_DESKTOP, _parentHWND, (PFNWP) &DlgProcCB,
_hTemplate, (PVOID) this);
_myHWND = _wDialog;
WinProcessDlg (_wDialog);
WinDestroyWindow (_wDialog);
_IsDisplayed = 0;
}
else
{
_wDialog = WinCreateDlg(HWND_DESKTOP, _parentHWND, (PFNWP) &DlgProcCB,
_hTemplate, (PVOID) this);
_myHWND = _wDialog;
SysDebug1(OS2Dev," Modeless dialog HWND = %x \n", _wDialog)
}
}
// ---------------------------------------------------------------------
//====================>>> DlgProc <<<=======================
MRESULT EXPENTRY DlgProcCB(HWND hDlg, ULONG uMsg,
MPARAM mp1, MPARAM mp2)
{
vDialog* useThis;
if (uMsg == WM_INITDLG) // first time!
{
useThis = (vDialog*)mp2;
_thisList.Add((ThisId)hDlg, (void*)useThis);
}
else
useThis = (vDialog*)_thisList.GetThis((ThisId)hDlg);
if (!useThis)
return WinDefDlgProc(hDlg, uMsg, mp1, mp2);
return (MRESULT) useThis->DynamicDlgProc(hDlg, uMsg, mp1, mp2);
}
//====================>>> vDialog::DynamicDlgProc <<<=======================
int vDialog::DynamicDlgProc(HWND hDlg, UINT uMsg,
MPARAM mp1, MPARAM mp2)
{
int fProcessed = 0;
// This code handles nested modals, a no no.... (V:1.13)
if (_curModal != 0 && _curModal != this) // V:1.13
{
return 0;
}
switch (uMsg)
{
case WM_INITDLG:
{
// Changes here must have equivalents in the vcmdpane.cpp code
// although we can set these later in ShowDialog we need to set them now
// during creation for those controls that need to set their
// initial values during window creation
_wDialog = hDlg;
_myHWND = hDlg;
WinSetWindowText(_wDialog, _name);
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_ToggleButton)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _wDialog);
if ((cp->dlgCmd)->cmdType == C_ToggleIconButton)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _wDialog);
if ((cp->dlgCmd)->cmdType == C_Icon)
cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _wDialog);
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)->attrs & CA_MainMsg)
{
cp->SetCmdStr((cp->dlgCmd)->title);
}
if ((cp->dlgCmd)->attrs & CA_DefaultButton)
{
WinFocusChange(HWND_DESKTOP,
WinWindowFromID(_wDialog, (cp->dlgCmd)->cmdId),
0L); // Set to default
fProcessed = 1; // return 0 if we call SetFocus
}
if ((cp->dlgCmd)->cmdType == C_TextIn)
{
WinFocusChange(HWND_DESKTOP,
WinWindowFromID(_wDialog, (cp->dlgCmd)->cmdId),
0L); // Set to default
fProcessed = 1; // return 0 if we call SetFocus
}
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_SList
|| (cp->dlgCmd)->cmdType == C_ComboBox
|| (cp->dlgCmd)->cmdType == C_SComboBox
|| (cp->dlgCmd)->cmdType == C_Spinner)
{
int curval = cp->GetCmdValue((cp->dlgCmd)->cmdId);
cp->SetCmdVal(curval,ChangeList);
}
if ((cp->dlgCmd)->cmdType == C_Icon || (cp->dlgCmd)->cmdType == C_Frame
|| (cp->dlgCmd)->cmdType == C_ToggleFrame)
{
// cp->SetCmdVal(0,Sensitive); // Trick to avoid getting focus
}
// TOOLTIPS NOT IMPLEMENTED YET!!!!
if ((cp->dlgCmd)->tip && *(cp->dlgCmd)->tip)
{
/* add the control to the tooltip. TTF_SUBCLASS causes the
tooltip to automatically subclass the window and look for the
messages it is interested in. */
if ((cp->dlgCmd)->tip && *(cp->dlgCmd)->tip)
{
}
}
}
DialogDisplayed();
return fProcessed;
}
case WM_CONTROL:
{
vCmd* UseThis = (vCmd *) getThisFromId((ItemVal)SHORT1FROMMP(mp1));
if (!UseThis)
{
fProcessed = 0;
break;
}
UseThis->CmdCallback(uMsg, mp1, mp2);
}
return fProcessed;
case WM_COMMAND:
{
vCmd* UseThis = (vCmd *) getThisFromId((ItemVal) mp1);
if (!UseThis)
{
fProcessed = 0;
break;
}
UseThis->CmdCallback(uMsg, mp1, mp2);
}
return fProcessed;
case WM_FOCUSCHANGE:
{
vCmd* UseThis = (vCmd *) getThisFromId((ItemVal) mp1);
if (!UseThis)
{
fProcessed = 0;
break;
}
UseThis->CmdCallback(uMsg, mp1, mp2);
}
return fProcessed;
/*
case WM_HSCROLL:
case WM_VSCROLL:
{
vCmd* UseThis = (vCmd *) getThisFromId(SHORT1FROMMP(mp1));
int code = SHORT2FROMMP(mp2);
if (!UseThis || code == SB_ENDSCROLL)
{
fProcessed = 0; break;
}
UseThis->CmdCallback(uMsg, mp1, mp2);
}
break;
*/
default:
fProcessed = FALSE;
break;
}
return (int) WinDefDlgProc(hDlg, uMsg, mp1, mp2);
}