home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
deans.zip
/
DIALOG.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-14
|
38KB
|
1,063 lines
//
// NAME: CIDGui_Dialog.Cpp
//
// DESCRIPTION:
//
// This module implements the DIALOGWND class. Note that we turn on the
// INCL_CIDLIB_GUICTRLS token, which forces all control window classes to
// be included.
//
//
// AUTHOR: Dean Roddey
//
// CREATE DATE: 09/25/93
//
// COPYRIGHT: 1992..1994, 'CIDCorp
//
// CAVEATS/GOTCHAS:
//
// 1) FRAMEWND's handling of presentation spaces are sufficient for
// DIALOGWND so it does not mess around with that stuff.
//
// MODIFICATION LOG:
//
// -----------------------------------------------------------------------------
// Local defines
// -----------------------------------------------------------------------------
#define CIDGUI_DIALOGWND_CPP
#define INCL_WINBUTTONS
#define INCL_WINENTRYFIELDS
#define INCL_WINLISTBOXES
#define INCL_WINSCROLLBARS
#define INCL_WINSTATICS
#define INCL_WINDIALOGS
#define INCL_WINFRAMEMGR
#define INCL_WINPOINTERS
#define INCL_WINWINDOWMGR
#define INCL_WINSYS
#define INCL_CIDLIB_FACOBJECT
#define INCL_CIDGUI_ERRORIDS
#define INCL_CIDGUI_FACOBJECT
#define INCL_CIDGUI_GUICTRLS
#define INCL_CIDGUI_DIALOGS
#define INCL_CIDGUI_GRAPHICS
#define INCL_CIDGUI_WINDOWS
// -----------------------------------------------------------------------------
// Standard includes
// -----------------------------------------------------------------------------
#include <string.h>
#include <stdlib.h>
// -----------------------------------------------------------------------------
// Facility specific includes
// -----------------------------------------------------------------------------
#include "CIDGui_.Hpp"
// -----------------------------------------------------------------------------
// Local functions
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: __clsMapPMClass( pDlgTmpl, pDlgItem, ppCtlData
// , pc4CtlLen)
//
// DESCRIPTION:
//
// This method will map the passed PM class type (and it's corresponding
// styles) into a equivilent CIDLib class name. It will also handle the
// control data for the control, if any. If not, it returns a 0 pointer.
// The caller is responsible for deleting the control data.
//
// The PM class type does not have the usual high word of set bits, so we
// force it on before comparing to the PM class constants.
// ---------------------------------------
// INPUT: pDlgTmpl is the address of the dialog template
// pDlgItem is the address of the dialog item for this control
//
// OUTPUT: ppCtlData is a pointer to a pointer that will be filled in with
// the address of an allocated control data buffer. If none, it is
// set to 0.
// pc4CtlLen is filled in with the length of the control data
//
// RETURN: A CIDCLASS object with the correct class name
//
static CIDCLASS __clsMapPMClass( const PDLGTEMPLATE pDlgTmpl
, const PDLGTITEM pDlgItem
, tCIDLib::VOID** ppCtlData
, tCIDLib::CARD4* pc4CtlLen)
{
tCIDLib::CARD4 c4Styles = pDlgItem->flStyle;
tCIDLib::CARD4 c4Tmp;
tCIDLib::VOID* pClass = (tCIDLib::VOID*)( 0xFFFF0000
| pDlgItem->offClassName);
// Assume no control data
*ppCtlData = 0;
*pc4CtlLen = 0;
if (pClass == WC_BUTTON)
{
//
// Look at the styles to decide exactly what type of button we
// are creating.
//
if (c4Styles & (BS_CHECKBOX | BS_AUTOCHECKBOX))
{
return CIDCLASS("CHECKBOXWND");
}
else if (c4Styles & (BS_RADIOBUTTON | BS_AUTORADIOBUTTON))
{
return CIDCLASS("RADIOBUTTWND");
}
else if (c4Styles & (BS_3STATE | BS_AUTO3STATE))
{
return CIDCLASS("TRIBUTTWND");
}
else
{
return CIDCLASS("PUSHBUTTWND");
}
}
else if (pClass == WC_CONTAINER)
{
return CIDCLASS("CONTAINERWND");
}
else if (pClass == WC_ENTRYFIELD)
{
return CIDCLASS("ENTRYFLDWND");
}
else if (pClass == WC_MLE)
{
return CIDCLASS("MLEWND");
}
else if (pClass == WC_STATIC)
{
//
// Look at the styles and decide what type we really need. Static
// styles are not bits, but are a numeric value embedded into the
// lower 7 bits.
//
c4Tmp = (c4Styles & 0x7FL);
if (c4Tmp == SS_GROUPBOX)
{
return CIDCLASS("GROUPBOXWND");
}
else if (c4Tmp == SS_TEXT)
{
return CIDCLASS("STATTXTWND");
}
else if ((c4Tmp == SS_FGNDRECT) || (c4Tmp == SS_BKGNDRECT))
{
return CIDCLASS("CLRAREAWND");
}
else if ((c4Tmp == SS_ICON) || (c4Tmp == SS_BITMAP))
{
//
// Get the id of the icon and put into the control data. It is
// in the window text in the form #xxx where xxx is the icon
// id.
//
if (pDlgItem->cchText == 0)
{
facCIDGui.LogMsg( __FILE__
, "__clsMapPMClass"
, __LINE__
, "ICONWND or BMPWND text must be "
"in form #xxx"
, tCIDLib::eSEV_PROCESS_FATAL);
}
tCIDLib::CH* pszTmp = new tCIDLib::CH[pDlgItem->cchText+1];
strcpy(pszTmp, (((tCIDLib::CH*)pDlgTmpl)+pDlgItem->offText));
if ((pszTmp[0] != '#') || (strlen(pszTmp) < 2))
{
facCIDGui.LogMsg( __FILE__
, "__clsMapPMClass"
, __LINE__
, "ICONWND or BMPWND text must be "
"in form #xxx"
, tCIDLib::eSEV_PROCESS_FATAL);
}
tCIDLib::CARD4 c4Id = atoi(&pszTmp[1]);
// Allocate the control data and fill it in
*ppCtlData = new tCIDLib::CARD4;
*((tCIDLib::CARD4*)*ppCtlData) = c4Id;
*pc4CtlLen = sizeof(tCIDLib::CARD4);
if (c4Tmp == SS_ICON)
return CIDCLASS("ICONWND");
else
return CIDCLASS("BMPWND");
}
}
else if (pClass == WC_LISTBOX)
{
return CIDCLASS("LISTBOXWND");
}
else if (pClass == WC_NOTEBOOK)
{
return CIDCLASS("NOTEBOOKWND");
}
else if (pClass == WC_SCROLLBAR)
{
return CIDCLASS("SCRBARWND");
}
//
// Was not one of the pre-defined classes, so we need to return it
// as text.
//
tCIDLib::CH* pszClass = (tCIDLib::CH*)pDlgTmpl;
pszClass += pDlgItem->offClassName;
// Make the compiler happy
return CIDCLASS(pszClass);
}
//
// FUNCTION/METHOD NAME: __pfnDlgProc(hwndDlg, c4Msg, mp1, mp2)
//
// DESCRIPTION:
//
// This guy is the dialog proc for all dialogs. Dialogs get some messages
// before the WM_INITDLG so we have to filter those out and pass them to the
// default dialog handler. Once we see that the init dialog has been handled,
// we can start passing messages to the regular handler.
// ---------------------------------------
// INPUT: hwndDlg is the handle of the dialog
// c4Msg is the message being recieved
// mp1, mp2 are the message parameters.
//
// OUTPUT: None
//
// RETURN: Depends upon the message
//
MRESULT WPROCEXP __pfnwpDlgProc(HWND hwndDlg
, tCIDLib::CARD4 c4Msg
, MPARAM mp1
, MPARAM mp2)
{
DIALOGWND* pdlgTmp;
if (c4Msg == WM_INITDLG)
{
WinSetWindowPtr(hwndDlg, QWL_USER, mp2);
return 0;
}
// Get the window data to see if it is set up yet
pdlgTmp = (DIALOGWND*)WinQueryWindowPtr(hwndDlg, QWL_USER);
//
// If it is set up, then check for some messages that we want to handle
// specially. If not one of those, then let it go to the normal handler.
//
if (pdlgTmp)
{
if (c4Msg == WM_CLOSE)
{
WinDismissDlg(hwndDlg, 0xFFFF);
return 0;
}
return _pfnwpMainSub(hwndDlg, c4Msg, mp1, mp2);
}
// Otherwise, we have to let it go to the default handler
return WinDefDlgProc(hwndDlg, c4Msg, mp1, mp2);
}
//
// FUNCTION/METHOD NAME: __pwndMakeCtrl(dlgwParent, clsCtrl, areaCtrl
// , c4Styles, c4Id, pCtlData)
//
// DESCRIPTION:
//
// This method is called (by the constructor) for each control in the dialog
// if the user does not provide a callout, or if the user's callout returns
// 0 to indicate that it wants us to create the control.
// ---------------------------------------
// INPUT: dlgwParent is the parent dialog window that is calling.
// clsCtrl is the class name.
// areaCtrl is the area of the control.
// c4Styles are the style flags.
// c4Id is the id of the control.
// pCtlData is the control data if any. If none, then it is 0.
//
// OUTPUT: None
//
// RETURN: A pointer to the window object created
//
static WINDOW* __pwndMakeCtrl( const DIALOGWND& dlgwParent
, const CIDCLASS& clsCtrl
, const AREA& areaCtrl
, tCIDLib::CARD4 c4Styles
, tCIDLib::CARD4 c4Id
, const tCIDLib::CH* pszText
, const tCIDLib::VOID* pCtlData)
{
//
// Switch on the class name and create the correct type of control. If
// not a supported class type, then abort.
//
tCIDLib::eBOOL bAuto;
if (clsCtrl == CIDCLASS("BMPWND"))
{
// The control data contains the bitmap id
tCIDLib::CARD4 c4BmpId = *(tCIDLib::CARD4*)pCtlData;
return new BMPWND( dlgwParent
, dlgwParent
, tCIDGui::eSTATICSTYLES(c4Styles)
, facCIDGui.wndTOP
, c4BmpId
, areaCtrl
, c4Id);
}
else if (clsCtrl == CIDCLASS("CLRAREAWND"))
{
return new CLRAREAWND( dlgwParent
, dlgwParent
, tCIDGui::eSTATICSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, c4Id);
}
else if (clsCtrl == CIDCLASS("CHECKBOXWND"))
{
bAuto = (c4Styles & BS_AUTOCHECKBOX) ? tCIDLib::eTRUE : tCIDLib::eFALSE;
return new CHECKBOXWND( dlgwParent
, dlgwParent
, tCIDGui::eBUTTSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id
, bAuto);
}
else if (clsCtrl == CIDCLASS("MLEWND"))
{
return new MLEWND( dlgwParent
, dlgwParent
, tCIDGui::eMLESTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id);
}
else if (clsCtrl == CIDCLASS("ENTRYFLDWND"))
{
return new ENTRYFLDWND( dlgwParent
, dlgwParent
, tCIDGui::eEFLDSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id);
}
else if (clsCtrl == CIDCLASS("ICONWND"))
{
// The control data contains the icon id
tCIDLib::CARD4 c4IconId = *(tCIDLib::CARD4*)pCtlData;
return new ICONWND( dlgwParent
, dlgwParent
, tCIDGui::eSTATICSTYLES(c4Styles)
, facCIDGui.wndTOP
, c4IconId
, areaCtrl
, c4Id);
}
else if (clsCtrl == CIDCLASS("GROUPBOXWND"))
{
return new GROUPBOXWND( dlgwParent
, dlgwParent
, tCIDGui::eSTATICSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id);
}
else if (clsCtrl == CIDCLASS("LISTBOXWND"))
{
//
// Pass 0 for height and width of items, this will cause them to be
// set to defaults, which will work for text list box in default
// font.
//
return new LISTBOXWND( dlgwParent
, dlgwParent
, tCIDGui::eLBSTYLES(c4Styles)
, facCIDGui.wndTOP
, 0, 0
, tCIDLib::eDEL_NODELETE
, tCIDLib::eFALSE
, areaCtrl
, c4Id);
}
else if (clsCtrl == CIDCLASS("NOTEBOOKWND"))
{
return new NOTEBOOKWND( dlgwParent
, dlgwParent
, tCIDGui::eBKSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, c4Id);
}
else if (clsCtrl == CIDCLASS("PUSHBUTTWND"))
{
return new PUSHBUTTWND( dlgwParent
, dlgwParent
, tCIDGui::eBUTTSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id);
}
else if (clsCtrl == CIDCLASS("RADIOBUTTWND"))
{
bAuto = (c4Styles & BS_AUTORADIOBUTTON) ?
tCIDLib::eTRUE : tCIDLib::eFALSE;
return new RADIOBUTTWND(dlgwParent
, dlgwParent
, tCIDGui::eBUTTSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id
, bAuto);
}
else if (clsCtrl == CIDCLASS("SCRBARWND"))
{
//
// We give the scroll bar a default range of 0..0 with the current
// value of 0, which will insure that it is disabled until the user
// sets it up.
//
return new SCRBARWND( dlgwParent
, dlgwParent
, tCIDGui::eSBSTYLES(c4Styles)
, facCIDGui.wndTOP
, 0, 0, 0, 0, 0
, areaCtrl
, c4Id);
}
else if (clsCtrl == CIDCLASS("STATTXTWND"))
{
return new STATTXTWND( dlgwParent
, dlgwParent
, tCIDGui::eSTATICSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id);
}
else if (clsCtrl == CIDCLASS("TRIBUTTWND"))
{
bAuto = (c4Styles & BS_AUTO3STATE) ? tCIDLib::eTRUE : tCIDLib::eFALSE;
return new TRIBUTTWND( dlgwParent
, dlgwParent
, tCIDGui::eBUTTSTYLES(c4Styles)
, facCIDGui.wndTOP
, areaCtrl
, STRG256(pszText)
, c4Id
, bAuto);
}
// It failed, so abort
facCIDGui.LogErr( __FILE__
, "DIALOGWND::_MakeCtrl"
, __LINE__
, GUIERR_DLG_TYPE_NOT_SUPPORTED
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_BADPARMS
, clsCtrl);
// Make the compiler happy
return 0;
}
// -----------------------------------------------------------------------------
// CLASS: DIALOGWND
// PREFIX: dlgw
//
// This class is the standard main window class.
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// DIALOGWND: Constructors/Destructors
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: DIALOGWND( wndOwner, c4Id, facSrc, pwndMakeCtrl
// , bDefMenus)
//
// DESCRIPTION:
//
// This is the only constructor for dialog windows. Note that we do not
// subclass the frame here, because we can get the needed control via the
// dialog window mechanism which is really setting up the subclass for us.
// ---------------------------------------
// INPUT: wndOwner is the owner window object.
// c4Id is the id value to give to the window. Defaults to 0.
// facSrc is the facility from which the dialog will be loaded.
// pwndMakeCtrl is the optional callout that the caller can provide
// that will be called for each control. This function should
// create the control object and return a pointer to it. If it
// is 0 or returns 0 for a particular control, then a local
// creation function will be called. It defaults to 0.
// bDefMenus indicates whether the child controls' default popup
// menus should be installed. It defaults to eTRUE.
//
// OUTPUT: None
//
// RETURN: None
//
PROCEXP DIALOGWND::DIALOGWND( const WINDOW& wndOwner
, tCIDLib::CARD4 c4Id
, const CIDFAC& facSrc
, tCIDGui::PFNMAKECTRL pwndMakeCtrl
, tCIDLib::eBOOL bDefMenus) :
FRAMEWND()
, __bModalProcessing(tCIDLib::eFALSE)
{
POINTL aptlMap[2];
tCIDLib::CARD4 c4Children;
HWND hwndOwner, hwndDesktop, hwndTmp;
PCH pchDlgBuf;
PDLGTEMPLATE pDlg;
PDLGTITEM pDlgItem;
tCIDLib::VOID* pDlgRscBuf;
POINTL ptlMouse;
WINDOW* pwndCtrl;
RECTL rectlFrame;
// Store the id away
_c4Id(c4Id);
// We need to know the screen size in a couple of places below
LONG lScrX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
LONG lScrY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
//
// Now we need to load the dialog resource. We will get back a readonly
// memory buffer that we can trash after we have created the dialog.
//
facSrc.LoadResource(tCIDLib::eRSCTYPE_DIALOG, c4Id, &pDlgRscBuf);
//
// Get a pointer to the buffer as a dialog template and start
// interpreting it. The 0th entry in the pDlb->adlgti[] array is the
// record for the dialog itself. All the controls are children of it.
// It contains a field that tells us how many children it has.
//
// Also, get a pointer to the buffer as a character pointer which will be
// used to access data at particular offsets in the buffer.
//
pDlg = (PDLGTEMPLATE)pDlgRscBuf;
pchDlgBuf = (PCH)pDlgRscBuf;
pDlgItem = &(pDlg->adlgti[0]);
c4Children = pDlgItem->cChildren;
//
// According to the styles, the origin is relative to the screen, parent
// window, or mouse. If relative to the mouse, get the mouse position and
// add that to the origin.
//
aptlMap[0].x = pDlgItem->x;
aptlMap[0].y = pDlgItem->y;
aptlMap[1].x = pDlgItem->x + pDlgItem->cx;
aptlMap[1].y = pDlgItem->y + pDlgItem->cy;
// Map the dialog coordinates into window coordinates
WinMapDlgPoints(HWND_DESKTOP, aptlMap, 2, 1);
if (pDlgItem->flStyle & FS_MOUSEALIGN)
{
WinQueryPointerPos(HWND_DESKTOP, &ptlMouse);
aptlMap[0].x += ptlMouse.x;
aptlMap[0].y += ptlMouse.y;
aptlMap[1].x += ptlMouse.x;
aptlMap[1].y += ptlMouse.y;
}
//
// Decide who the owner really is. It is the first window up the parent
// chain that is a direct child of HWND_DESKTOP, or NULL if we don't find
// one. This insures correct disabling of the application's windows when
// the dialog is processed modally.
//
hwndOwner = wndOwner.hwndThis();
hwndDesktop = WinQueryDesktopWindow(WinQueryAnchorBlock(hwndOwner)
, HDC(0));
while (1)
{
hwndTmp = WinQueryWindow(hwndOwner, QW_PARENT);
if (hwndTmp == hwndDesktop)
break;
hwndOwner = hwndTmp;
if (!hwndOwner)
break;
}
//
// Create the frame window that will serve as the dialog frame. Make
// sure that it is initially invisible. The frame creation flags are
// in the dialog tempalte as is the frame text. It is also 0 sized
// and positioned since we don't know these values yet.
//
FRAMECDATA FrameData;
FrameData.cb = sizeof(FrameData);
FrameData.flCreateFlags = *(ULONG*)(pchDlgBuf + pDlgItem->offCtlData);
FrameData.hmodResources = 0;
FrameData.idResources = -1;
_hwndThis( WinCreateWindow(HWND_DESKTOP
, WC_FRAME
, PSZ(pchDlgBuf + pDlgItem->offText)
, pDlgItem->flStyle & ~WS_VISIBLE
, 0
, 0
, 0
, 0
, hwndOwner
, HWND_TOP
, pDlgItem->id
, &FrameData
, 0));
if (!hwndThis())
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr( __FILE__
, "DIALOGWND::DIALOGWND"
, __LINE__
, "WinCreateWindow failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Store the object pointer in the window's spare data
WinSetWindowPtr(hwndThis(), QWL_USER, (tCIDLib::VOID*)((WINDOW*)this));
//
// Calculate the size of a frame that would surround a client area of
// the size of the dialog.
//
rectlFrame.xLeft = aptlMap[0].x;
rectlFrame.yBottom = aptlMap[0].y;
rectlFrame.xRight = aptlMap[1].x;
rectlFrame.yTop = aptlMap[1].y;
WinCalcFrameRect(hwndThis(), &rectlFrame, FALSE);
//
// Make sure that the dialog does not go off of the screen. If so, bring
// it back as long as it would not make the origin go negative.
//
if (rectlFrame.xRight > lScrX)
{
LONG lTmp;
if ((rectlFrame.xLeft - (rectlFrame.xRight-lScrX)) < 0)
lTmp = rectlFrame.xLeft;
else
lTmp = rectlFrame.xRight-lScrX;
rectlFrame.xLeft -= lTmp;
rectlFrame.xRight -= lTmp;
}
if (rectlFrame.yTop > lScrY)
{
LONG lTmp;
if ((rectlFrame.yBottom - (rectlFrame.yTop-lScrY)) < 0)
lTmp = rectlFrame.yBottom;
else
lTmp = rectlFrame.yTop-lScrY;
rectlFrame.yBottom -= lTmp;
rectlFrame.yTop -= lTmp;
}
// Now size the frame to the calculated size
WinSetWindowPos(hwndThis()
, 0
, rectlFrame.xLeft
, rectlFrame.yBottom
, (rectlFrame.xRight-rectlFrame.xLeft)
, (rectlFrame.yTop-rectlFrame.yBottom)
, SWP_SIZE | SWP_MOVE);
//
// Use pres params to make the frame window paint its background using
// the dialog background color, not the usual window color.
//
LONG lTmp = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0);
WinSetPresParam(hwndThis()
, PP_BACKGROUNDCOLOR
, sizeof(LONG)
, &lTmp);
// Force the frame to update it's controls
WinSendMsg(hwndThis(), WM_UPDATEFRAME, MPARAM(FrameData.flCreateFlags), 0);
//
// Set the default handler to the PM frame proc. If the c4Process()
// method is called later, we will change this to the default dialog
// proc.
//
_pfnWndProc(WinSubclassWindow(hwndThis(), _pfnwpMainSub));
if (!_pfnWndProc())
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr(__FILE__
, "DIALOGWND::DIALOGWND"
, __LINE__
, "WinSubclassWindow failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
//
// Query the size of the border. Since dialogs don't have a client
// window, we have to offset all of the control origins by the width
// of the dialog border.
//
WPOINT wpntBorder;
WinSendMsg(hwndThis(), WM_QUERYBORDERSIZE, MPARAM(&wpntBorder), 0);
//
// Now loop through the children and create window objects for each one.
// We call the callout routine for each one to do the creation. This
// allows derived classes to handle the creation.
//
// Before we enter the loop, bump up the dialog item pointer to point to
// the last child. This is because of the way that the WS_GROUP style is
// used. Creating the children in reverse will cause the groups to work
// correctly.
//
CIDCLASS clsCtrl("");
tCIDLib::VOID* pCtlData;
tCIDLib::CARD4 c4CtlLen;
tCIDLib::CH* pszText;
pDlgItem += c4Children;
for (tCIDLib::INT4 i4Ind = c4Children-1; i4Ind >= 0; i4Ind--)
{
//
// Make the dialog coordinates into window coordinates. Make sure to
// add in the border width to the origin.
//
aptlMap[0].x = pDlgItem->x+wpntBorder.x;
aptlMap[0].y = pDlgItem->y+wpntBorder.y;
aptlMap[1].x = pDlgItem->cx;
aptlMap[1].y = pDlgItem->cy;
WinMapDlgPoints(HWND_DESKTOP, aptlMap, 2, 1);
// Get the class name and control data
clsCtrl = __clsMapPMClass(pDlg, pDlgItem, &pCtlData, &c4CtlLen);
// Get a pointer to the text, if any
pszText = 0;
if (pDlgItem->cchText)
pszText = (tCIDLib::CH*)(pchDlgBuf+pDlgItem->offText);
//
// Now we call the user's callout (if he provided one). If not, or his
// returns 0, we call the local default.
//
pwndCtrl = 0;
if (pwndMakeCtrl)
{
pwndCtrl = pwndMakeCtrl(*this
, clsCtrl
, AREA( aptlMap[0].x
, aptlMap[0].y
, aptlMap[1].x
, aptlMap[1].y)
, pDlgItem->flStyle
, pDlgItem->id
, pszText
, pCtlData);
}
if (!pwndCtrl)
{
//
// We can tell PM controls because the class name length is 0.
// This is possible because the PM classes are numeric, not
// text.
//
if (pDlgItem->cchClassName != 0)
{
// Just log a message and go to the next child
facCIDGui.LogErr( __FILE__
, "DIALOGWND::DIALOGWND"
, __LINE__
, GUIERR_DLG_TYPE_NOT_SUPPORTED
, tCIDLib::eSEV_WARNING
, tCIDLib::eCLASS_BADPARMS
, STRG128((tCIDLib::CH*)(pchDlgBuf+pDlgItem->offClassName)));
pDlgItem--;
continue;
}
pwndCtrl =
__pwndMakeCtrl( *this
, clsCtrl
, AREA( aptlMap[0].x
, aptlMap[0].y
, aptlMap[1].x
, aptlMap[1].y)
, pDlgItem->flStyle
, pDlgItem->id
, pszText
, pCtlData);
}
// Now apply the default menu if we need to
if (bDefMenus)
pwndCtrl->SetDefMenu();
//
// Now, if there are any presentation parameters, set them on
// the window. We don't know how many parms but know the size of
// the parm buffer. So we track the count of bytes processed and
// fall out when we exceed the amount available.
//
if (pDlgItem->offPresParams != tCIDLib::c2MAXCARD)
{
tCIDLib::CARD4 c4ByteCnt = 8;
PARAM* pParm;
PRESPARAMS* pPresParms;
pPresParms = (PRESPARAMS*)(pchDlgBuf+pDlgItem->offPresParams);
pParm = (PARAM*)(pchDlgBuf+(pDlgItem->offPresParams+4));
while (c4ByteCnt < pPresParms->cb)
{
if (!WinSetPresParam( *pwndCtrl
, pParm->id
, pParm->cb
, (tCIDLib::VOID*)pParm->ab))
{
facCIDGui.LogLastSysErr(__FILE__
, "DIALOGWND::DIALOGWND"
, __LINE__
, "WinSetPresParam failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Move to the next param
pParm = (PARAM*)(((tCIDLib::CARD1*)pParm) + 8 + pParm->cb);
// Bump up the count of bytes processed.
c4ByteCnt += 8 + pParm->cb;
}
}
//
// Delete the control data, if any. The control will have made its
// own copy of the data.
//
if (pCtlData)
delete pCtlData;
//
// If this is the index of the control that is to get the initial
// focus, then give it the focus now.
//
if (pDlg->iItemFocus == i4Ind)
pwndCtrl->TakeFocus();
// Move to the next child
pDlgItem--;
}
//
// If there was no focus item, then we have to pick one. So look for
// the first tab item.
//
if (pDlg->iItemFocus == 0xFFFF)
{
WinSetFocus(HWND_DESKTOP
, WinEnumDlgItem( *this
, 0
, EDI_FIRSTTABITEM));
}
// Activate the frame
Activate();
// Free the dialog template buffer now since we are done with it
facCIDLib.FreeResource(pDlgRscBuf);
}
//
// FUNCTION/METHOD NAME: ~DIALOGWND()
//
// DESCRIPTION:
//
// The destructor does not need to do anything at this time.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
PROCEXP DIALOGWND::~DIALOGWND()
{
}
// -----------------------------------------------------------------------------
// DIALOGWND: Public, inherited methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: FormatToStr(strbDest) const
//
// DESCRIPTION:
//
// This method will format this object to the passed string buffer. For this
// class, we just format some debug info since this guy has no outwardly
// visible data members.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: strbDest is the string buffer to format into.
//
// RETURN: None
//
tCIDLib::VOID PROCEXP DIALOGWND::FormatToStr(STRGBUF& strbDest) const
{
strbDest << "Duh?";
}
// -----------------------------------------------------------------------------
// DIALOGWND: Public, virtual methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: c4Process()
//
// DESCRIPTION:
//
// This method will process the dialog window modally.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: The value passed to the Dismiss() method will be returned.
//
tCIDLib::CARD4 PROCEXP DIALOGWND::c4Process()
{
// Set the modal processing flag
__bModalProcessing = tCIDLib::eTRUE;
// Change the default proc to the default dialog proc
_pfnWndProc(WinDefDlgProc);
// Process the dialog
tCIDLib::CARD4 c4Ret = WinProcessDlg(*this);
return c4Ret;
}
//
// FUNCTION/METHOD NAME: Dismiss(c4RetStatus)
//
// DESCRIPTION:
//
// This method will dismiss the dialog window, which should currently be in
// a modal processing state. If not, a fatal error will be generated.
// ---------------------------------------
// INPUT: c4RetStatus is returned to the thread that called c4Process() as
// the return value of c4Process().
//
// OUTPUT: None
//
// RETURN: The return status that should be passed back to the caller of
// c4Process().
//
tCIDLib::VOID PROCEXP DIALOGWND::Dismiss(tCIDLib::CARD4 c4RetStatus)
{
if (!__bModalProcessing)
{
facCIDGui.LogMsg( __FILE__
, "DIALOGWND::Dismiss"
, __LINE__
, "Dialog was not being modally processed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Clear the modal processing flag
__bModalProcessing = tCIDLib::eFALSE;
// Dismiss the dialog
if (!WinDismissDlg(*this, c4RetStatus))
{
facCIDGui.LogLastSysErr(__FILE__
, "DIALOGWND::Dismiss"
, __LINE__
, "Dialog dismiss failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
// -----------------------------------------------------------------------------
// DIALOGWND: Protected, inherited methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: _bIsEqual(objTarget) const
//
// DESCRIPTION:
//
// This method will see if this object is equal to the passed object. If the
// passed object is not a DIALOGWND object, then eFALSE is returned, else the
// data members are compared.
// ---------------------------------------
// INPUT: objTarget is the target object to compare against
//
// OUTPUT: None
//
// RETURN: eTRUE if the objects are equal, else eFALSE.
//
tCIDLib::eBOOL PROCEXP DIALOGWND::_bIsEqual(const CIDOBJECT& objTarget) const
{
//
// Call our parent's version first. We call it regardless of the depth of
// the comparison
//
if (!FRAMEWND::_bIsEqual(objTarget))
return tCIDLib::eFALSE;
// Look at the object as a DIALOGWND object
return tCIDLib::eTRUE;
}