home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
deans.zip
/
WINDOW.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-14
|
84KB
|
2,678 lines
//
// NAME: CIDLib_Window.Cpp
//
// DESCRIPTION:
//
// This module implements the WINDOW class. This is a virtual class that is
// the basis for all other window classes. It provides all of the general
// window operations that act the same on all windows.
//
//
// AUTHOR: Dean Roddey
//
// CREATE DATE: 04/11/93
//
// COPYRIGHT: 1992..1994, 'CIDCorp
//
// CAVEATS/GOTCHAS:
//
// 1) Most of the time in here, the __hwndThis member is used for
// efficiency, when calling system calls. But, be sure to pass *this
// when the call is to a CIDLib method because it wants the real window
// and will try to reconstruct one from the window handle (and destroy
// the window when the surrogate object is destroyed.
//
// MODIFICATION LOG:
//
// -----------------------------------------------------------------------------
// Local defines
// -----------------------------------------------------------------------------
#define CIDGUI_WINDOW_CPP
#define INCL_GPILCIDS
#define INCL_GPILOGCOLORTABLE
#define INCL_GPIREGIONS
#define INCL_WINCURSORS
#define INCL_WINDIALOGS
#define INCL_WINFRAMEMGR
#define INCL_WININPUT
#define INCL_WINMENUS
#define INCL_WINMESSAGEMGR
#define INCL_WINWINDOWMGR
#define INCL_WINSYS
#define INCL_CIDLIB_MEMORY
#define INCL_CIDLIB_METRICS
#define INCL_CIDLIB_TEXTFILES
#define INCL_CIDGUI_ERRORIDS
#define INCL_CIDGUI_FACOBJECT
#define INCL_CIDGUI_GRAPHICS
#define INCL_CIDGUI_MENUS
#define INCL_CIDGUI_WINDOWS
// -----------------------------------------------------------------------------
// Facility specific includes
//
// CIDGui_.Hpp
// We just need the internal facility header
// -----------------------------------------------------------------------------
#include "CIDGui_.Hpp"
// -----------------------------------------------------------------------------
// Local data
// -----------------------------------------------------------------------------
tCIDLib::CH* __apszMClkDesc[] = {
"Button1Down"
, "Button1Up"
, "Button1Click"
, "Button1DblClk"
, "Button2Down"
, "Button2Up"
, "Button2Click"
, "Button2DblClk"
, "Button3Down"
, "Button3Up"
, "Button3Click"
, "Button3DblClk"
, "Chord"
};
const tCIDLib::CARD4 c4MClkMax = (sizeof(__apszMClkDesc)
/sizeof(__apszMClkDesc[0]));
// -----------------------------------------------------------------------------
// Global functions
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: operator<<(strbDest, eMsClk)
//
// DESCRIPTION:
//
// This method will format the passed mouse click into the passed string
// buffer.
// ---------------------------------------
// INPUT: eMsClk is the mouse click to format
//
// OUTPUT: strbDest is the string object to format into
//
// RETURN: A reference to the string buffer
//
STRGBUF& PROCEXP operator<<(STRGBUF& strbDest, tCIDGui::eMOUSECLKS eMsClk)
{
// Check for valid ranges
if (((eMsClk != tCIDGui::eMCLK_CHORD)
&& (eMsClk != tCIDGUi::eMCLK_BUTTON1CLICK)
&& (eMsClk != tCIDGUi::eMCLK_BUTTON2CLICK)
&& (eMsClk != tCIDGUi::eMCLK_BUTTON3CLICK))
|| ((eMsClk < tCIDGUi::eMCLK_BUTTON1DOWN)
|| (eMsClk > tCIDGUi::eMCLK_BUTTON3DBLCLK)))
{
facCIDGui.LogErr( __FILE__
, "operator<<"
, __LINE__
, GUIERR_GEN_NOT_VALID_VALUE
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_BADPARMS
, INTEGER(eMsClk)
, STRG16("Mouse Click"));
}
// Format the string, adjusting the index to make it 0 based.
strbDest << __apszMClkDesc[eMsClk-tCIDGui::eMCLK_BUTTON1DOWN];
return strbDest;
}
OTXTFILE& PROCEXP operator<<(OTXTFILE& otfDest, tCIDGui::eMOUSECLKS eMsClk)
{
STRG64 strTmp;
strTmp << eMsClk;
otfDest << strTmp;
return otfDest;
}
// -----------------------------------------------------------------------------
// Local functions
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: __pfnwpMainClass(hwndThis, c4Msg, mp1, mp2)
//
// DESCRIPTION:
//
// This method is window proc used to register the standard window class. It
// exists just to eat the messages that arrive before the window can be
// subclassed to _pfnwpMainSub(), below.
// ---------------------------------------
// INPUT: hwndThis is the handle to the window
// c4Msg is the message being received
// mp1, mp2 are the message parms.
//
// OUTPUT: None
//
// RETURN: None
//
static MRESULT EXPENTRY __pfnwpMainClass( HWND hwndThis
, tCIDLib::CARD4 c4Msg
, MPARAM mp1
, MPARAM mp2)
{
if (c4Msg == WM_CREATE)
return 0;
return WinDefWindowProc(hwndThis, c4Msg, mp1, mp2);
}
// -----------------------------------------------------------------------------
// Intrafacility functions (Prototypes are in CIDGui_.Hpp)
//
// _bInitWindow
// This is the initialization function for this module. It is called from
// the constructor of the facility object.
//
// __pfnwpMainClass
// This is the window proc for all windows. It serves as the switch box
// for all messages to make sure that they are handled correctly and get
// to the right place.
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: _bInitWindow(habInit)
//
// DESCRIPTION:
//
// This method is called from the facility object's constructor. It handles
// doing any local module initialization. In this case, we want to get some
// PM information and store it away and register our primary window class.
// ---------------------------------------
// INPUT: habInit is an anchor block to use for initialization
//
// OUTPUT: None
//
// RETURN: eTRUE if successful, else eFALSE.
//
tCIDLib::eBOOL _bInitWindow(HAB habInit)
{
// Register the window class
if (!WinRegisterClass( habInit
, _szCIDGuiClass
, __pfnwpMainClass
, CS_SIZEREDRAW
| CS_MOVENOTIFY
, sizeof(tCIDLib::VOID*)))
{
//
// DO NOT call LogLastSysErr() because it might depend upon something
// that is not initialized yet. LogMsg() is inherited from the basic
// facility class (in CIDLib.Dll) so it is safe.
//
ERRORID ErrId = WinGetLastError(habInit);
facCIDGui.LogMsg( __FILE__
, "_bInitWindow"
, __LINE__
, "Could not register CIDGui window class. Err=%(1)"
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_INTERNAL
, CARDINAL(ErrId & 0x7FFF));
}
// Went ok so return true
return tCIDLib::eTRUE;
}
//
// FUNCTION/METHOD NAME: _pfnwpMainSub(hwndThis, c4Msg, mp1, mp2)
//
// DESCRIPTION:
//
// This guy gets all messages first. It handles some without giving them to
// anyone. The rest are first passed on to the class to be handled. If it
// does not handle the message, then it is passed to the original window
// procedure for PM controls or to the default window proc for others.
// ---------------------------------------
// INPUT: hwndThis is the handle to the window
// c4Msg is the message being received
// mp1, mp2 are the message parms.
//
// OUTPUT: None
//
// RETURN: None
//
MRESULT EXPENTRY _pfnwpMainSub( HWND hwndThis
, tCIDLib::CARD4 c4Msg
, MPARAM mp1
, MPARAM mp2)
{
// Get a pointer to the window data, which is a pointer to the object
WINDOW* pThis = (WINDOW*)WinQueryWindowPtr(hwndThis, QWL_USER);
// If it is null, then a major error, so abort.
if (!pThis)
{
facCIDGui.LogMsg( __FILE__
, "__pfnwpMainSub"
, __LINE__
, "Window data did not point to this"
, tCIDLib::eSEV_PROCESS_FATAL);
// Make compiler happy
return 0;
}
// Call the message handler for this guy
return pThis->_mresHandleMsg(hwndThis, c4Msg, mp1, mp2);
}
// -----------------------------------------------------------------------------
// CLASS: WINDOW
// PREFIX: wnd
//
// This class is the base window class.
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// WINDOW: Constructors/Destructors
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: WINDOW(wndParent, wndOwner, eStyle, wndBehind
// , areaInit, strbText, c4Id, pfnWndProc)
//
// DESCRIPTION:
//
// This is the only constructor for windows. The derived class provides us
// with the particulars and we create the window. The bPMPaint member is set
// to eFALSE here since that is by far the most used mode.
// ---------------------------------------
// INPUT: wndParent is the parent window object
// wndOwner is the owner window. Can be facGUI.wndNONE if no owner is
// desired.
// eStyle is the window style flags. It will be at least the eWS_xxxx
// flags, but mostly it will be the styles of the derived type,
// which is a super set of the eWS_xxxx styles.
// wndBehind is the window behind which the new window should be
// inserted. This can be one of the special windows
// facCIDGui.wndTOP or facCIDGui.wndBOTTOM.
// areaInit is the initial size and position to give to the window.
// Defaults to 0,0,0,0.
// strbText is the window text for this window. Defaults to "".
// c4Id is the id value to give to the window. Defaults to 0.
// pfnWndProc is for the existing PM controls which already have a
// window procedure. The derived classes which implement these
// controls will pass the correct window procedure here. Others
// should pass 0, which is the default.
//
// OUTPUT: None
//
// RETURN: None
//
PROCEXP WINDOW::WINDOW( const WINDOW& wndParent
, const WINDOW& wndOwner
, tCIDGui::eWNDSTYLES eStyle
, const WINDOW& wndBehind
, const AREA& areaInit
, const STRGBUF& strbText
, tCIDLib::CARD4 c4Id
, PFNWP pfnWndProc) :
__bDestructing(tCIDLib::eFALSE)
, __bMouseCaptured(tCIDLib::eFALSE)
, __bPMPaint(tCIDLib::eFALSE)
, __c4Id(c4Id)
, __hwndThis(0)
, __pfnWndProc(0)
, __pmenuThis(0)
, __strWndText(strbText, strbText.c4Length())
{
//
// Save away the passed window proc. If it is 0, then set it to the
// default window proc
//
if (pfnWndProc)
__pfnWndProc = pfnWndProc;
else
__pfnWndProc = WinDefWindowProc;
// Try to create the window
__hwndThis = WinCreateWindow( wndParent
, _szCIDGuiClass
, strbText.pSZ()
, eStyle
, areaInit.i4X()
, areaInit.i4Y()
, LONG(areaInit.c4CX())
, LONG(areaInit.c4CY())
, wndOwner
, wndBehind
, c4Id
, 0
, 0);
if (!__hwndThis)
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW"
, __LINE__
, __strWndText
, tCIDLib::eSEV_PROCESS_FATAL);
}
WinSubclassWindow(__hwndThis, _pfnwpMainSub);
WinSetWindowPtr(__hwndThis, QWL_USER, this);
// Bump up the window count in the core metrics
_pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
}
//
// FUNCTION/METHOD NAME: WINDOW(hwndWnd)
//
// DESCRIPTION:
//
// This contructor is provided to create window objects from existing
// windows. This gets all of the needed information from the pased window
// handle. It checks for the special window handles so that this
// constructor can be used to create objects for the special windows.
// ---------------------------------------
// INPUT: hwndWnd is the handle to the window
//
// OUTPUT: None
//
// RETURN: None
//
PROCEXP WINDOW::WINDOW(HWND hwndWnd) :
__bDestructing(tCIDLib::eFALSE)
, __bMouseCaptured(tCIDLib::eFALSE)
, __bPMPaint(tCIDLib::eFALSE)
, __c4Id(WinQueryWindowUShort(hwndWnd, QWS_ID))
, __hwndThis(hwndWnd)
, __pfnWndProc(0)
, __pmenuThis(0)
{
// Check for the special window handles. If so, then we are done
if ((hwndWnd == HWND_DESKTOP)
|| (hwndWnd == HWND_OBJECT)
|| (hwndWnd == HWND_TOP)
|| (hwndWnd == HWND_BOTTOM)
|| (hwndWnd == HWND(0)))
{
// Bump up the window count in the core metrics
_pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
return;
}
//
// If there is a window handle, then subclass it. If it is already
// subclassed to our window proc, then abort.
//
if (__hwndThis)
{
PFNWP pfnTmp = (PFNWP)WinQueryWindowPtr(__hwndThis, QWP_PFNWP);
if (pfnTmp == _pfnwpMainSub)
{
facCIDGui.LogMsg( __FILE__
, "WINDOW"
, __LINE__
, "Window was already subclassed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
__pfnWndProc = WinSubclassWindow(__hwndThis, _pfnwpMainSub);
// Store the object pointer in the window's spare data
WinSetWindowPtr(__hwndThis, QWL_USER, (tCIDLib::VOID*)(WINDOW*)this);
// Make sure that the subclass went ok. If not, we gotta abort.
if (!__pfnWndProc)
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW"
, __LINE__
, "WinSubclass failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
// Bump up the window count in the core metrics
_pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
}
PROCEXP WINDOW::WINDOW() :
__bDestructing(tCIDLib::eFALSE)
, __bMouseCaptured(tCIDLib::eFALSE)
, __bPMPaint(tCIDLib::eFALSE)
, __c4Id(0)
, __hwndThis(0)
, __pfnWndProc(0)
, __pmenuThis(0)
{
// Bump up the window count in the core metrics
_pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
}
//
// FUNCTION/METHOD NAME: ~WINDOW()
//
// DESCRIPTION:
//
// This is the destructor for WINDOW objects. It just calls
// WinDestroyWindow() for the window handle if it is not HWND(0). This
// will cause the destroy method to be called so that the derived window
// class can clean up.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
PROCEXP WINDOW::~WINDOW()
{
//
// If the handle is filled in then destroy it. This will cause the
// destructor to be called.
//
if (__hwndThis)
{
//
// We need to destroy the window, but make sure that they WM_DESTROY
// message knows that it does not have to in turn call the
// destructor. So, set the __bDestructing flag, then destroy the
// window.
//
__bDestructing = tCIDLib::eTRUE;
WinDestroyWindow(__hwndThis);
// Now we can waste the handle
__hwndThis = 0;
}
// If there is a menu then destroy it
if (__pmenuThis)
delete __pmenuThis;
// Bump down the window count in the core metrics
_pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, -1);
}
// -----------------------------------------------------------------------------
// WINDOW: 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 WINDOW::FormatToStr(STRGBUF& strbDest) const
{
strbDest << "Id=" << __c4Id
<< ", HWND=" << CARDINAL(__hwndThis, tCIDLib::eRADIX_HEX);
}
// -----------------------------------------------------------------------------
// WINDOW: Public, virtual methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: bPaint(areaInvalid, ptbTarget)
//
// DESCRIPTION:
//
// This is the default paint method if the derived class does not handle it.
// We just do an erase of the invalid area.
// ---------------------------------------
// INPUT: areaInvalid is the invalid area. We don't use it here.
// ptbTarget is a painting object that is set up to paint on this
// window. We just fill the invalid area.
//
// OUTPUT: None
//
// RETURN: eTRUE to indicate that we handled it and it should not be passed
// to the default handler.
//
tCIDLib::eBOOL PROCEXP WINDOW::bPaint( const AREA& areaInvalid
, PAINTBRUSH& ptbTarget)
{
// Make the compiler happy
areaInvalid;
// Do the erase
if (!GpiErase(ptbTarget))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::bPaint"
, __LINE__
, "GpiErase failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
return tCIDLib::eTRUE;
}
//
// FUNCTION/METHOD NAME: bPopUpMenu(pntPos)
//
// DESCRIPTION:
//
// This menu will popup the menu for this window, if any.
// ---------------------------------------
// INPUT: pntPos is the position to place the lower left corner of the menu
//
// OUTPUT: None
//
// RETURN: eTRUE if successful, else eFALSE.
//
tCIDLib::eBOOL PROCEXP WINDOW::bPopUpMenu(const POINT& pntPos)
{
if (!__pmenuThis)
return tCIDLib::eFALSE;
// Get the parent of this window for the parent of the menu
WINDOW& wndCtlParent = wndParent();
// Translate the point to the parent's coordinates
POINT pntTmp(pntPos);
wndCtlParent.TranslateCoord(pntTmp, *this);
//
// Now popup the menu. Be sure to pass *this, not the raw handle,
// because that will create a new window object.
//
__pmenuThis->PopUp(wndCtlParent, *this, pntTmp);
return tCIDLib::eTRUE;
}
//
// FUNCTION/METHOD NAME: SetMenu(pwndNewMenu, bDestroyOldMenu)
//
// DESCRIPTION:
//
// This menu will install the passed menu object as the top level menu for
// this window object.
// ---------------------------------------
// INPUT: wndNewMenu is a pointer to the new pop up menu object to install
// bDestroyOldMenu, if eTRUE, will cause the currently installed
// menu object to be destroyed.
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::SetMenu( POPUPMENU* pmenuNew
, tCIDLib::eBOOL bDestroyOldMenu)
{
//
// If there is a current menu object, then we need to destroy it if
// bDestroyOldMenu is eTRUE. If not, then do nothing. We will overwrite
// its pointer with the new menu object.
//
if (bDestroyOldMenu && __pmenuThis)
{
delete __pmenuThis;
__pmenuThis = 0;
}
// Store away the pointer to the menu
__pmenuThis = pmenuNew;
}
// -----------------------------------------------------------------------------
// WINDOW: Public, non-virtual methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: areaWnd() const
//
// DESCRIPTION:
//
// Returns the area of the window object. It will contain the size and
// position relative to its parent.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: The area of the window
//
AREA PROCEXP WINDOW::areaWnd() const
{
SWP swpTmp;
if (!WinQueryWindowPos(__hwndThis, &swpTmp))
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::areaWnd"
, __LINE__
, "WinQueryWindowPos"
, tCIDLib::eSEV_PROCESS_FATAL);
}
return AREA(swpTmp);
}
//
// FUNCTION/METHOD NAME: areaSize() const
//
// DESCRIPTION:
//
// Returns the size of the window object. This is just like areaWnd()
// except that it returns a 0 based area regardless of the position of the
// window relative to its parent.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: The size of the window
//
AREA PROCEXP WINDOW::areaWndSize() const
{
AREA areaTmp;
SWP swpTmp;
if (!WinQueryWindowPos(__hwndThis, &swpTmp))
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::areaWndSize"
, __LINE__
, "WinQueryWindowPos failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
swpTmp.x = 0;
swpTmp.y = 0;
return AREA(swpTmp);
}
//
// FUNCTION/METHOD NAME: bGotFocus() const
//
// DESCRIPTION:
//
// This method will return eTRUE if this window object has the focus, else
// eFALSE.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: eTRUE if this window has the focus, else eFALSE.
//
tCIDLib::eBOOL PROCEXP WINDOW::bGotFocus() const
{
if (WinQueryFocus(HWND_DESKTOP) == __hwndThis)
return tCIDLib::eTRUE;
else
return tCIDLib::eFALSE;
}
//
// FUNCTION/METHOD NAME: bIsChildWindow(wndTest)
//
// DESCRIPTION:
//
// This method will test the passed window to see if it is a descendant
// (not necessarily a direct child) of this window.
// ---------------------------------------
// INPUT: wndTest is the window to test for childhood
//
// OUTPUT: None
//
// RETURN: eTRUE if the passed window is a child, else eFALSE.
//
tCIDLib::eBOOL PROCEXP WINDOW::bIsChildWindow(const WINDOW& wndTest)
{
if (WinIsChild(wndTest, __hwndThis))
return tCIDLib::eTRUE;
else
return tCIDLib::eFALSE;
}
//
// FUNCTION/METHOD NAME: bIsEnabled() const
//
// DESCRIPTION:
//
// This method will return a boolean that indicates whether this window is
// enabled or not.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: eTRUE if enabled, else eFALSE.
//
tCIDLib::eBOOL PROCEXP WINDOW::bIsEnabled() const
{
if (WinIsWindowEnabled(__hwndThis))
return tCIDLib::eTRUE;
else
return tCIDLib::eFALSE;
}
//
// FUNCTION/METHOD NAME: bIsShowing() const
//
// DESCRIPTION:
//
// This method will return a flag that indicates whether any portion of
// this window is showing or not. This is not the same as the window's
// visibility state, which hides or shows the window. This flag indicates
// when the window, even if it is visible, might be totally covered up.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: eTRUE if visible, else eFALSE.
//
tCIDLib::eBOOL PROCEXP WINDOW::bIsShowing() const
{
if (WinIsWindowShowing(__hwndThis))
return tCIDLib::eTRUE;
else
return tCIDLib::eFALSE;
}
//
// FUNCTION/METHOD NAME: bIsVisible() const
//
// DESCRIPTION:
//
// This method will return the visibility status of this window
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: eTRUE if visible, else eFALSE.
//
tCIDLib::eBOOL PROCEXP WINDOW::bIsVisible() const
{
if (WinIsWindowVisible(__hwndThis))
return tCIDLib::eTRUE;
else
return tCIDLib::eFALSE;
}
//
// FUNCTION/METHOD NAME: bQueryPresColor(ePresClr, rgbClr)
//
// DESCRIPTION:
//
// This method will look for the indicated presentation color for this
// window. If one has not been set, then the caller should query the
// appropriate system color.
// ---------------------------------------
// INPUT: ePresClr is the presentation color to query
//
// OUTPUT: rgbClr is filled in with the color, if found. If the return
// value is eFALSE, then it is unchanged.
//
// RETURN: eTRUE if the presentation color was available, else eFALSE.
//
tCIDLib::eBOOL
PROCEXP WINDOW::bQueryPresColor(tCIDGui::ePRESCLRS ePresClr
, RGBCLR& rgbClr) const
{
tCIDLib::CARD4 c4Found;
tCIDLib::INT4 i4Value;
if (!WinQueryPresParam( __hwndThis
, ePresClr
, 0
, &c4Found
, sizeof(i4Value)
, &i4Value
, QPF_NOINHERIT))
{
return tCIDLib::eFALSE;
}
rgbClr = i4Value;
return tCIDLib::eTRUE;
}
//
// FUNCTION/METHOD NAME: bQueryWndColor(ePresClr, eSysClr, rgbResult)
//
// DESCRIPTION:
//
// This method will try to find the passed presparam color first, then the
// the passed system color. It will return the first one found.
// ---------------------------------------
// INPUT: ePresClr is the desired presparam color
// eSysClr is the desired system color that will be used if the
// presparam color is not set.
//
// OUTPUT: rgbResult is filled in with the color
//
// RETURN: eTRUE if the presparam color was found, else eFALSE if the system
// color was found.
//
tCIDLib::eBOOL WINDOW::bQueryWndColor( tCIDGui::ePRESCLRS ePresClr
, tCIDGui::eSYSCOLORS eSysClr
, RGBCLR& rgbResult) const
{
tCIDLib::CARD4 c4Found;
tCIDLib::INT4 i4Clr;
// Try the presparam first
if (WinQueryPresParam( __hwndThis
, ePresClr
, 0
, &c4Found
, sizeof(i4Clr)
, &i4Clr
, QPF_NOINHERIT))
{
rgbResult = i4Clr;
return tCIDLib::eTRUE;
}
// Did not get it so try the system color
i4Clr = WinQuerySysColor(HWND_DESKTOP, eSysClr, 0);
rgbResult = i4Clr;
return tCIDLib::eFALSE;
}
//
// FUNCTION/METHOD NAME: c4WindowTextLen() const
//
// DESCRIPTION:
//
// This method will return the length of the winodw text.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: The length of the window text.
//
tCIDLib::CARD4 PROCEXP WINDOW::c4WindowTextLen() const
{
return tCIDLib::CARD4(WinQueryWindowTextLength(__hwndThis));
}
//
// FUNCTION/METHOD NAME: CaptureMouse()
//
// DESCRIPTION:
//
// Calling this message will allow this window to receive all mouse input
// messages until ReleaseMouse() is called. It should be used with
// restraint. Of course, since it affects a global resource.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::CaptureMouse()
{
if (!WinSetCapture(HWND_DESKTOP, __hwndThis))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::CaptureMouse"
, __LINE__
, "WinSetCapture failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
__bMouseCaptured = tCIDLib::eTRUE;
}
//
// FUNCTION/METHOD NAME: Disable()
//
// DESCRIPTION:
//
// This method will disable the window
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::Disable()
{
if (!WinEnableWindow(__hwndThis, 0))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::Disable"
, __LINE__
, "WinEnableWindow"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Repaint the window
ForceRepaint();
}
//
// FUNCTION/METHOD NAME: Enable()
//
// DESCRIPTION:
//
// This method will enable the window
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::Enable()
{
if (!WinEnableWindow(__hwndThis, 1))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::Enable"
, __LINE__
, "WinEnableWindow"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Repaint the window
ForceRepaint();
}
//
// FUNCTION/METHOD NAME: ExitMsgLoop()
//
// DESCRIPTION:
//
// This method will post a quit message to the message loop to cause it to
// exit.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::ExitMsgLoop()
{
if (!WinPostMsg(__hwndThis, WM_QUIT, 0, 0))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::ExitMsgLoop"
, __LINE__
, "Could not post WM_QUIT"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: eWndStyles() const
//
// DESCRIPTION:
//
// This method will return the current window styles. We get them from PM.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: The current window styles.
//
tCIDGui::eWNDSTYLES PROCEXP WINDOW::eWndStyles() const
{
return tCIDGui::eWNDSTYLES(WinQueryWindowULong(__hwndThis, QWL_STYLE));
}
//
// FUNCTION/METHOD NAME: eWndStyles(eNewStyles, eRelevant)
//
// DESCRIPTION:
//
// This method will set the window styles. Derived classes provide their
// own method to set their styles, but they just cast their styles to
// window styles and call this method.
// ---------------------------------------
// INPUT: eNewStyles is the new styles to set
// eRelevant is the mask that indicates which bits in eNewStyles
// are to be set.
//
// OUTPUT: None
//
// RETURN: The current window styles
//
tCIDGui::eWNDSTYLES PROCEXP
WINDOW::eWndStyles( tCIDGui::eWNDSTYLES eNewStyles
, tCIDGui::eWNDSTYLES eRelevant)
{
// Query the current PM styles.
tCIDLib::CARD4 c4PMStyles = WinQueryWindowULong(__hwndThis, QWL_STYLE);
//
// Turn off the relevant bits. This means we only have to reset those
// that the user wants set. The cleared state is now a default.
//
c4PMStyles &= ~tCIDLib::CARD4(eRelevant);
tCIDLib::CARD4 c4Mask = 0x1;
for (tCIDLib::CARD4 c4Ind = 0; c4Ind < 31; c4Ind++)
{
if (eRelevant & c4Mask)
{
if (eNewStyles & c4Mask)
c4PMStyles |= c4Mask;
}
c4Mask <<= 1;
}
//
// We now need to write back out the PM style flags.
//
if (!WinSetWindowULong(__hwndThis, QWL_STYLE, c4PMStyles))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::eWndStyles"
, __LINE__
, "WinSetWindowULong failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Return the new styles
return tCIDGui::eWNDSTYLES(c4PMStyles);
}
//
// FUNCTION/METHOD NAME: ForceRepaint(bChildrenToo)
//
// DESCRIPTION:
//
// This method will invalidate the whole window causing its paint method to
// be called.
// ---------------------------------------
// INPUT: bChildrenToo indicates whether children should be invalidated
// also. The default is eTRUE.
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::ForceRepaint(tCIDLib::eBOOL bChildrenToo)
{
if (!WinInvalidateRect(__hwndThis, 0, bChildrenToo))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::ForceRepaint"
, __LINE__
, "WinInvalidateRect failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: Hide()
//
// DESCRIPTION:
//
// This method will turn off the visibility style for the window
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::Hide()
{
if (!WinShowWindow(__hwndThis, 0))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::Hide"
, __LINE__
, "WinShowWindow failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: InvalidateArea(areaInvalidate, bDoClippedChild)
//
// DESCRIPTION:
//
// This method will invalidate the passed area, causing the window to
// receive a paint with this area as the update region.
// ---------------------------------------
// INPUT: areaInvalidate is the area to invalidate.
// bDoClippedChild indicates whether clipped children should be
// invalidated as well. The default is eFALSE.
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID
PROCEXP WINDOW::InvalidateArea( const AREA& areaInvalidate
, tCIDLib::eBOOL bDoClippedChild)
{
RECTL rectlTmp;
// Convert to a non-inclusive rectangle
areaInvalidate.ToRectl(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
if (!WinInvalidateRect(__hwndThis, &rectlTmp, bDoClippedChild))
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::InvalidateArea"
, __LINE__
, "WinInvalidateRect failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: pntWndOrg() const
//
// DESCRIPTION:
//
// This method will return a point that contains the origin of the window
// relative to its parent.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: A POINT object with the window's origin
//
POINT PROCEXP WINDOW::pntWndOrg() const
{
SWP swpTmp;
if (!WinQueryWindowPos(__hwndThis, &swpTmp))
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::pntWndOrg"
, __LINE__
, "WinQueryWindowPos failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
return POINT(swpTmp.x, swpTmp.y);
}
//
// FUNCTION/METHOD NAME: ReleaseMouse()
//
// DESCRIPTION:
//
// This method undoes a call to CaptureMouse()
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::ReleaseMouse()
{
if (!WinSetCapture(HWND_DESKTOP, 0))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::ReleaseMouse"
, __LINE__
, "WinSetCapture failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
__bMouseCaptured = tCIDLib::eFALSE;
}
//
// FUNCTION/METHOD NAME: ScrollArea(areaScroll, i4CX, i4CY, bInvalidate
// , bScrollChildren)
// ScrollArea(areaScroll, i4CX, i4CY, areaInvalidated
// , areaClip, bInvalidate, bScrollChildren)
//
// DESCRIPTION:
//
// These methods will scroll the indicated area in the indicated directions.
// There is a simple version that just scrolls the whole area with an
// optional invalidation of the uncovered area. The second version allows a
// clip area and returns the invalidated area.
// ---------------------------------------
// INPUT: areaScroll is the area to scroll
// i4CX, i4CY are the directions to scroll in the x and y directions
// areaClip is the clip area to use during the scroll
// bInvalidate indicates whether the uncovered area will be
// invalidated.
// bScrollChildren indicates whether children should be scrolled as
// well.
//
// OUTPUT: areaInvalidated is filled in with the invalidated area
//
// RETURN: None
//
tCIDLib::VOID
PROCEXP WINDOW::ScrollArea( const AREA& areaScroll
, tCIDLib::INT4 i4CX
, tCIDLib::INT4 i4CY
, tCIDLib::eBOOL bInvalidate
, tCIDLib::eBOOL bScrollChildren)
{
RECTL rectlTmp;
tCIDLib::CARD4 c4Flags = 0;
if (bInvalidate)
c4Flags |= SW_INVALIDATERGN;
if (bScrollChildren)
c4Flags |= SW_SCROLLCHILDREN;
areaScroll.ToRectl(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
if (WinScrollWindow(__hwndThis
, i4CX, i4CY
, &rectlTmp
, 0
, 0
, 0
, c4Flags) == RGN_ERROR)
{
// It failed, so we need to log a message and abort
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::ScrollArea"
, __LINE__
, "WinScrollWindow failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
tCIDLib::VOID
PROCEXP WINDOW::ScrollArea( const AREA& areaScroll
, tCIDLib::INT4 i4CX
, tCIDLib::INT4 i4CY
, AREA& areaInvalidated
, const AREA& areaClip
, tCIDLib::eBOOL bInvalidate
, tCIDLib::eBOOL bScrollChildren)
{
RECTL rectlTmp, rectlUpdate, rectlClip;
tCIDLib::CARD4 c4Flags = 0;
if (bInvalidate)
c4Flags |= SW_INVALIDATERGN;
if (bScrollChildren)
c4Flags |= SW_SCROLLCHILDREN;
areaScroll.ToRectl(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
areaClip.ToRectl(rectlClip, tCIDGui::eRECTL_NONINCLUSIVE);
if (WinScrollWindow(__hwndThis
, i4CX, i4CY
, &rectlTmp
, &rectlClip
, 0
, &rectlUpdate
, c4Flags) == RGN_ERROR)
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::ScrollArea"
, __LINE__
, "WinScrollWindow failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Get the update rectangle to the output area
areaInvalidated.FromRectl(rectlUpdate, tCIDGui::eRECTL_NONINCLUSIVE);
}
//
// FUNCTION/METHOD NAME: SetPresColor(ePresClr, rgbClr)
//
// DESCRIPTION:
//
// This method will set the indicated presentation color to the passed
// color value.
// ---------------------------------------
// INPUT: ePresClr is the presentation color to set
// rgbClr is the new color to apply
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP
WINDOW::SetPresColor( tCIDGui::ePRESCLRS ePresClr
, const RGBCLR& rgbClr)
{
//
// Note that we cast the RGBCLR object to a long value, which causes
// the implicit operator to return a pointer to the color info. It is
// in the right order so that the low 3 bytes look like an RGB.
//
tCIDLib::INT4 i4Clr = rgbClr;
if (!WinSetPresParam( __hwndThis
, ePresClr
, sizeof(RGB)
, &i4Clr))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::SetPresColor"
, __LINE__
, "WinSetPresParam failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: SetSWPFlags(eSwp, areaComponent, wndBehind)
//
// DESCRIPTION:
//
// This method allows a number of position/size/zorder/min/max operations
// to be done at once very efficiently.
// ---------------------------------------
// INPUT: eSwp contains the flags that indicate the operations.
// areaComponent is the area to set. This is used if the size
// or move or min or max or restore options flags are
// set. Defaults to NUL_AREA.
// wndBehind is used is the z order flag is set. It is the window
// to install behind. NUL_WINDOW.
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP
WINDOW::SetSWPFlags( tCIDGui::eSWPFLAGS eSwp
, const AREA& areaComponent
, const WINDOW& wndBehind)
{
// Zero out an SWP structure to use
SWP swpTmp;
SetMemory(&swpTmp, 0, sizeof(SWP));
// Copy over the flags
swpTmp.fl = eSwp;
//
// If the area is present, then get the info. If not, then make sure
// that no flags are on that require it.
//
if (&areaComponent)
{
swpTmp.x = areaComponent.i4X();
swpTmp.y = areaComponent.i4Y();
swpTmp.cx = areaComponent.c4CX();
swpTmp.cy = areaComponent.c4CY();
}
else
{
if (swpTmp.fl & (SWP_SIZE | SWP_MOVE | SWP_MINIMIZE))
{
facCIDGui.LogErr( __FILE__
, "WINDOW::SetSWPFlags"
, __LINE__
, GUIERR_WIN_BAD_SWP_FLAGS
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_BADPARMS
, STRG16("Size/Move/Minimize")
, STRG16("area"));
}
}
//
// If the window parameter is present, then get the handle. If not,
// make sure that the z order option is not present.
//
if (&wndBehind)
{
swpTmp.hwndInsertBehind = wndBehind.hwndThis();
}
else
{
if (swpTmp.fl & SWP_ZORDER)
{
facCIDGui.LogErr( __FILE__
, "WINDOW::SetSWPFlags"
, __LINE__
, GUIERR_WIN_BAD_SWP_FLAGS
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_BADPARMS
, STRG16("ZORDER")
, STRG16("window"));
}
}
// Do the set operation now
if (!WinSetWindowPos( hwndThis()
, swpTmp.hwndInsertBehind
, swpTmp.x
, swpTmp.y
, swpTmp.cx
, swpTmp.cy
, swpTmp.fl))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::SetSWPFlags"
, __LINE__
, "WinSetWindowPos failed"
, tCIDLib::eSEV_API_FAILED);
}
}
//
// FUNCTION/METHOD NAME: SetWndPos(pntNewOrg)
// SetWndSize(c4CX, c4CY)
// SetWndSizePos(areaNew)
//
// DESCRIPTION:
//
// These methods will set the size/position
// ---------------------------------------
// INPUT: pntNewOrg is the new orgin when setting the new position
// c4CX,c4CY are the new sizes when setting the size
// areaNew is the new when setting both
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::SetWndPos(const POINT& pntNewOrg)
{
if (!WinSetWindowPos( __hwndThis
, HWND(0)
, pntNewOrg.i4X()
, pntNewOrg.i4Y()
, 0
, 0
, SWP_MOVE))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::SetWndPos"
, __LINE__
, "WinSetWindowPos failed"
, tCIDLib::eSEV_API_FAILED);
}
}
tCIDLib::VOID PROCEXP WINDOW::SetWndSize( tCIDLib::CARD4 c4CX
, tCIDLib::CARD4 c4CY)
{
if (!WinSetWindowPos( __hwndThis
, HWND(0)
, 0
, 0
, c4CX
, c4CY
, SWP_SIZE))
{
// It failed, so we need to log a message and return
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::SetWndSize"
, __LINE__
, "WinSetWindowPos failed"
, tCIDLib::eSEV_API_FAILED);
}
}
tCIDLib::VOID PROCEXP WINDOW::SetWndSizePos(const AREA& areaNew)
{
if (!WinSetWindowPos( __hwndThis
, HWND(0)
, areaNew.i4X()
, areaNew.i4Y()
, areaNew.c4CX()
, areaNew.c4CY()
, SWP_SIZE | SWP_MOVE))
{
// It failed, so we need to log a message and return
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::SetWndSizePos"
, __LINE__
, "WinSetWindowPos failed"
, tCIDLib::eSEV_API_FAILED);
}
}
//
// FUNCTION/METHOD NAME: Show()
//
// DESCRIPTION:
//
// This method will turn on the visibility style for the winodw
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::Show()
{
if (!WinShowWindow(__hwndThis, 1))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::Show"
, __LINE__
, "WinShowWindow failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: strWndText() const
// strWndText(strbNewText)
//
// DESCRIPTION:
//
// These methods get/set the window text. We have to deal with PM window
// text, but we need to copy into the __strWndText and return a constant
// reference to it.
// ---------------------------------------
// INPUT: strbNewText is the new text to set.
//
// OUTPUT: None
//
// RETURN: A constant reference to the window text.
//
const STRING& PROCEXP WINDOW::strWndText() const
{
// Get the window text length and realloc the string to fit
tCIDLib::INT4 i4Len = (tCIDLib::INT4)WinQueryWindowTextLength(*this);
((STRING*)&__strWndText)->Realloc(i4Len);
//
// NOTE: The buffer is one larger than the max size method. This call
// wants the full size of the buffer, not the maximum chars.
//
WinQueryWindowText( __hwndThis
, __strWndText.c4MaxSize()+1
, __strWndText.pSZ());
return __strWndText;
}
const STRING& PROCEXP WINDOW::strWndText(const STRGBUF& strbNewText)
{
// Copy the text to our buffer
__strWndText.Realloc(strbNewText.c4MaxSize());
__strWndText = strbNewText;
if (!WinSetWindowText(__hwndThis, __strWndText.pSZ()))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::strWndText"
, __LINE__
, "WinSetWindowText failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
return __strWndText;
}
//
// FUNCTION/METHOD NAME: TakeFocus()
//
// DESCRIPTION:
//
// This method will cause the calling window object to take the focus.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::TakeFocus()
{
if (!WinSetFocus(HWND_DESKTOP, __hwndThis))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::TakeFocus"
, __LINE__
, "WinSetFocus failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: ToBottom()
// ToTop()
//
// DESCRIPTION:
//
// This method will move this window to the top or bottom of its sibling
// windows.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::ToBottom()
{
if (!WinSetWindowPos( *this
, HWND_BOTTOM
, 0, 0, 0, 0
, SWP_ZORDER))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::ToBottom"
, __LINE__
, "WinSetWindowPos failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
tCIDLib::VOID PROCEXP WINDOW::ToTop()
{
if (!WinSetWindowPos( *this
, HWND_TOP
, 0, 0, 0, 0
, SWP_ZORDER))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::ToTop"
, __LINE__
, "WinSetWindowPos failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: TranslateCoord(pntTmp, wndSrc)
//
// DESCRIPTION:
//
// This method will translate the passed coordinates from the source
// window's coordinate system to this window's.
// ---------------------------------------
// INPUT: wndSrc is the source window whose coordinate system the passed
// point is in.
//
// OUTPUT: pntTmp is updated to the new coordinates.
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::TranslateCoord( POINT& pntTmp
, const WINDOW& wndSrc)
{
POINTL ptlTmp;
if (!WinMapWindowPoints(wndSrc.__hwndThis
, __hwndThis
, pntTmp
, 1))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::TranslateCoord"
, __LINE__
, "WinMapWindowPoints failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: wndChildFromId(c4Id)
//
// DESCRIPTION:
//
// This method will return a WINDOW pointer for the indicated child window.
// The desired window must be child of this window and have the indicated
// id.
// ---------------------------------------
// INPUT: c4Id is the id of the child window
//
// OUTPUT: None
//
// RETURN: A reference to the correct WINDOW object. If the window does not
// exist, then the return can be NUL_WINDOW.
//
WINDOW& PROCEXP WINDOW::wndChildFromId(tCIDLib::CARD4 c4Id) const
{
HWND hwndChild = WinWindowFromID(__hwndThis, c4Id);
if (!hwndChild)
return NUL_WINDOW;
WINDOW* pwndTmp = (WINDOW*)(WinQueryWindowPtr(hwndChild, QWL_USER));
if (!pwndTmp)
{
facCIDGui.LogErr( __FILE__
, "WINDOW::wndOwner"
, __LINE__
, GUIERR_GEN_NOT_CIDLIB_WINDOW
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_CANTDO
, strWndText());
}
return *pwndTmp;
}
//
// FUNCTION/METHOD NAME: wndChildUnderPnt(pntPos, bDeep)
//
// DESCRIPTION:
//
// This method will find the highest z order child window that lies under
// the passed point. If none, then NUL_WINDOW is returned.
// ---------------------------------------
// INPUT: pntPos is the position to check for a hit, relative to the
// origin of this window.
// bPoint indictes whether all descendants should be searched or
// just direct children.
//
// OUTPUT: None
//
// RETURN: A reference to the window that was hit, else NUL_WINDOW.
//
WINDOW& PROCEXP WINDOW::wndChildUnderPnt( const POINT& pntPos
, tCIDLib::eBOOL bDeep)
{
HWND hwndChild = WinWindowFromPoint(__hwndThis, pntPos, bDeep);
if ((hwndChild == 0) || (hwndChild == __hwndThis))
return NUL_WINDOW;
// Make sure that it is not a title bar
if (WinQueryWindowUShort(hwndChild, QWS_ID) == FID_TITLEBAR)
return NUL_WINDOW;
// Get a pointer to the child window object
WINDOW* pwndTmp = (WINDOW*)WinQueryWindowPtr(hwndChild, QWL_USER);
if (!pwndTmp)
{
facCIDGui.LogErr( __FILE__
, "WINDOW::wndChildUnderPnt"
, __LINE__
, GUIERR_GEN_NOT_CIDLIB_WINDOW
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_CANTDO
, strWndText());
}
return *pwndTmp;
}
//
// FUNCTION/METHOD NAME: wndEnumChildren(wndChild, eEnumChild)
//
// DESCRIPTION:
//
// This method will find other child windows in other groups or in the
// same group as the passed child. This is used to provide tab sequence
// management. This guy calls a protected virtual method to let derived
// types actual handle this operation. If they don't handle it, then we
// use the default PM logic.
// ---------------------------------------
// INPUT: wndChild is the child window from which we start
// eEnumChild indicates the relation to the passed child of the
// window to find.
//
// OUTPUT: None
//
// RETURN: A reference to the window or NUL_WINDOW if not found.
//
WINDOW& PROCEXP
WINDOW::wndEnumChildren(const WINDOW& wndChild
, tCIDGui::eENUMCHILD eEnumChild)
{
tCIDLib::eBOOL bHandled = tCIDLib::eFALSE;
// Give derived types the first shot
WINDOW& wndTmp = _wndEnumChildren(wndChild, eEnumChild, bHandled);
if (bHandled)
return wndTmp;
HWND hwndNew = WinEnumDlgItem(__hwndThis, wndChild.__hwndThis, eEnumChild);
if (!hwndNew)
return NUL_WINDOW;
// Get the window object address from the window and return that
return *((WINDOW*)WinQueryWindowPtr(hwndNew, QWL_USER));
}
//
// FUNCTION/METHOD NAME: wndOwner(wndNewOwner)
//
// DESCRIPTION:
//
// This method will set/get the owner window.
// ---------------------------------------
// INPUT: wndNewOwner is the new owner window
//
// OUTPUT: None
//
// RETURN: A reference to the new/current owner window. If none,
// then NUL_WINDOW.
//
const WINDOW& PROCEXP WINDOW::wndOwner(const WINDOW& wndNewOwner)
{
if (!WinSetOwner(__hwndThis, wndNewOwner))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::wndOwner(WINDOW)"
, __LINE__
, "WinSetOwner failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
return wndNewOwner;
}
WINDOW& PROCEXP WINDOW::wndOwner() const
{
HWND hwndOwner = WinQueryWindow(__hwndThis, QW_OWNER);
if (!hwndOwner)
return NUL_WINDOW;
WINDOW* pwndTmp = (WINDOW*)WinQueryWindowPtr(hwndOwner, QWL_USER);
if (!pwndTmp)
{
facCIDGui.LogErr( __FILE__
, "WINDOW::wndOwner"
, __LINE__
, GUIERR_GEN_NOT_CIDLIB_WINDOW
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_CANTDO
, strWndText());
}
return *pwndTmp;
}
//
// FUNCTION/METHOD NAME: wndParent(wndNewParent, bRedraw)
//
// DESCRIPTION:
//
// This method will make the passed window the parent of this window.
// ---------------------------------------
// INPUT: wndNewParent is the new parent window to set
// bRedraw indicates whether the window should be redrawn after the
// parent is changed.
//
// OUTPUT: None
//
// RETURN: A reference to the parent window object
//
const WINDOW& PROCEXP WINDOW::wndParent(const WINDOW& wndNewParent
, tCIDLib::eBOOL bRedraw)
{
if (!WinSetParent(__hwndThis, wndNewParent, bRedraw))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::wndParent"
, __LINE__
, "WinSetParent failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
return wndNewParent;
}
//
// FUNCTION/METHOD NAME: wndParent()
//
// DESCRIPTION:
//
// This method will get/set the parent window
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: A reference to the parent window object
//
WINDOW& PROCEXP WINDOW::wndParent() const
{
HWND hwndParent = WinQueryWindow(__hwndThis, QW_PARENT);
if (!hwndParent)
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::wndParent"
, __LINE__
, ""
, tCIDLib::eSEV_PROCESS_FATAL);
}
WINDOW* pwndTmp = (WINDOW*)WinQueryWindowPtr(hwndParent, QWL_USER);
if (!pwndTmp)
{
facCIDGui.LogErr( __FILE__
, "WINDOW::wndOwner"
, __LINE__
, GUIERR_GEN_NOT_CIDLIB_WINDOW
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_CANTDO
, STRG16("The parent of window:")
, strWndText());
}
return *pwndTmp;
}
// -----------------------------------------------------------------------------
// WINDOW: Protected, virtual methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: _bQueryWndParms(pParmBuf)
// _bSetWndParms(pParmBuf)
//
// DESCRIPTION:
//
// This is the default handler for this message method. It just supports
// window text ignores the other queried/set parms.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: pParmBuf is a pointer to a PM WNDPARAMS structure
//
// RETURN: eTRUE to indicate that we handled it
//
tCIDLib::eBOOL PROCEXP WINDOW::_bQueryWndParams(tCIDLib::VOID* pParmBuf) const
{
PWNDPARAMS pwpTmp = (PWNDPARAMS)pParmBuf;
// Init everything to 'not handled' statuses as defaults
pwpTmp->cchText = 0;
pwpTmp->pszText = 0;
pwpTmp->cbPresParams= 0;
pwpTmp->pPresParams = 0;
pwpTmp->cbCtlData = 0;
pwpTmp->pCtlData = 0;
//
// We only support the text and text length, so check for them. We leave
// the other flags untouched to indicate that they are not returned.
//
if (WPM_CCHTEXT & pwpTmp->fsStatus)
{
pwpTmp->cchText = __strWndText.c4Length();
pwpTmp->fsStatus &= ~WPM_CCHTEXT;
}
if (WPM_TEXT & pwpTmp->fsStatus)
{
pwpTmp->pszText = __strWndText.pSZ();
pwpTmp->fsStatus &= ~WPM_TEXT;
}
return tCIDLib::eTRUE;
}
tCIDLib::eBOOL PROCEXP WINDOW::_bSetWndParams(tCIDLib::VOID* pParmBuf)
{
PWNDPARAMS pwpTmp = (PWNDPARAMS)pParmBuf;
//
// We only support the text, so check for it. If it is set, then assign
// the passed text to the string and clear the status flag. Check for a
// null though.
//
if (WPM_TEXT & pwpTmp->fsStatus)
{
if (pwpTmp->pszText)
__strWndText = (tCIDLib::CH*)pwpTmp->pszText;
else
__strWndText.Clear();
pwpTmp->fsStatus &= ~WPM_TEXT;
}
return tCIDLib::eTRUE;
}
// -----------------------------------------------------------------------------
// WINDOW: Protected, inherited methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: _bIsEqual(objTarget) const
//
// DESCRIPTION:
//
// ---------------------------------------
// INPUT: objTarget is the target object to compare against
//
// OUTPUT: None
//
// RETURN: eTRUE if the objects are equal, else eFALSE.
//
tCIDLib::eBOOL PROCEXP WINDOW::_bIsEqual(const CIDOBJECT& objTarget) const
{
// Call our parent's version first
if (!CIDOBJECT::_bIsEqual(objTarget))
return tCIDLib::eFALSE;
// Look at the object as a window
WINDOW* pwndTarget = (WINDOW*)(&objTarget);
// Compare the window handles
if (__hwndThis != pwndTarget->__hwndThis)
return tCIDLib::eFALSE;
return tCIDLib::eTRUE;
}
// -----------------------------------------------------------------------------
// WINDOW: Protected, non-virtual methods
// -----------------------------------------------------------------------------
//
// FUNCTION/METHOD NAME: _CreateCursor(areaCursor, areaClip, eCursorType)
//
// DESCRIPTION:
//
// This method will create a PM cursor of the indicate area and type,
// clipped to the clip area.
// ---------------------------------------
// INPUT: areaCursor is the area of the new cursor
// areaClip is the area to clip the cursor to
// eCursorType is the style of the cursor to create
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP
WINDOW::_CreateCursor( const AREA& areaCursor
, const AREA& areaClip
, tCIDGui::eCURSORS eCursorType)
{
RECTL rectlClip;
areaClip.ToRectl(rectlClip, tCIDGui::eRECTL_NONINCLUSIVE);
if (!WinCreateCursor( __hwndThis
, areaCursor.i4X()
, areaCursor.i4Y()
, areaCursor.c4CX()
, areaCursor.c4CY()
, eCursorType
, &rectlClip))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::_CreateCursor"
, __LINE__
, "WinCreateCursor failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: _DestroyCursor()
//
// DESCRIPTION:
//
// Destroys the current cursor for this window, if one exists.
// ---------------------------------------
// INPUT: None
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::_DestroyCursor()
{
if (!WinDestroyCursor(__hwndThis))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::_DestroyCursor"
, __LINE__
, "WinDestroyCursor failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: _MoveCursor(pntNewPos)
//
// DESCRIPTION:
//
// This method will move the current cursor to the indicate position.
// ---------------------------------------
// INPUT: pntNewPos is the new cursor origin
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::_MoveCursor(const POINT& pntNewPos)
{
if (!WinCreateCursor( __hwndThis
, pntNewPos.i4X()
, pntNewPos.i4Y()
, 0
, 0
, CURSOR_SETPOS
, 0))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::_MoveCursor"
, __LINE__
, "WinMoveCursor failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}
//
// FUNCTION/METHOD NAME: _mresHandleMsg(hwndThis, c4Msg, mp1, mp2)
//
// DESCRIPTION:
//
// This method is called from the main class' window procedure any time that
// a message is received. It will handle getting the message to the correct
// place.
//
// NOTE: To support repeat counts in char messages, WM_CHAR calls the
// default window proc manually instead of falling through to
// the bottom of the method.
//
// NOTE: Don't declare any complex local objects because the constructors
// will be called on every entry to this method, and recursively to
// make matters worse. Each case below allocates the objects it
// needs.
// ---------------------------------------
// INPUT: hwndThis is the handle of the window that got the message
// c4Msg is the message it got
// mp1, mp2 are the message parms
//
// OUTPUT: None
//
// RETURN: If the message is handled by the derived class, then its return
// is returned. Else the return of the backup window proc is
// returned.
//
MRESULT PROCEXP WINDOW::_mresHandleMsg( HWND hwndThis
, tCIDLib::CARD4 c4Msg
, MPARAM mp1
, MPARAM mp2)
{
tCIDLib::eBOOL bTmp;
tCIDLib::CARD2 c2Tmp;
tCIDLib::CARD4 c4Index, c4Tmp;
if (((c4Msg >= WM_BUTTONCLICKFIRST) && (c4Msg <= WM_BUTTONCLICKLAST))
|| (c4Msg == WM_BUTTON1CLICK)
|| (c4Msg == WM_BUTTON2CLICK)
|| (c4Msg == WM_BUTTON3CLICK)
|| (c4Msg == WM_CHORD))
{
//
// $CIDWATCH_DEPENUM$
//
// Handle button click events. We can cast the message directly to
// the click type parm since they have the same values as their
// message equivalent.
//
POINT pntPos(SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
if (bClick(tCIDGui::eMOUSECLKS(c4Msg), pntPos))
return 0;
}
else if (c4Msg == WM_CHAR)
{
//
// Parse the character and call the correct character method. We
// only send messages for key down messages, forgoing the ability
// to sense keyup messages in order to simplify things. So get the
// flags word and operate according to what it tells us.
//
c2Tmp = SHORT1FROMMP(mp1);
//
// $CIDWATCH_DEPENUM$
//
// We cast PM values into an enum for passing to the window object.
// Check for stuff that we just don't deal with at all. Let them go
// to default window proc.
//
if (!(c2Tmp
& (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP | KC_KEYUP)))
{
// Translate the shifts into our type of bit mask
c4Tmp = tCIDGui::eSHIFT_NONE;
if (c2Tmp & KC_SHIFT)
c4Tmp |= tCIDGui::eSHIFT_SHIFT;
if (c2Tmp & KC_ALT)
c4Tmp |= tCIDGui::eSHIFT_ALT;
if (c2Tmp & KC_CTRL)
c4Tmp |= tCIDGui::eSHIFT_CTRL;
for (c4Index = 0; c4Index < CHAR3FROMMP(mp1); c4Index++)
{
if (c2Tmp & KC_VIRTUALKEY)
{
bTmp = bExtendedChar(tCIDGui::eEXTKEYS(SHORT2FROMMP(mp2))
, tCIDGui::eSHIFTKEYS(c4Tmp));
}
else if (c2Tmp & KC_CHAR)
{
bTmp = bChar( tCIDLib::CH(SHORT1FROMMP(mp2))
, tCIDGui::eSHIFTKEYS(c4Tmp));
}
if (!bTmp)
this->__pfnWndProc(hwndThis, c4Msg, mp1, mp2);
}
// Return that we dealt with the message
return MRESULT(1);
}
}
else if (c4Msg == WM_COMMAND)
{
//
// Pass on commands from our child menus and buttons. The first
// parm is the notification code, the high word of the 1st
// window param. The next parm is the id of the child. If it is
// not handled, let if fall through to the default handler.
//
if (_bCommand(SHORT1FROMMP(mp1)))
return 0;
}
else if (c4Msg == WM_CONTEXTMENU)
{
if (__pmenuThis)
{
// Allowed derived classes to pre-process menu
_InitMenu(*__pmenuThis);
// Call the popup menu function
POINTS ptsTmp = *((POINTS*)&mp1);
POINT pntPos(ptsTmp.x, ptsTmp.y);
bPopUpMenu(pntPos);
return MRESULT(1);
}
}
else if (c4Msg == WM_CONTROL)
{
//
// This is a notifications from a child control.
//
// We echo the control message back to the control itself via
// the _bControl() method. He will process it and pass on the
// processed version this window, if this is desired. If he
// does not process it, we let it go to this window (i.e. the
// owner.)
//
WINDOW& wndChild = wndChildFromId(SHORT1FROMMP(mp1));
if (&wndChild)
{
if (wndChild._bControl( SHORT2FROMMP(mp1)
, SHORT1FROMMP(mp1)
, LONGFROMMP(mp2)))
{
return 0;
}
}
if (_bControl( SHORT2FROMMP(mp1)
, SHORT1FROMMP(mp1)
, LONGFROMMP(mp2)))
{
return 0;
}
}
else if (c4Msg == WM_CREATE)
{
//
// We should never get this message here because it is handled by
// the window dispatching function. If we do, then log a message and
// return 1 to indicate an error.
//
facCIDGui.LogErr( __FILE__
, "WINDOW::_mresHandleMsg"
, __LINE__
, GUIERR_WIN_WM_CREATE
, tCIDLib::eSEV_WARNING
, tCIDLib::eCLASS_INTERNAL);
return MRESULT(1);
}
else if (c4Msg == WM_CLOSE)
{
//
// Let the derived class handle not allowing a system menu
// operation to close the application. If he returns eTRUE,
// then he has handled it and we don't pass it on to the
// default handler.
//
if (bClose())
return 0;
}
else if (c4Msg == WM_DESTROY)
{
//
// Let the derived classes see this. If the __bDestructing flag is
// set, then we are done because we go here via a call to the
// destructor. Otherwise, we need to call the destructor, clearing
// the window handle first to let him know that we are causing it
// (so he will not try to destroy the window again.)
//
bDestroy();
if (!__bDestructing)
{
__hwndThis = 0;
delete this;
}
return 0;
}
else if (c4Msg == WM_ENABLE)
{
bTmp = SHORT1FROMMP(mp1) ? tCIDLib::eTRUE : tCIDLib::eFALSE;
if (bEnableState(bTmp))
return 0;
}
else if ((c4Msg == WM_HSCROLL) || (c4Msg == WM_VSCROLL))
{
if (bScrollEvent( SHORT1FROMMP(mp1)
, tCIDGui::eSCROLLEV(SHORT2FROMMP(mp2))
, tCIDLib::INT4(SHORT1FROMMP(mp2))))
{
return 0;
}
}
else if (c4Msg == WM_MINMAXFRAME)
{
// Convert the SWP structure to individual parms
SWP& swpTmp = *(SWP*)mp1;
AREA areaNew(swpTmp);
tCIDGui::eSWPFLAGS eFlags = tCIDGui::eSWPFLAGS(swpTmp.fl);
//
// Let the frame handle the min/max change
//
if (_bMinMaxFrame(eFlags, areaNew))
return MPARAM(1);
// If the user modified the area
areaNew.ToSwp(swpTmp);
swpTmp.fl = eFlags;
}
else if (c4Msg == WM_MOVE)
{
if (bMoved())
return 0;
}
else if (c4Msg == WM_MOUSEMOVE)
{
//
// Convert the position to a POINT object and pass it along to the
// method.
//
if (bMouseMove(POINT(SHORT1FROMMP(mp1), SHORT2FROMMP(mp1))))
return MPARAM(1);
}
else if (c4Msg == WM_PAINT)
{
if (!__bPMPaint)
{
tCIDLib::eBOOL bHandled;
RECTL rectlTmp;
// Start the paint and get the invalid rectangle
HPS hPS = WinBeginPaint(__hwndThis, 0, &rectlTmp);
if (!hPS)
{
// Log a message
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::_mresHandleMsg"
, __LINE__
, "WinBeginPaint failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
// Convert the rectangle to an area. The rect is non-inclusive
AREA areaInvalid(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
//
// Get a paint brush for this window. We call the special,
// protected version is just for paint messages, as it takes a
// PS as a parm instead of creating one. The last parm indicates
// this is a paint PS, as apposed to a persistant one.
//
PAINTBRUSH* pptbTmp = new PAINTBRUSH( hPS
, *this
, PAINTBRUSH::ePS_PAINT);
bHandled = bPaint(areaInvalid, *pptbTmp);
// Destroy the paint brush
delete pptbTmp;
//
// If the message was handled, then return; else, let it go
// the the default
//
if (bHandled)
return 0;
}
}
else if (c4Msg == WM_PRESPARAMCHANGED)
{
if (bPresParamChanged())
return 0;
}
else if (c4Msg == WM_QUERYWINDOWPARAMS)
{
//
// Give the derived class a chance to provide window params. Its
// primary use is for the WINDOW class to support PM window text
// like other windows. Actual PM control classes must override
// this guy and just return eFALSE to let it go to the default
// handler.
//
if (_bQueryWndParams((tCIDLib::VOID*)mp1))
return MRESULT(1);
}
else if (c4Msg == WM_SETFOCUS)
{
//
// Call either the losing or getting focus method. If the object
// handles the message, then return 0.
//
if (SHORT1FROMMP(mp2))
bTmp = bGettingFocus();
else
bTmp = bLosingFocus();
if (bTmp)
return 0;
}
else if (c4Msg == WM_SHOW)
{
bTmp = SHORT1FROMMP(mp1) ? tCIDLib::eTRUE : tCIDLib::eFALSE;
if (bShowState(bTmp))
return 0;
}
else if (c4Msg == WM_SIZE)
{
// Convert the new and old sizes to a AREAs that are 0 based
AREA areaNew(0, 0, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
AREA areaOld(0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
if (bSizeChanged(areaNew, areaOld))
return 0;
}
else if (c4Msg == WM_SYSCOMMAND)
{
if (bIsDescendantOf("FRAMEWND"))
{
FRAMEWND* pfrmwTmp = (FRAMEWND*)this;
if (pfrmwTmp->bSysCommand(tCIDGui::eSYSCMDS(SHORT1FROMMP(mp1))))
return 0;
}
}
else if (c4Msg == WM_SYSCOLORCHANGE)
{
if (bSysColorChanged())
return 0;
}
else if (c4Msg >= WM_USER)
{
//
// It is a user message so call the generic user message event.
//
if (bUserMsg(c4Msg, tCIDLib::CARD4(mp1), tCIDLib::CARD4(mp2)))
return 0;
}
// If the default window proc is not set in this object, then abort
if (!this->__pfnWndProc)
{
facCIDGui.LogErr( __FILE__
, "WINDOW::_mresHandleMsg"
, __LINE__
, GUIERR_WIN_NO_WNDPROC
, tCIDLib::eSEV_PROCESS_FATAL
, tCIDLib::eCLASS_INTERNAL
, clsIsA());
}
//
// No one handled it so call the object's default proc and return its
// return
//
return this->__pfnWndProc(hwndThis, c4Msg, mp1, mp2);
}
//
// FUNCTION/METHOD NAME: _SendControl(c4Code, c4SrcWndId, c4Data1, c4Data2)
//
// DESCRIPTION:
//
// This method will send a control message to the owner window if one
// exists.
// ---------------------------------------
// INPUT: c4Code is the notification code
// c4SrcWndId is the source window id
// c4Data1, c4Data2 are the optional data parms. They default to
// 0.
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::_SendControl( tCIDLib::CARD4 c4Code
, tCIDLib::CARD4 c4SrcWndId
, tCIDLib::CARD4 c4Data1
, tCIDLib::CARD4 c4Data2)
{
WINDOW& wndTarget = wndOwner();
if (!(&wndTarget))
{
// Log a message here!!!!!!!
return;
}
wndTarget._bControl(c4Code, c4SrcWndId, c4Data1, c4Data2);
}
//
// FUNCTION/METHOD NAME: _ShowCursor(bState)
//
// DESCRIPTION:
//
// This method will set the cursor visible state of this window's cursor.
// ---------------------------------------
// INPUT: bState is the new state
//
// OUTPUT: None
//
// RETURN: None
//
tCIDLib::VOID PROCEXP WINDOW::_ShowCursor(tCIDLib::eBOOL bState)
{
if (!WinShowCursor(__hwndThis, bState))
{
facCIDGui.LogLastSysErr(__FILE__
, "WINDOW::_ShowCursor"
, __LINE__
, "WinShowCursor failed"
, tCIDLib::eSEV_PROCESS_FATAL);
}
}