home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / deans.zip / WINDOW.CPP < prev    next >
C/C++ Source or Header  |  1994-09-14  |  84KB  |  2,678 lines

  1. //
  2. // NAME: CIDLib_Window.Cpp
  3. //
  4. // DESCRIPTION:
  5. //
  6. //    This module implements the WINDOW class. This is a virtual class that is
  7. //  the basis for all other window classes. It provides all of the general
  8. //  window operations that act the same on all windows.
  9. //
  10. //
  11. // AUTHOR: Dean Roddey
  12. //
  13. // CREATE DATE: 04/11/93
  14. //
  15. // COPYRIGHT: 1992..1994, 'CIDCorp
  16. //
  17. // CAVEATS/GOTCHAS:
  18. //
  19. //  1)  Most of the time in here, the __hwndThis member is used for
  20. //      efficiency, when calling system calls. But, be sure to pass *this
  21. //      when the call is to a CIDLib method because it wants the real window
  22. //      and will try to reconstruct one from the window handle (and destroy
  23. //      the window when the surrogate object is destroyed.
  24. //
  25. // MODIFICATION LOG:
  26. //
  27.  
  28.  
  29.  
  30. // -----------------------------------------------------------------------------
  31. //  Local defines
  32. // -----------------------------------------------------------------------------
  33. #define        CIDGUI_WINDOW_CPP
  34.  
  35. #define     INCL_GPILCIDS
  36. #define     INCL_GPILOGCOLORTABLE
  37. #define     INCL_GPIREGIONS
  38. #define     INCL_WINCURSORS
  39. #define     INCL_WINDIALOGS
  40. #define     INCL_WINFRAMEMGR
  41. #define     INCL_WININPUT
  42. #define     INCL_WINMENUS
  43. #define     INCL_WINMESSAGEMGR
  44. #define     INCL_WINWINDOWMGR
  45. #define     INCL_WINSYS
  46.  
  47. #define     INCL_CIDLIB_MEMORY
  48. #define     INCL_CIDLIB_METRICS
  49. #define     INCL_CIDLIB_TEXTFILES
  50.  
  51. #define     INCL_CIDGUI_ERRORIDS
  52. #define     INCL_CIDGUI_FACOBJECT
  53. #define     INCL_CIDGUI_GRAPHICS
  54. #define     INCL_CIDGUI_MENUS
  55. #define     INCL_CIDGUI_WINDOWS
  56.  
  57.  
  58.  
  59.  
  60. // -----------------------------------------------------------------------------
  61. //  Facility specific includes
  62. //
  63. //  CIDGui_.Hpp
  64. //      We just need the internal facility header
  65. // -----------------------------------------------------------------------------
  66. #include    "CIDGui_.Hpp"
  67.  
  68.  
  69. // -----------------------------------------------------------------------------
  70. //  Local data
  71. // -----------------------------------------------------------------------------
  72. tCIDLib::CH* __apszMClkDesc[] = {
  73.                                       "Button1Down"
  74.                                       , "Button1Up"
  75.                                       , "Button1Click"
  76.                                       , "Button1DblClk"
  77.                                       , "Button2Down"
  78.                                       , "Button2Up"
  79.                                       , "Button2Click"
  80.                                       , "Button2DblClk"
  81.                                       , "Button3Down"
  82.                                       , "Button3Up"
  83.                                       , "Button3Click"
  84.                                       , "Button3DblClk"
  85.                                       , "Chord"
  86.                                 };
  87. const tCIDLib::CARD4 c4MClkMax  = (sizeof(__apszMClkDesc)
  88.                                                 /sizeof(__apszMClkDesc[0]));
  89.  
  90.  
  91.  
  92. // -----------------------------------------------------------------------------
  93. //  Global functions
  94. // -----------------------------------------------------------------------------
  95.  
  96. //
  97. // FUNCTION/METHOD NAME: operator<<(strbDest, eMsClk)
  98. //
  99. // DESCRIPTION:
  100. //
  101. //  This method will format the passed mouse click into the passed string
  102. //  buffer.
  103. // ---------------------------------------
  104. //   INPUT: eMsClk is the mouse click to format
  105. //
  106. //  OUTPUT: strbDest is the string object to format into
  107. //
  108. //  RETURN: A reference to the string buffer
  109. //
  110. STRGBUF& PROCEXP operator<<(STRGBUF& strbDest, tCIDGui::eMOUSECLKS eMsClk)
  111. {
  112.     // Check for valid ranges
  113.     if (((eMsClk != tCIDGui::eMCLK_CHORD)
  114.     &&  (eMsClk != tCIDGUi::eMCLK_BUTTON1CLICK)
  115.     &&  (eMsClk != tCIDGUi::eMCLK_BUTTON2CLICK)
  116.     &&  (eMsClk != tCIDGUi::eMCLK_BUTTON3CLICK))
  117.     || ((eMsClk < tCIDGUi::eMCLK_BUTTON1DOWN)
  118.                             || (eMsClk > tCIDGUi::eMCLK_BUTTON3DBLCLK)))
  119.     {
  120.         facCIDGui.LogErr(   __FILE__
  121.                             , "operator<<"
  122.                             , __LINE__
  123.                             , GUIERR_GEN_NOT_VALID_VALUE
  124.                             , tCIDLib::eSEV_PROCESS_FATAL
  125.                             , tCIDLib::eCLASS_BADPARMS
  126.                             , INTEGER(eMsClk)
  127.                             , STRG16("Mouse Click"));
  128.     }
  129.  
  130.     // Format the string, adjusting the index to make it 0 based.
  131.     strbDest << __apszMClkDesc[eMsClk-tCIDGui::eMCLK_BUTTON1DOWN];
  132.     return strbDest;
  133. }
  134.  
  135. OTXTFILE& PROCEXP operator<<(OTXTFILE& otfDest, tCIDGui::eMOUSECLKS eMsClk)
  136. {
  137.     STRG64  strTmp;
  138.     strTmp << eMsClk;
  139.     otfDest << strTmp;
  140.     return otfDest;
  141. }
  142.  
  143.  
  144.  
  145. // -----------------------------------------------------------------------------
  146. //  Local functions
  147. // -----------------------------------------------------------------------------
  148.  
  149. //
  150. // FUNCTION/METHOD NAME: __pfnwpMainClass(hwndThis, c4Msg, mp1, mp2)
  151. //
  152. // DESCRIPTION:
  153. //
  154. //  This method is window proc used to register the standard window class. It
  155. //  exists just to eat the messages that arrive before the window can be
  156. //  subclassed to _pfnwpMainSub(), below.
  157. // ---------------------------------------
  158. //   INPUT: hwndThis is the handle to the window
  159. //          c4Msg is the message being received
  160. //          mp1, mp2 are the message parms.
  161. //
  162. //  OUTPUT: None
  163. //
  164. //  RETURN: None
  165. //
  166. static MRESULT EXPENTRY __pfnwpMainClass(   HWND                hwndThis
  167.                                             , tCIDLib::CARD4    c4Msg
  168.                                             , MPARAM            mp1
  169.                                             , MPARAM            mp2)
  170. {
  171.     if (c4Msg == WM_CREATE)
  172.         return 0;
  173.  
  174.     return WinDefWindowProc(hwndThis, c4Msg, mp1, mp2);
  175. }
  176.  
  177.  
  178. // -----------------------------------------------------------------------------
  179. //  Intrafacility functions     (Prototypes are in CIDGui_.Hpp)
  180. //
  181. //  _bInitWindow
  182. //      This is the initialization function for this module. It is called from
  183. //      the constructor of the facility object.
  184. //
  185. //  __pfnwpMainClass
  186. //      This is the window proc for all windows. It serves as the switch box
  187. //      for all messages to make sure that they are handled correctly and get
  188. //      to the right place.
  189. // -----------------------------------------------------------------------------
  190.  
  191. //
  192. // FUNCTION/METHOD NAME: _bInitWindow(habInit)
  193. //
  194. // DESCRIPTION:
  195. //
  196. //  This method is called from the facility object's constructor. It handles
  197. //  doing any local module initialization. In this case, we want to get some
  198. //  PM information and store it away and register our primary window class.
  199. // ---------------------------------------
  200. //   INPUT: habInit is an anchor block to use for initialization
  201. //
  202. //  OUTPUT: None
  203. //
  204. //  RETURN: eTRUE if successful, else eFALSE.
  205. //
  206. tCIDLib::eBOOL _bInitWindow(HAB habInit)
  207. {
  208.     // Register the window class
  209.     if (!WinRegisterClass(  habInit
  210.                             , _szCIDGuiClass
  211.                             , __pfnwpMainClass
  212.                             , CS_SIZEREDRAW
  213.                               | CS_MOVENOTIFY
  214.                             , sizeof(tCIDLib::VOID*)))
  215.     {
  216.         //
  217.         //  DO NOT call LogLastSysErr() because it might depend upon something
  218.         //  that is not initialized yet. LogMsg() is inherited from the basic
  219.         //  facility class (in CIDLib.Dll) so it is safe.
  220.         //
  221.         ERRORID ErrId = WinGetLastError(habInit);
  222.         facCIDGui.LogMsg(   __FILE__
  223.                             , "_bInitWindow"
  224.                             , __LINE__
  225.                             , "Could not register CIDGui window class. Err=%(1)"
  226.                             , tCIDLib::eSEV_PROCESS_FATAL
  227.                             , tCIDLib::eCLASS_INTERNAL
  228.                             , CARDINAL(ErrId & 0x7FFF));
  229.     }
  230.  
  231.     // Went ok so return true
  232.     return tCIDLib::eTRUE;
  233. }
  234.  
  235.  
  236. //
  237. // FUNCTION/METHOD NAME: _pfnwpMainSub(hwndThis, c4Msg, mp1, mp2)
  238. //
  239. // DESCRIPTION:
  240. //
  241. //  This guy gets all messages first. It handles some without giving them to
  242. //  anyone. The rest are first passed on to the class to be handled. If it
  243. //  does not handle the message, then it is passed to the original window
  244. //  procedure for PM controls or to the default window proc for others.
  245. // ---------------------------------------
  246. //   INPUT: hwndThis is the handle to the window
  247. //          c4Msg is the message being received
  248. //          mp1, mp2 are the message parms.
  249. //
  250. //  OUTPUT: None
  251. //
  252. //  RETURN: None
  253. //
  254. MRESULT EXPENTRY _pfnwpMainSub( HWND                hwndThis
  255.                                 , tCIDLib::CARD4    c4Msg
  256.                                 , MPARAM            mp1
  257.                                 , MPARAM            mp2)
  258. {
  259.     // Get a pointer to the window data, which is a pointer to the object
  260.     WINDOW*  pThis = (WINDOW*)WinQueryWindowPtr(hwndThis, QWL_USER);
  261.  
  262.     // If it is null, then a major error, so abort.
  263.     if (!pThis)
  264.     {
  265.         facCIDGui.LogMsg(   __FILE__
  266.                             , "__pfnwpMainSub"
  267.                             , __LINE__
  268.                             , "Window data did not point to this"
  269.                             , tCIDLib::eSEV_PROCESS_FATAL);
  270.         // Make compiler happy
  271.         return 0;
  272.     }
  273.  
  274.     // Call the message handler for this guy
  275.     return pThis->_mresHandleMsg(hwndThis, c4Msg, mp1, mp2);
  276. }
  277.  
  278.  
  279.  
  280.  
  281. // -----------------------------------------------------------------------------
  282. //   CLASS: WINDOW
  283. //  PREFIX: wnd
  284. //
  285. //  This class is the base window class.
  286. // -----------------------------------------------------------------------------
  287.  
  288. // -----------------------------------------------------------------------------
  289. //  WINDOW: Constructors/Destructors
  290. // -----------------------------------------------------------------------------
  291.  
  292. //
  293. // FUNCTION/METHOD NAME: WINDOW(wndParent, wndOwner, eStyle, wndBehind
  294. //                              , areaInit, strbText, c4Id, pfnWndProc)
  295. //
  296. // DESCRIPTION:
  297. //
  298. //  This is the only constructor for windows. The derived class provides us
  299. //  with the particulars and we create the window. The bPMPaint member is set
  300. //  to eFALSE here since that is by far the most used mode.
  301. // ---------------------------------------
  302. //   INPUT: wndParent is the parent window object
  303. //          wndOwner is the owner window. Can be facGUI.wndNONE if no owner is
  304. //              desired.
  305. //          eStyle is the window style flags. It will be at least the eWS_xxxx
  306. //              flags, but mostly it will be the styles of the derived type,
  307. //              which is a super set of the eWS_xxxx styles.
  308. //          wndBehind is the window behind which the new window should be
  309. //              inserted. This can be one of the special windows
  310. //              facCIDGui.wndTOP or facCIDGui.wndBOTTOM.
  311. //          areaInit is the initial size and position to give to the window.
  312. //              Defaults to 0,0,0,0.
  313. //          strbText is the window text for this window. Defaults to "".
  314. //          c4Id is the id value to give to the window. Defaults to 0.
  315. //          pfnWndProc is for the existing PM controls which already have a
  316. //              window procedure. The derived classes which implement these
  317. //              controls will pass the correct window procedure here. Others
  318. //              should pass 0, which is the default.
  319. //
  320. //  OUTPUT: None
  321. //
  322. //  RETURN: None
  323. //
  324. PROCEXP WINDOW::WINDOW( const   WINDOW&             wndParent
  325.                         , const WINDOW&             wndOwner
  326.                         ,       tCIDGui::eWNDSTYLES eStyle
  327.                         , const WINDOW&             wndBehind
  328.                         , const AREA&               areaInit
  329.                         , const STRGBUF&            strbText
  330.                         ,       tCIDLib::CARD4      c4Id
  331.                         ,       PFNWP               pfnWndProc) :
  332.  
  333.     __bDestructing(tCIDLib::eFALSE)
  334.     , __bMouseCaptured(tCIDLib::eFALSE)
  335.     , __bPMPaint(tCIDLib::eFALSE)
  336.     , __c4Id(c4Id)
  337.     , __hwndThis(0)
  338.     , __pfnWndProc(0)
  339.     , __pmenuThis(0)
  340.     , __strWndText(strbText, strbText.c4Length())
  341. {
  342.     //
  343.     //  Save away the passed window proc. If it is 0, then set it to the
  344.     //  default window proc
  345.     //
  346.     if (pfnWndProc)
  347.         __pfnWndProc = pfnWndProc;
  348.      else
  349.         __pfnWndProc = WinDefWindowProc;
  350.  
  351.     // Try to create the window
  352.     __hwndThis = WinCreateWindow(   wndParent
  353.                                     , _szCIDGuiClass
  354.                                     , strbText.pSZ()
  355.                                     , eStyle
  356.                                     , areaInit.i4X()
  357.                                     , areaInit.i4Y()
  358.                                     , LONG(areaInit.c4CX())
  359.                                     , LONG(areaInit.c4CY())
  360.                                     , wndOwner
  361.                                     , wndBehind
  362.                                     , c4Id
  363.                                     , 0
  364.                                     , 0);
  365.     if (!__hwndThis)
  366.     {
  367.         // It failed, so we need to log a message and abort
  368.         facCIDGui.LogLastSysErr(__FILE__
  369.                                 , "WINDOW"
  370.                                 , __LINE__
  371.                                 , __strWndText
  372.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  373.     }
  374.  
  375.     WinSubclassWindow(__hwndThis, _pfnwpMainSub);
  376.     WinSetWindowPtr(__hwndThis, QWL_USER, this);
  377.  
  378.     // Bump up the window count in the core metrics
  379.     _pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
  380. }
  381.  
  382.  
  383. //
  384. // FUNCTION/METHOD NAME: WINDOW(hwndWnd)
  385. //
  386. // DESCRIPTION:
  387. //
  388. //  This contructor is provided to create window objects from existing
  389. //  windows. This gets all of the needed information from the pased window
  390. //  handle. It checks for the special window handles so that this
  391. //  constructor can be used to create objects for the special windows.
  392. // ---------------------------------------
  393. //   INPUT: hwndWnd is the handle to the window
  394. //
  395. //  OUTPUT: None
  396. //
  397. //  RETURN: None
  398. //
  399. PROCEXP WINDOW::WINDOW(HWND hwndWnd) :
  400.  
  401.     __bDestructing(tCIDLib::eFALSE)
  402.     , __bMouseCaptured(tCIDLib::eFALSE)
  403.     , __bPMPaint(tCIDLib::eFALSE)
  404.     , __c4Id(WinQueryWindowUShort(hwndWnd, QWS_ID))
  405.     , __hwndThis(hwndWnd)
  406.     , __pfnWndProc(0)
  407.     , __pmenuThis(0)
  408. {
  409.     // Check for the special window handles. If so, then we are done
  410.     if ((hwndWnd == HWND_DESKTOP)
  411.     || (hwndWnd == HWND_OBJECT)
  412.     || (hwndWnd == HWND_TOP)
  413.     || (hwndWnd == HWND_BOTTOM)
  414.     || (hwndWnd == HWND(0)))
  415.     {
  416.         // Bump up the window count in the core metrics
  417.         _pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
  418.         return;
  419.     }
  420.  
  421.     //
  422.     //  If there is a window handle, then subclass it. If it is already
  423.     //  subclassed to our window proc, then abort.
  424.     //
  425.     if (__hwndThis)
  426.     {
  427.         PFNWP pfnTmp = (PFNWP)WinQueryWindowPtr(__hwndThis, QWP_PFNWP);
  428.         if (pfnTmp == _pfnwpMainSub)
  429.         {
  430.             facCIDGui.LogMsg(   __FILE__
  431.                                 , "WINDOW"
  432.                                 , __LINE__
  433.                                 , "Window was already subclassed"
  434.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  435.         }
  436.  
  437.         __pfnWndProc = WinSubclassWindow(__hwndThis, _pfnwpMainSub);
  438.  
  439.         // Store the object pointer in the window's spare data
  440.         WinSetWindowPtr(__hwndThis, QWL_USER, (tCIDLib::VOID*)(WINDOW*)this);
  441.  
  442.         // Make sure that the subclass went ok. If not, we gotta abort.
  443.         if (!__pfnWndProc)
  444.         {
  445.             facCIDGui.LogLastSysErr(__FILE__
  446.                                     , "WINDOW"
  447.                                     , __LINE__
  448.                                     , "WinSubclass failed"
  449.                                     , tCIDLib::eSEV_PROCESS_FATAL);
  450.         }
  451.     }
  452.  
  453.     // Bump up the window count in the core metrics
  454.     _pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
  455. }
  456.  
  457.  
  458. PROCEXP WINDOW::WINDOW() :
  459.  
  460.     __bDestructing(tCIDLib::eFALSE)
  461.     , __bMouseCaptured(tCIDLib::eFALSE)
  462.     , __bPMPaint(tCIDLib::eFALSE)
  463.     , __c4Id(0)
  464.     , __hwndThis(0)
  465.     , __pfnWndProc(0)
  466.     , __pmenuThis(0)
  467. {
  468.     // Bump up the window count in the core metrics
  469.     _pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, 1);
  470. }
  471.  
  472.  
  473.  
  474. //
  475. // FUNCTION/METHOD NAME: ~WINDOW()
  476. //
  477. // DESCRIPTION:
  478. //
  479. //  This is the destructor for WINDOW objects. It just calls
  480. //  WinDestroyWindow() for the window handle if it is not HWND(0). This
  481. //  will cause the destroy method to be called so that the derived window
  482. //  class can clean up.
  483. // ---------------------------------------
  484. //   INPUT: None
  485. //
  486. //  OUTPUT: None
  487. //
  488. //  RETURN: None
  489. //
  490. PROCEXP WINDOW::~WINDOW()
  491. {
  492.     //
  493.     //  If the handle is filled in then destroy it. This will cause the
  494.     //  destructor to be called.
  495.     //
  496.     if (__hwndThis)
  497.     {
  498.         //
  499.         //  We need to destroy the window, but make sure that they WM_DESTROY
  500.         //  message knows that it does not have to in turn call the
  501.         //  destructor. So, set the __bDestructing flag, then destroy the
  502.         //  window.
  503.         //
  504.         __bDestructing = tCIDLib::eTRUE;
  505.         WinDestroyWindow(__hwndThis);
  506.  
  507.         // Now we can waste the handle
  508.         __hwndThis = 0;
  509.     }
  510.  
  511.     // If there is a menu then destroy it
  512.     if (__pmenuThis)
  513.         delete __pmenuThis;
  514.  
  515.     // Bump down the window count in the core metrics
  516.     _pmtrGUICore->OffsetCard(tCIDGui_::eCOREMETRIC_WNDCOUNT, -1);
  517. }
  518.  
  519.  
  520. // -----------------------------------------------------------------------------
  521. //  WINDOW: Public, Inherited methods
  522. // -----------------------------------------------------------------------------
  523.  
  524. //
  525. // FUNCTION/METHOD NAME: FormatToStr(strbDest) const
  526. //
  527. // DESCRIPTION:
  528. //
  529. //  This method will format this object to the passed string buffer. For this
  530. //  class, we just format some debug info since this guy has no outwardly
  531. //  visible data members.
  532. // ---------------------------------------
  533. //   INPUT: None
  534. //
  535. //  OUTPUT: strbDest is the string buffer to format into.
  536. //
  537. //  RETURN: None
  538. //
  539. tCIDLib::VOID PROCEXP WINDOW::FormatToStr(STRGBUF& strbDest) const
  540. {
  541.     strbDest << "Id=" << __c4Id 
  542.              << ", HWND=" << CARDINAL(__hwndThis, tCIDLib::eRADIX_HEX);
  543. }
  544.  
  545.  
  546.  
  547. // -----------------------------------------------------------------------------
  548. //  WINDOW: Public, virtual methods
  549. // -----------------------------------------------------------------------------
  550.  
  551. //
  552. // FUNCTION/METHOD NAME: bPaint(areaInvalid, ptbTarget)
  553. //
  554. // DESCRIPTION:
  555. //
  556. //  This is the default paint method if the derived class does not handle it.
  557. //  We just do an erase of the invalid area.
  558. // ---------------------------------------
  559. //   INPUT: areaInvalid is the invalid area. We don't use it here.
  560. //          ptbTarget is a painting object that is set up to paint on this
  561. //              window. We just fill the invalid area.
  562. //
  563. //  OUTPUT: None
  564. //
  565. //  RETURN: eTRUE to indicate that we handled it and it should not be passed
  566. //              to the default handler.
  567. //
  568. tCIDLib::eBOOL PROCEXP WINDOW::bPaint(  const   AREA&       areaInvalid
  569.                                         ,       PAINTBRUSH& ptbTarget)
  570. {
  571.     // Make the compiler happy
  572.     areaInvalid;
  573.  
  574.     // Do the erase
  575.     if (!GpiErase(ptbTarget))
  576.     {
  577.         facCIDGui.LogLastSysErr(__FILE__
  578.                                 , "WINDOW::bPaint"
  579.                                 , __LINE__
  580.                                 , "GpiErase failed"
  581.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  582.     }
  583.     return tCIDLib::eTRUE;
  584. }
  585.  
  586.  
  587. //
  588. // FUNCTION/METHOD NAME: bPopUpMenu(pntPos)
  589. //
  590. // DESCRIPTION:
  591. //
  592. //  This menu will popup the menu for this window, if any.
  593. // ---------------------------------------
  594. //   INPUT: pntPos is the position to place the lower left corner of the menu
  595. //
  596. //  OUTPUT: None
  597. //
  598. //  RETURN: eTRUE if successful, else eFALSE.
  599. //
  600. tCIDLib::eBOOL PROCEXP WINDOW::bPopUpMenu(const POINT& pntPos)
  601. {
  602.     if (!__pmenuThis)
  603.         return tCIDLib::eFALSE;
  604.  
  605.     // Get the parent of this window for the parent of the menu
  606.     WINDOW& wndCtlParent = wndParent();
  607.  
  608.     // Translate the point to the parent's coordinates
  609.     POINT   pntTmp(pntPos);
  610.     wndCtlParent.TranslateCoord(pntTmp, *this);
  611.  
  612.     //
  613.     //  Now popup the menu. Be sure to pass *this, not the raw handle,
  614.     //  because that will create a new window object.
  615.     //
  616.     __pmenuThis->PopUp(wndCtlParent, *this, pntTmp);
  617.  
  618.     return tCIDLib::eTRUE;
  619. }
  620.  
  621.  
  622. //
  623. // FUNCTION/METHOD NAME: SetMenu(pwndNewMenu, bDestroyOldMenu)
  624. //
  625. // DESCRIPTION:
  626. //
  627. //  This menu will install the passed menu object as the top level menu for
  628. //  this window object.
  629. // ---------------------------------------
  630. //   INPUT: wndNewMenu is a pointer to the new pop up menu object to install
  631. //          bDestroyOldMenu, if eTRUE, will cause the currently installed
  632. //              menu object to be destroyed.
  633. //
  634. //  OUTPUT: None
  635. //
  636. //  RETURN: None
  637. //
  638. tCIDLib::VOID PROCEXP WINDOW::SetMenu(  POPUPMENU*          pmenuNew
  639.                                         , tCIDLib::eBOOL    bDestroyOldMenu)
  640. {
  641.     //
  642.     //  If there is a current menu object, then we need to destroy it if
  643.     //  bDestroyOldMenu is eTRUE. If not, then do nothing. We will overwrite
  644.     //  its pointer with the new menu object.
  645.     //
  646.     if (bDestroyOldMenu && __pmenuThis)
  647.     {
  648.         delete __pmenuThis;
  649.         __pmenuThis = 0;
  650.     }
  651.  
  652.     // Store away the pointer to the menu
  653.     __pmenuThis = pmenuNew;
  654. }
  655.  
  656.  
  657. // -----------------------------------------------------------------------------
  658. //  WINDOW: Public, non-virtual methods
  659. // -----------------------------------------------------------------------------
  660.  
  661. //
  662. // FUNCTION/METHOD NAME: areaWnd() const
  663. //
  664. // DESCRIPTION:
  665. //
  666. //  Returns the area of the window object. It will contain the size and
  667. //  position relative to its parent.
  668. // ---------------------------------------
  669. //   INPUT: None
  670. //
  671. //  OUTPUT: None
  672. //
  673. //  RETURN: The area of the window
  674. //
  675. AREA PROCEXP WINDOW::areaWnd() const
  676. {
  677.     SWP     swpTmp;
  678.  
  679.     if (!WinQueryWindowPos(__hwndThis, &swpTmp))
  680.     {
  681.         // It failed, so we need to log a message and abort
  682.         facCIDGui.LogLastSysErr(__FILE__
  683.                                 , "WINDOW::areaWnd"
  684.                                 , __LINE__
  685.                                 , "WinQueryWindowPos"
  686.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  687.     }
  688.     return AREA(swpTmp);
  689. }
  690.  
  691.  
  692. //
  693. // FUNCTION/METHOD NAME: areaSize() const
  694. //
  695. // DESCRIPTION:
  696. //
  697. //  Returns the size of the window object. This is just like areaWnd()
  698. //  except that it returns a 0 based area regardless of the position of the
  699. //  window relative to its parent.
  700. // ---------------------------------------
  701. //   INPUT: None
  702. //
  703. //  OUTPUT: None
  704. //
  705. //  RETURN: The size of the window
  706. //
  707. AREA PROCEXP WINDOW::areaWndSize() const
  708. {
  709.     AREA    areaTmp;
  710.     SWP     swpTmp;
  711.  
  712.     if (!WinQueryWindowPos(__hwndThis, &swpTmp))
  713.     {
  714.         // It failed, so we need to log a message and abort
  715.         facCIDGui.LogLastSysErr(__FILE__
  716.                                 , "WINDOW::areaWndSize"
  717.                                 , __LINE__
  718.                                 , "WinQueryWindowPos failed"
  719.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  720.     }
  721.     swpTmp.x = 0;
  722.     swpTmp.y = 0;
  723.     return AREA(swpTmp);
  724. }
  725.  
  726.  
  727. //
  728. // FUNCTION/METHOD NAME: bGotFocus() const
  729. //
  730. // DESCRIPTION:
  731. //
  732. //  This method will return eTRUE if this window object has the focus, else
  733. //  eFALSE.
  734. // ---------------------------------------
  735. //   INPUT: None
  736. //
  737. //  OUTPUT: None
  738. //
  739. //  RETURN: eTRUE if this window has the focus, else eFALSE.
  740. //
  741. tCIDLib::eBOOL PROCEXP WINDOW::bGotFocus() const
  742. {
  743.     if (WinQueryFocus(HWND_DESKTOP) == __hwndThis)
  744.         return tCIDLib::eTRUE;
  745.      else
  746.         return tCIDLib::eFALSE;
  747. }
  748.  
  749.  
  750. //
  751. // FUNCTION/METHOD NAME: bIsChildWindow(wndTest)
  752. //
  753. // DESCRIPTION:
  754. //
  755. //  This method will test the passed window to see if it is a descendant
  756. //  (not necessarily a direct child) of this window.
  757. // ---------------------------------------
  758. //   INPUT: wndTest is the window to test for childhood
  759. //
  760. //  OUTPUT: None
  761. //
  762. //  RETURN: eTRUE if the passed window is a child, else eFALSE.
  763. //
  764. tCIDLib::eBOOL PROCEXP WINDOW::bIsChildWindow(const WINDOW& wndTest)
  765. {
  766.     if (WinIsChild(wndTest, __hwndThis))
  767.         return tCIDLib::eTRUE;
  768.      else
  769.         return tCIDLib::eFALSE;
  770. }
  771.  
  772.  
  773. //
  774. // FUNCTION/METHOD NAME: bIsEnabled() const
  775. //
  776. // DESCRIPTION:
  777. //
  778. //  This method will return a boolean that indicates whether this window is
  779. //  enabled or not.
  780. // ---------------------------------------
  781. //   INPUT: None
  782. //
  783. //  OUTPUT: None
  784. //
  785. //  RETURN: eTRUE if enabled, else eFALSE.
  786. //
  787. tCIDLib::eBOOL PROCEXP WINDOW::bIsEnabled() const
  788. {
  789.     if (WinIsWindowEnabled(__hwndThis))
  790.         return tCIDLib::eTRUE;
  791.      else
  792.         return tCIDLib::eFALSE;
  793. }
  794.  
  795.  
  796. //
  797. // FUNCTION/METHOD NAME: bIsShowing() const
  798. //
  799. // DESCRIPTION:
  800. //
  801. //  This method will return a flag that indicates whether any portion of
  802. //  this window is showing or not. This is not the same as the window's
  803. //  visibility state, which hides or shows the window. This flag indicates
  804. //  when the window, even if it is visible, might be totally covered up.
  805. // ---------------------------------------
  806. //   INPUT: None
  807. //
  808. //  OUTPUT: None
  809. //
  810. //  RETURN: eTRUE if visible, else eFALSE.
  811. //
  812. tCIDLib::eBOOL PROCEXP WINDOW::bIsShowing() const
  813. {
  814.     if (WinIsWindowShowing(__hwndThis))
  815.         return tCIDLib::eTRUE;
  816.      else
  817.         return tCIDLib::eFALSE;
  818. }
  819.  
  820.  
  821. //
  822. // FUNCTION/METHOD NAME: bIsVisible() const
  823. //
  824. // DESCRIPTION:
  825. //
  826. //  This method will return the visibility status of this window
  827. // ---------------------------------------
  828. //   INPUT: None
  829. //
  830. //  OUTPUT: None
  831. //
  832. //  RETURN: eTRUE if visible, else eFALSE.
  833. //
  834. tCIDLib::eBOOL PROCEXP WINDOW::bIsVisible() const
  835. {
  836.     if (WinIsWindowVisible(__hwndThis))
  837.         return tCIDLib::eTRUE;
  838.      else
  839.         return tCIDLib::eFALSE;
  840. }
  841.  
  842.  
  843. //
  844. // FUNCTION/METHOD NAME: bQueryPresColor(ePresClr, rgbClr)
  845. //
  846. // DESCRIPTION:
  847. //
  848. //  This method will look for the indicated presentation color for this
  849. //  window. If one has not been set, then the caller should query the
  850. //  appropriate system color.
  851. // ---------------------------------------
  852. //   INPUT: ePresClr is the presentation color to query
  853. //          
  854. //  OUTPUT: rgbClr is filled in with the color, if found. If the return
  855. //              value is eFALSE, then it is unchanged.
  856. //
  857. //  RETURN: eTRUE if the presentation color was available, else eFALSE.
  858. //
  859. tCIDLib::eBOOL
  860.         PROCEXP WINDOW::bQueryPresColor(tCIDGui::ePRESCLRS  ePresClr
  861.                                         , RGBCLR&           rgbClr) const
  862. {
  863.     tCIDLib::CARD4  c4Found;
  864.     tCIDLib::INT4   i4Value;
  865.  
  866.     if (!WinQueryPresParam( __hwndThis
  867.                             , ePresClr
  868.                             , 0
  869.                             , &c4Found
  870.                             , sizeof(i4Value)
  871.                             , &i4Value
  872.                             , QPF_NOINHERIT))
  873.     {
  874.         return tCIDLib::eFALSE;
  875.     }
  876.     rgbClr = i4Value;
  877.     return tCIDLib::eTRUE;
  878. }
  879.  
  880.  
  881. //
  882. // FUNCTION/METHOD NAME: bQueryWndColor(ePresClr, eSysClr, rgbResult)
  883. //
  884. // DESCRIPTION:
  885. //
  886. //  This method will try to find the passed presparam color first, then the
  887. //  the passed system color. It will return the first one found.
  888. // ---------------------------------------
  889. //   INPUT: ePresClr is the desired presparam color
  890. //          eSysClr is the desired system color that will be used if the
  891. //              presparam color is not set.
  892. //
  893. //  OUTPUT: rgbResult is filled in with the color
  894. //
  895. //  RETURN: eTRUE if the presparam color was found, else eFALSE if the system
  896. //              color was found.
  897. //
  898. tCIDLib::eBOOL WINDOW::bQueryWndColor(  tCIDGui::ePRESCLRS      ePresClr
  899.                                         , tCIDGui::eSYSCOLORS   eSysClr
  900.                                         , RGBCLR&               rgbResult) const
  901. {
  902.     tCIDLib::CARD4  c4Found;
  903.     tCIDLib::INT4   i4Clr;
  904.  
  905.     // Try the presparam first
  906.     if (WinQueryPresParam(  __hwndThis
  907.                             , ePresClr
  908.                             , 0
  909.                             , &c4Found
  910.                             , sizeof(i4Clr)
  911.                             , &i4Clr
  912.                             , QPF_NOINHERIT))
  913.     {
  914.         rgbResult = i4Clr;
  915.         return tCIDLib::eTRUE;
  916.     }
  917.  
  918.     // Did not get it so try the system color
  919.     i4Clr = WinQuerySysColor(HWND_DESKTOP, eSysClr, 0);
  920.  
  921.     rgbResult = i4Clr;
  922.     return tCIDLib::eFALSE;
  923. }
  924.  
  925.  
  926. //
  927. // FUNCTION/METHOD NAME: c4WindowTextLen() const
  928. //
  929. // DESCRIPTION:
  930. //
  931. //  This method will return the length of the winodw text.
  932. // ---------------------------------------
  933. //   INPUT: None
  934. //
  935. //  OUTPUT: None
  936. //
  937. //  RETURN: The length of the window text.
  938. //
  939. tCIDLib::CARD4 PROCEXP WINDOW::c4WindowTextLen() const
  940. {
  941.     return tCIDLib::CARD4(WinQueryWindowTextLength(__hwndThis));
  942. }
  943.  
  944.  
  945. //
  946. // FUNCTION/METHOD NAME: CaptureMouse()
  947. //
  948. // DESCRIPTION:
  949. //
  950. //  Calling this message will allow this window to receive all mouse input
  951. //  messages until ReleaseMouse() is called. It should be used with
  952. //  restraint. Of course, since it affects a global resource.
  953. // ---------------------------------------
  954. //   INPUT: None
  955. //
  956. //  OUTPUT: None
  957. //
  958. //  RETURN: None
  959. //
  960. tCIDLib::VOID PROCEXP WINDOW::CaptureMouse()
  961. {
  962.     if (!WinSetCapture(HWND_DESKTOP, __hwndThis))
  963.     {
  964.         facCIDGui.LogLastSysErr(__FILE__
  965.                                 , "WINDOW::CaptureMouse"
  966.                                 , __LINE__
  967.                                 , "WinSetCapture failed"
  968.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  969.     }
  970.     __bMouseCaptured = tCIDLib::eTRUE;
  971. }
  972.  
  973.  
  974. //
  975. // FUNCTION/METHOD NAME: Disable()
  976. //
  977. // DESCRIPTION:
  978. //
  979. //  This method will disable the window
  980. // ---------------------------------------
  981. //   INPUT: None
  982. //
  983. //  OUTPUT: None
  984. //
  985. //  RETURN: None
  986. //
  987. tCIDLib::VOID PROCEXP WINDOW::Disable()
  988. {
  989.     if (!WinEnableWindow(__hwndThis, 0))
  990.     {
  991.         facCIDGui.LogLastSysErr(__FILE__
  992.                                 , "WINDOW::Disable"
  993.                                 , __LINE__
  994.                                 , "WinEnableWindow"
  995.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  996.     }
  997.  
  998.     // Repaint the window
  999.     ForceRepaint();
  1000. }
  1001.  
  1002.  
  1003. //
  1004. // FUNCTION/METHOD NAME: Enable()
  1005. //
  1006. // DESCRIPTION:
  1007. //
  1008. //  This method will enable the window
  1009. // ---------------------------------------
  1010. //   INPUT: None
  1011. //
  1012. //  OUTPUT: None
  1013. //
  1014. //  RETURN: None
  1015. //
  1016. tCIDLib::VOID PROCEXP WINDOW::Enable()
  1017. {
  1018.     if (!WinEnableWindow(__hwndThis, 1))
  1019.     {
  1020.         facCIDGui.LogLastSysErr(__FILE__
  1021.                                 , "WINDOW::Enable"
  1022.                                 , __LINE__
  1023.                                 , "WinEnableWindow"
  1024.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1025.     }
  1026.  
  1027.     // Repaint the window
  1028.     ForceRepaint();
  1029. }
  1030.  
  1031.  
  1032. //
  1033. // FUNCTION/METHOD NAME: ExitMsgLoop()
  1034. //
  1035. // DESCRIPTION:
  1036. //
  1037. //  This method will post a quit message to the message loop to cause it to
  1038. //  exit.
  1039. // ---------------------------------------
  1040. //   INPUT: None
  1041. //
  1042. //  OUTPUT: None
  1043. //
  1044. //  RETURN: None
  1045. //
  1046. tCIDLib::VOID PROCEXP WINDOW::ExitMsgLoop()
  1047. {
  1048.     if (!WinPostMsg(__hwndThis, WM_QUIT, 0, 0))
  1049.     {
  1050.         facCIDGui.LogLastSysErr(__FILE__
  1051.                                 , "WINDOW::ExitMsgLoop"
  1052.                                 , __LINE__
  1053.                                 , "Could not post WM_QUIT"
  1054.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1055.     }
  1056. }
  1057.  
  1058.  
  1059. //
  1060. // FUNCTION/METHOD NAME: eWndStyles() const
  1061. //
  1062. // DESCRIPTION:
  1063. //
  1064. //  This method will return the current window styles. We get them from PM.
  1065. // ---------------------------------------
  1066. //   INPUT: None
  1067. //
  1068. //  OUTPUT: None
  1069. //
  1070. //  RETURN: The current window styles.
  1071. //
  1072. tCIDGui::eWNDSTYLES PROCEXP WINDOW::eWndStyles() const
  1073. {
  1074.     return tCIDGui::eWNDSTYLES(WinQueryWindowULong(__hwndThis, QWL_STYLE));
  1075. }
  1076.  
  1077.  
  1078. //
  1079. // FUNCTION/METHOD NAME: eWndStyles(eNewStyles, eRelevant)
  1080. //
  1081. // DESCRIPTION:
  1082. //
  1083. //  This method will set the window styles. Derived classes provide their
  1084. //  own method to set their styles, but they just cast their styles to
  1085. //  window styles and call this method.
  1086. // ---------------------------------------
  1087. //   INPUT: eNewStyles is the new styles to set
  1088. //          eRelevant is the mask that indicates which bits in eNewStyles
  1089. //              are to be set.
  1090. //
  1091. //  OUTPUT: None
  1092. //
  1093. //  RETURN: The current window styles
  1094. //
  1095. tCIDGui::eWNDSTYLES PROCEXP
  1096.             WINDOW::eWndStyles(  tCIDGui::eWNDSTYLES    eNewStyles
  1097.                                 , tCIDGui::eWNDSTYLES   eRelevant)
  1098. {
  1099.     // Query the current PM styles.
  1100.     tCIDLib::CARD4 c4PMStyles = WinQueryWindowULong(__hwndThis, QWL_STYLE);
  1101.  
  1102.     //
  1103.     //  Turn off the relevant bits. This means we only have to reset those
  1104.     //  that the user wants set. The cleared state is now a default.
  1105.     //
  1106.     c4PMStyles &= ~tCIDLib::CARD4(eRelevant);
  1107.  
  1108.     tCIDLib::CARD4  c4Mask = 0x1;
  1109.     for (tCIDLib::CARD4 c4Ind = 0; c4Ind < 31; c4Ind++)
  1110.     {
  1111.         if (eRelevant & c4Mask)
  1112.         {
  1113.             if (eNewStyles & c4Mask)
  1114.                 c4PMStyles |= c4Mask;
  1115.         }
  1116.         c4Mask <<= 1;
  1117.     }
  1118.  
  1119.     //
  1120.     //  We now need to write back out the PM style flags.
  1121.     //
  1122.     if (!WinSetWindowULong(__hwndThis, QWL_STYLE, c4PMStyles))
  1123.     {
  1124.         facCIDGui.LogLastSysErr(__FILE__
  1125.                                 , "WINDOW::eWndStyles"
  1126.                                 , __LINE__
  1127.                                 , "WinSetWindowULong failed"
  1128.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1129.     }
  1130.  
  1131.     // Return the new styles
  1132.     return tCIDGui::eWNDSTYLES(c4PMStyles);
  1133. }
  1134.  
  1135.  
  1136. //
  1137. // FUNCTION/METHOD NAME: ForceRepaint(bChildrenToo)
  1138. //
  1139. // DESCRIPTION:
  1140. //
  1141. //  This method will invalidate the whole window causing its paint method to
  1142. //  be called.
  1143. // ---------------------------------------
  1144. //   INPUT: bChildrenToo indicates whether children should be invalidated
  1145. //              also. The default is eTRUE.
  1146. //
  1147. //  OUTPUT: None
  1148. //
  1149. //  RETURN: None
  1150. //
  1151. tCIDLib::VOID PROCEXP WINDOW::ForceRepaint(tCIDLib::eBOOL bChildrenToo)
  1152. {
  1153.     if (!WinInvalidateRect(__hwndThis, 0, bChildrenToo))
  1154.     {
  1155.         facCIDGui.LogLastSysErr(__FILE__
  1156.                                 , "WINDOW::ForceRepaint"
  1157.                                 , __LINE__
  1158.                                 , "WinInvalidateRect failed"
  1159.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1160.     }
  1161. }
  1162.  
  1163.  
  1164. //
  1165. // FUNCTION/METHOD NAME: Hide()
  1166. //
  1167. // DESCRIPTION:
  1168. //
  1169. //  This method will turn off the visibility style for the window
  1170. // ---------------------------------------
  1171. //   INPUT: None
  1172. //
  1173. //  OUTPUT: None
  1174. //
  1175. //  RETURN: None
  1176. //
  1177. tCIDLib::VOID PROCEXP WINDOW::Hide()
  1178. {
  1179.     if (!WinShowWindow(__hwndThis, 0))
  1180.     {
  1181.         facCIDGui.LogLastSysErr(__FILE__
  1182.                                 , "WINDOW::Hide"
  1183.                                 , __LINE__
  1184.                                 , "WinShowWindow failed"
  1185.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1186.     }
  1187. }
  1188.  
  1189.  
  1190. //
  1191. // FUNCTION/METHOD NAME: InvalidateArea(areaInvalidate, bDoClippedChild)
  1192. //
  1193. // DESCRIPTION:
  1194. //
  1195. //  This method will invalidate the passed area, causing the window to
  1196. //  receive a paint with this area as the update region.
  1197. // ---------------------------------------
  1198. //   INPUT: areaInvalidate is the area to invalidate.
  1199. //          bDoClippedChild indicates whether clipped children should be
  1200. //              invalidated as well. The default is eFALSE.
  1201. //
  1202. //  OUTPUT: None
  1203. //
  1204. //  RETURN: None
  1205. //
  1206. tCIDLib::VOID
  1207.     PROCEXP WINDOW::InvalidateArea( const AREA&         areaInvalidate
  1208.                                     , tCIDLib::eBOOL    bDoClippedChild)
  1209. {
  1210.     RECTL   rectlTmp;
  1211.  
  1212.     // Convert to a non-inclusive rectangle
  1213.     areaInvalidate.ToRectl(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
  1214.  
  1215.     if (!WinInvalidateRect(__hwndThis, &rectlTmp, bDoClippedChild))
  1216.     {
  1217.         // It failed, so we need to log a message and abort
  1218.         facCIDGui.LogLastSysErr(__FILE__
  1219.                                 , "WINDOW::InvalidateArea"
  1220.                                 , __LINE__
  1221.                                 , "WinInvalidateRect failed"
  1222.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1223.     }
  1224. }
  1225.  
  1226.  
  1227. //
  1228. // FUNCTION/METHOD NAME: pntWndOrg() const
  1229. //
  1230. // DESCRIPTION:
  1231. //
  1232. //  This method will return a point that contains the origin of the window
  1233. //  relative to its parent.
  1234. // ---------------------------------------
  1235. //   INPUT: None
  1236. //
  1237. //  OUTPUT: None
  1238. //
  1239. //  RETURN: A POINT object with the window's origin
  1240. //
  1241. POINT PROCEXP WINDOW::pntWndOrg() const
  1242. {
  1243.     SWP     swpTmp;
  1244.  
  1245.     if (!WinQueryWindowPos(__hwndThis, &swpTmp))
  1246.     {
  1247.         // It failed, so we need to log a message and abort
  1248.         facCIDGui.LogLastSysErr(__FILE__
  1249.                                 , "WINDOW::pntWndOrg"
  1250.                                 , __LINE__
  1251.                                 , "WinQueryWindowPos failed"
  1252.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1253.     }
  1254.     return POINT(swpTmp.x, swpTmp.y);
  1255. }
  1256.  
  1257. //
  1258. // FUNCTION/METHOD NAME: ReleaseMouse()
  1259. //
  1260. // DESCRIPTION:
  1261. //
  1262. //  This method undoes a call to CaptureMouse()
  1263. // ---------------------------------------
  1264. //   INPUT: None
  1265. //
  1266. //  OUTPUT: None
  1267. //
  1268. //  RETURN: None
  1269. //
  1270. tCIDLib::VOID PROCEXP WINDOW::ReleaseMouse()
  1271. {
  1272.     if (!WinSetCapture(HWND_DESKTOP, 0))
  1273.     {
  1274.         facCIDGui.LogLastSysErr(__FILE__
  1275.                                 , "WINDOW::ReleaseMouse"
  1276.                                 , __LINE__
  1277.                                 , "WinSetCapture failed"
  1278.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1279.     }
  1280.     __bMouseCaptured = tCIDLib::eFALSE;
  1281. }
  1282.  
  1283.  
  1284. //
  1285. // FUNCTION/METHOD NAME: ScrollArea(areaScroll, i4CX, i4CY, bInvalidate
  1286. //                                  , bScrollChildren)
  1287. //                       ScrollArea(areaScroll, i4CX, i4CY, areaInvalidated
  1288. //                                  , areaClip, bInvalidate, bScrollChildren)
  1289. //
  1290. // DESCRIPTION:
  1291. //
  1292. //  These methods will scroll the indicated area in the indicated directions.
  1293. //  There is a simple version that just scrolls the whole area with an
  1294. //  optional invalidation of the uncovered area. The second version allows a
  1295. //  clip area and returns the invalidated area.
  1296. // ---------------------------------------
  1297. //   INPUT: areaScroll is the area to scroll
  1298. //          i4CX, i4CY are the directions to scroll in the x and y directions
  1299. //          areaClip is the clip area to use during the scroll
  1300. //          bInvalidate indicates whether the uncovered area will be
  1301. //              invalidated.
  1302. //          bScrollChildren indicates whether children should be scrolled as
  1303. //              well.
  1304. //
  1305. //  OUTPUT: areaInvalidated is filled in with the invalidated area
  1306. //
  1307. //  RETURN: None
  1308. //
  1309. tCIDLib::VOID
  1310.     PROCEXP WINDOW::ScrollArea( const   AREA&           areaScroll
  1311.                                 ,       tCIDLib::INT4   i4CX
  1312.                                 ,       tCIDLib::INT4   i4CY
  1313.                                 ,       tCIDLib::eBOOL  bInvalidate
  1314.                                 ,       tCIDLib::eBOOL  bScrollChildren)
  1315. {
  1316.     RECTL           rectlTmp;
  1317.     tCIDLib::CARD4  c4Flags = 0;
  1318.  
  1319.     if (bInvalidate)
  1320.         c4Flags |= SW_INVALIDATERGN;
  1321.  
  1322.     if (bScrollChildren)
  1323.         c4Flags |= SW_SCROLLCHILDREN;
  1324.  
  1325.     areaScroll.ToRectl(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
  1326.     if (WinScrollWindow(__hwndThis
  1327.                         , i4CX, i4CY
  1328.                         , &rectlTmp
  1329.                         , 0
  1330.                         , 0
  1331.                         , 0
  1332.                         , c4Flags) == RGN_ERROR)
  1333.     {
  1334.         // It failed, so we need to log a message and abort
  1335.         facCIDGui.LogLastSysErr(__FILE__
  1336.                                 , "WINDOW::ScrollArea"
  1337.                                 , __LINE__
  1338.                                 , "WinScrollWindow failed"
  1339.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1340.     }
  1341. }
  1342.  
  1343. tCIDLib::VOID
  1344.     PROCEXP WINDOW::ScrollArea( const   AREA&           areaScroll
  1345.                                 ,       tCIDLib::INT4   i4CX
  1346.                                 ,       tCIDLib::INT4   i4CY
  1347.                                 ,       AREA&           areaInvalidated
  1348.                                 , const AREA&           areaClip
  1349.                                 ,       tCIDLib::eBOOL  bInvalidate
  1350.                                 ,       tCIDLib::eBOOL  bScrollChildren)
  1351. {
  1352.     RECTL           rectlTmp, rectlUpdate, rectlClip;
  1353.     tCIDLib::CARD4  c4Flags = 0;
  1354.  
  1355.     if (bInvalidate)
  1356.         c4Flags |= SW_INVALIDATERGN;
  1357.  
  1358.     if (bScrollChildren)
  1359.         c4Flags |= SW_SCROLLCHILDREN;
  1360.  
  1361.     areaScroll.ToRectl(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
  1362.     areaClip.ToRectl(rectlClip, tCIDGui::eRECTL_NONINCLUSIVE);
  1363.  
  1364.     if (WinScrollWindow(__hwndThis
  1365.                         , i4CX, i4CY
  1366.                         , &rectlTmp
  1367.                         , &rectlClip
  1368.                         , 0
  1369.                         , &rectlUpdate
  1370.                         , c4Flags) == RGN_ERROR)
  1371.     {
  1372.         facCIDGui.LogLastSysErr(__FILE__
  1373.                                 , "WINDOW::ScrollArea"
  1374.                                 , __LINE__
  1375.                                 , "WinScrollWindow failed"
  1376.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1377.     }
  1378.  
  1379.     // Get the update rectangle to the output area
  1380.     areaInvalidated.FromRectl(rectlUpdate, tCIDGui::eRECTL_NONINCLUSIVE);
  1381. }
  1382.  
  1383.  
  1384. //
  1385. // FUNCTION/METHOD NAME: SetPresColor(ePresClr, rgbClr)
  1386. //
  1387. // DESCRIPTION:
  1388. //
  1389. //  This method will set the indicated presentation color to the passed
  1390. //  color value.
  1391. // ---------------------------------------
  1392. //   INPUT: ePresClr is the presentation color to set
  1393. //          rgbClr is the new color to apply
  1394. //
  1395. //  OUTPUT: None
  1396. //
  1397. //  RETURN: None
  1398. //
  1399. tCIDLib::VOID PROCEXP
  1400.             WINDOW::SetPresColor(           tCIDGui::ePRESCLRS  ePresClr
  1401.                                     , const RGBCLR&             rgbClr)
  1402. {
  1403.     //
  1404.     //  Note that we cast the RGBCLR object to a long value, which causes
  1405.     //  the implicit operator to return a pointer to the color info. It is
  1406.     //  in the right order so that the low 3 bytes look like an RGB.
  1407.     //
  1408.     tCIDLib::INT4 i4Clr = rgbClr;
  1409.     if (!WinSetPresParam(   __hwndThis
  1410.                             , ePresClr
  1411.                             , sizeof(RGB)
  1412.                             , &i4Clr))
  1413.     {
  1414.         facCIDGui.LogLastSysErr(__FILE__
  1415.                                 , "WINDOW::SetPresColor"
  1416.                                 , __LINE__
  1417.                                 , "WinSetPresParam failed"
  1418.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1419.     }
  1420. }
  1421.  
  1422.  
  1423. //
  1424. // FUNCTION/METHOD NAME: SetSWPFlags(eSwp, areaComponent, wndBehind)
  1425. //
  1426. // DESCRIPTION:
  1427. //
  1428. //  This method allows a number of position/size/zorder/min/max operations
  1429. //  to be done at once very efficiently.
  1430. // ---------------------------------------
  1431. //   INPUT: eSwp contains the flags that indicate the operations.
  1432. //          areaComponent is the area to set. This is used if the size
  1433. //              or move or min or max or restore options flags are
  1434. //              set. Defaults to NUL_AREA.
  1435. //          wndBehind is used is the z order flag is set. It is the window
  1436. //              to install behind. NUL_WINDOW.
  1437. //
  1438. //  OUTPUT: None
  1439. //
  1440. //  RETURN: None
  1441. //
  1442. tCIDLib::VOID PROCEXP
  1443.         WINDOW::SetSWPFlags(        tCIDGui::eSWPFLAGS  eSwp
  1444.                             , const AREA&               areaComponent
  1445.                             , const WINDOW&             wndBehind)
  1446. {
  1447.     // Zero out an SWP structure to use
  1448.     SWP swpTmp;
  1449.     SetMemory(&swpTmp, 0, sizeof(SWP));
  1450.  
  1451.     // Copy over the flags
  1452.     swpTmp.fl = eSwp;
  1453.  
  1454.     //
  1455.     //  If the area is present, then get the info. If not, then make sure
  1456.     //  that no flags are on that require it.
  1457.     //
  1458.     if (&areaComponent)
  1459.     {
  1460.         swpTmp.x    = areaComponent.i4X();
  1461.         swpTmp.y    = areaComponent.i4Y();
  1462.         swpTmp.cx   = areaComponent.c4CX();
  1463.         swpTmp.cy   = areaComponent.c4CY();
  1464.     }
  1465.      else
  1466.     {
  1467.         if (swpTmp.fl & (SWP_SIZE | SWP_MOVE | SWP_MINIMIZE))
  1468.         {
  1469.             facCIDGui.LogErr(   __FILE__
  1470.                                 , "WINDOW::SetSWPFlags"
  1471.                                 , __LINE__
  1472.                                 , GUIERR_WIN_BAD_SWP_FLAGS
  1473.                                 , tCIDLib::eSEV_PROCESS_FATAL
  1474.                                 , tCIDLib::eCLASS_BADPARMS
  1475.                                 , STRG16("Size/Move/Minimize")
  1476.                                 , STRG16("area"));
  1477.         }
  1478.     }
  1479.  
  1480.     //
  1481.     //  If the window parameter is present, then get the handle. If not,
  1482.     //  make sure that the z order option is not present.
  1483.     //
  1484.     if (&wndBehind)
  1485.     {
  1486.         swpTmp.hwndInsertBehind = wndBehind.hwndThis();
  1487.     }
  1488.      else
  1489.     {
  1490.         if (swpTmp.fl & SWP_ZORDER)
  1491.         {
  1492.             facCIDGui.LogErr(   __FILE__
  1493.                                 , "WINDOW::SetSWPFlags"
  1494.                                 , __LINE__
  1495.                                 , GUIERR_WIN_BAD_SWP_FLAGS
  1496.                                 , tCIDLib::eSEV_PROCESS_FATAL
  1497.                                 , tCIDLib::eCLASS_BADPARMS
  1498.                                 , STRG16("ZORDER")
  1499.                                 , STRG16("window"));
  1500.         }
  1501.     }
  1502.  
  1503.     // Do the set operation now
  1504.     if (!WinSetWindowPos(   hwndThis()
  1505.                             , swpTmp.hwndInsertBehind
  1506.                             , swpTmp.x
  1507.                             , swpTmp.y
  1508.                             , swpTmp.cx
  1509.                             , swpTmp.cy
  1510.                             , swpTmp.fl))
  1511.     {
  1512.         facCIDGui.LogLastSysErr(__FILE__
  1513.                                 , "WINDOW::SetSWPFlags"
  1514.                                 , __LINE__
  1515.                                 , "WinSetWindowPos failed"
  1516.                                 , tCIDLib::eSEV_API_FAILED);
  1517.     }
  1518. }
  1519.  
  1520.  
  1521. //
  1522. // FUNCTION/METHOD NAME: SetWndPos(pntNewOrg)
  1523. //                       SetWndSize(c4CX, c4CY)
  1524. //                       SetWndSizePos(areaNew)
  1525. //
  1526. // DESCRIPTION:
  1527. //
  1528. //  These methods will set the size/position
  1529. // ---------------------------------------
  1530. //   INPUT: pntNewOrg is the new orgin when setting the new position
  1531. //          c4CX,c4CY are the new sizes when setting the size
  1532. //          areaNew is the new when setting both
  1533. //
  1534. //  OUTPUT: None
  1535. //
  1536. //  RETURN: None
  1537. //
  1538. tCIDLib::VOID PROCEXP WINDOW::SetWndPos(const POINT& pntNewOrg)
  1539. {
  1540.     if (!WinSetWindowPos(   __hwndThis
  1541.                             , HWND(0)
  1542.                             , pntNewOrg.i4X()
  1543.                             , pntNewOrg.i4Y()
  1544.                             , 0
  1545.                             , 0
  1546.                             , SWP_MOVE))
  1547.     {
  1548.         facCIDGui.LogLastSysErr(__FILE__
  1549.                                 , "WINDOW::SetWndPos"
  1550.                                 , __LINE__
  1551.                                 , "WinSetWindowPos failed"
  1552.                                 , tCIDLib::eSEV_API_FAILED);
  1553.     }
  1554. }
  1555.  
  1556. tCIDLib::VOID PROCEXP WINDOW::SetWndSize(   tCIDLib::CARD4      c4CX
  1557.                                             , tCIDLib::CARD4    c4CY)
  1558. {
  1559.     if (!WinSetWindowPos(   __hwndThis
  1560.                             , HWND(0)
  1561.                             , 0
  1562.                             , 0
  1563.                             , c4CX
  1564.                             , c4CY
  1565.                             , SWP_SIZE))
  1566.     {
  1567.         // It failed, so we need to log a message and return
  1568.         facCIDGui.LogLastSysErr(__FILE__
  1569.                                 , "WINDOW::SetWndSize"
  1570.                                 , __LINE__
  1571.                                 , "WinSetWindowPos failed"
  1572.                                 , tCIDLib::eSEV_API_FAILED);
  1573.     }
  1574. }
  1575.  
  1576. tCIDLib::VOID PROCEXP WINDOW::SetWndSizePos(const AREA& areaNew)
  1577. {
  1578.     if (!WinSetWindowPos(   __hwndThis
  1579.                             , HWND(0)
  1580.                             , areaNew.i4X()
  1581.                             , areaNew.i4Y()
  1582.                             , areaNew.c4CX()
  1583.                             , areaNew.c4CY()
  1584.                             , SWP_SIZE | SWP_MOVE))
  1585.     {
  1586.         // It failed, so we need to log a message and return
  1587.         facCIDGui.LogLastSysErr(__FILE__
  1588.                                 , "WINDOW::SetWndSizePos"
  1589.                                 , __LINE__
  1590.                                 , "WinSetWindowPos failed"
  1591.                                 , tCIDLib::eSEV_API_FAILED);
  1592.     }
  1593. }
  1594.  
  1595.  
  1596. //
  1597. // FUNCTION/METHOD NAME: Show()
  1598. //
  1599. // DESCRIPTION:
  1600. //
  1601. //  This method will turn on the visibility style for the winodw
  1602. // ---------------------------------------
  1603. //   INPUT: None
  1604. //
  1605. //  OUTPUT: None
  1606. //
  1607. //  RETURN: None
  1608. //
  1609. tCIDLib::VOID PROCEXP WINDOW::Show()
  1610. {
  1611.     if (!WinShowWindow(__hwndThis, 1))
  1612.     {
  1613.         facCIDGui.LogLastSysErr(__FILE__
  1614.                                 , "WINDOW::Show"
  1615.                                 , __LINE__
  1616.                                 , "WinShowWindow failed"
  1617.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1618.     }
  1619. }
  1620.  
  1621.  
  1622. //
  1623. // FUNCTION/METHOD NAME: strWndText() const
  1624. //                       strWndText(strbNewText)
  1625. //
  1626. // DESCRIPTION:
  1627. //
  1628. //  These methods get/set the window text. We have to deal with PM window
  1629. //  text, but we need to copy into the __strWndText and return a constant
  1630. //  reference to it.
  1631. // ---------------------------------------
  1632. //   INPUT: strbNewText is the new text to set.
  1633. //
  1634. //  OUTPUT: None
  1635. //
  1636. //  RETURN: A constant reference to the window text.
  1637. //
  1638. const STRING& PROCEXP WINDOW::strWndText() const
  1639. {
  1640.     // Get the window text length and realloc the string to fit
  1641.     tCIDLib::INT4 i4Len = (tCIDLib::INT4)WinQueryWindowTextLength(*this);
  1642.  
  1643.     ((STRING*)&__strWndText)->Realloc(i4Len);
  1644.  
  1645.     //
  1646.     //  NOTE: The buffer is one larger than the max size method. This call
  1647.     //  wants the full size of the buffer, not the maximum chars.
  1648.     //
  1649.     WinQueryWindowText( __hwndThis
  1650.                         , __strWndText.c4MaxSize()+1
  1651.                         , __strWndText.pSZ());
  1652.     return __strWndText;
  1653. }
  1654.  
  1655. const STRING& PROCEXP WINDOW::strWndText(const STRGBUF& strbNewText)
  1656. {
  1657.     // Copy the text to our buffer
  1658.     __strWndText.Realloc(strbNewText.c4MaxSize());
  1659.     __strWndText = strbNewText;
  1660.  
  1661.     if (!WinSetWindowText(__hwndThis, __strWndText.pSZ()))
  1662.     {
  1663.         facCIDGui.LogLastSysErr(__FILE__
  1664.                                 , "WINDOW::strWndText"
  1665.                                 , __LINE__
  1666.                                 , "WinSetWindowText failed"
  1667.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1668.     }
  1669.     return __strWndText;
  1670. }
  1671.  
  1672.  
  1673. //
  1674. // FUNCTION/METHOD NAME: TakeFocus()
  1675. //
  1676. // DESCRIPTION:
  1677. //
  1678. //  This method will cause the calling window object to take the focus.
  1679. // ---------------------------------------
  1680. //   INPUT: None
  1681. //
  1682. //  OUTPUT: None
  1683. //
  1684. //  RETURN: None
  1685. //
  1686. tCIDLib::VOID PROCEXP WINDOW::TakeFocus()
  1687. {
  1688.     if (!WinSetFocus(HWND_DESKTOP, __hwndThis))
  1689.     {
  1690.         facCIDGui.LogLastSysErr(__FILE__
  1691.                                 , "WINDOW::TakeFocus"
  1692.                                 , __LINE__
  1693.                                 , "WinSetFocus failed"
  1694.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1695.     }
  1696. }
  1697.  
  1698.  
  1699. //
  1700. // FUNCTION/METHOD NAME: ToBottom()
  1701. //                       ToTop()
  1702. //
  1703. // DESCRIPTION:
  1704. //
  1705. //  This method will move this window to the top or bottom of its sibling
  1706. //  windows.
  1707. // ---------------------------------------
  1708. //   INPUT: None
  1709. //
  1710. //  OUTPUT: None
  1711. //
  1712. //  RETURN: None
  1713. //
  1714. tCIDLib::VOID PROCEXP WINDOW::ToBottom()
  1715. {
  1716.     if (!WinSetWindowPos(   *this
  1717.                             , HWND_BOTTOM
  1718.                             , 0, 0, 0, 0
  1719.                             , SWP_ZORDER))
  1720.     {
  1721.         facCIDGui.LogLastSysErr(__FILE__
  1722.                                 , "WINDOW::ToBottom"
  1723.                                 , __LINE__
  1724.                                 , "WinSetWindowPos failed"
  1725.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1726.     }
  1727. }
  1728.  
  1729. tCIDLib::VOID PROCEXP WINDOW::ToTop()
  1730. {
  1731.     if (!WinSetWindowPos(   *this
  1732.                             , HWND_TOP
  1733.                             , 0, 0, 0, 0
  1734.                             , SWP_ZORDER))
  1735.     {
  1736.         facCIDGui.LogLastSysErr(__FILE__
  1737.                                 , "WINDOW::ToTop"
  1738.                                 , __LINE__
  1739.                                 , "WinSetWindowPos failed"
  1740.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1741.     }
  1742. }
  1743.  
  1744.  
  1745. //
  1746. // FUNCTION/METHOD NAME: TranslateCoord(pntTmp, wndSrc)
  1747. //
  1748. // DESCRIPTION:
  1749. //
  1750. //  This method will translate the passed coordinates from the source
  1751. //  window's coordinate system to this window's.
  1752. // ---------------------------------------
  1753. //   INPUT: wndSrc is the source window whose coordinate system the passed
  1754. //              point is in.
  1755. //
  1756. //  OUTPUT: pntTmp is updated to the new coordinates.
  1757. //
  1758. //  RETURN: None
  1759. //
  1760. tCIDLib::VOID PROCEXP WINDOW::TranslateCoord(           POINT&  pntTmp
  1761.                                                 , const WINDOW& wndSrc)
  1762. {
  1763.     POINTL  ptlTmp;
  1764.  
  1765.     if (!WinMapWindowPoints(wndSrc.__hwndThis
  1766.                             , __hwndThis
  1767.                             , pntTmp
  1768.                             , 1))
  1769.     {
  1770.         facCIDGui.LogLastSysErr(__FILE__
  1771.                                 , "WINDOW::TranslateCoord"
  1772.                                 , __LINE__
  1773.                                 , "WinMapWindowPoints failed"
  1774.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1775.     }
  1776. }
  1777.  
  1778.  
  1779. //
  1780. // FUNCTION/METHOD NAME: wndChildFromId(c4Id)
  1781. //
  1782. // DESCRIPTION:
  1783. //
  1784. //  This method will return a WINDOW pointer for the indicated child window.
  1785. //  The desired window must be child of this window and have the indicated
  1786. //  id.
  1787. // ---------------------------------------
  1788. //   INPUT: c4Id is the id of the child window
  1789. //
  1790. //  OUTPUT: None
  1791. //
  1792. //  RETURN: A reference to the correct WINDOW object. If the window does not
  1793. //              exist, then the return can be NUL_WINDOW.
  1794. //
  1795. WINDOW& PROCEXP WINDOW::wndChildFromId(tCIDLib::CARD4 c4Id) const
  1796. {
  1797.     HWND    hwndChild = WinWindowFromID(__hwndThis, c4Id);
  1798.  
  1799.     if (!hwndChild)
  1800.         return NUL_WINDOW;
  1801.  
  1802.     WINDOW* pwndTmp = (WINDOW*)(WinQueryWindowPtr(hwndChild, QWL_USER));
  1803.  
  1804.     if (!pwndTmp)
  1805.     {
  1806.         facCIDGui.LogErr(   __FILE__
  1807.                             , "WINDOW::wndOwner"
  1808.                             , __LINE__
  1809.                             , GUIERR_GEN_NOT_CIDLIB_WINDOW
  1810.                             , tCIDLib::eSEV_PROCESS_FATAL
  1811.                             , tCIDLib::eCLASS_CANTDO
  1812.                             , strWndText());
  1813.     }
  1814.     return *pwndTmp;
  1815. }
  1816.  
  1817.  
  1818. //
  1819. // FUNCTION/METHOD NAME: wndChildUnderPnt(pntPos, bDeep)
  1820. //
  1821. // DESCRIPTION:
  1822. //
  1823. //  This method will find the highest z order child window that lies under
  1824. //  the passed point. If none, then NUL_WINDOW is returned.
  1825. // ---------------------------------------
  1826. //   INPUT: pntPos is the position to check for a hit, relative to the
  1827. //              origin of this window.
  1828. //          bPoint indictes whether all descendants should be searched or
  1829. //              just direct children.
  1830. //
  1831. //  OUTPUT: None
  1832. //
  1833. //  RETURN: A reference to the window that was hit, else NUL_WINDOW.
  1834. //
  1835. WINDOW& PROCEXP WINDOW::wndChildUnderPnt(   const   POINT&          pntPos
  1836.                                             ,       tCIDLib::eBOOL  bDeep)
  1837. {
  1838.     HWND    hwndChild = WinWindowFromPoint(__hwndThis, pntPos, bDeep);
  1839.  
  1840.     if ((hwndChild == 0) || (hwndChild == __hwndThis))
  1841.         return NUL_WINDOW;
  1842.  
  1843.     // Make sure that it is not a title bar
  1844.     if (WinQueryWindowUShort(hwndChild, QWS_ID) == FID_TITLEBAR)
  1845.         return NUL_WINDOW;
  1846.  
  1847.     // Get a pointer to the child window object
  1848.     WINDOW* pwndTmp = (WINDOW*)WinQueryWindowPtr(hwndChild, QWL_USER);
  1849.  
  1850.     if (!pwndTmp)
  1851.     {
  1852.         facCIDGui.LogErr(   __FILE__
  1853.                             , "WINDOW::wndChildUnderPnt"
  1854.                             , __LINE__
  1855.                             , GUIERR_GEN_NOT_CIDLIB_WINDOW
  1856.                             , tCIDLib::eSEV_PROCESS_FATAL
  1857.                             , tCIDLib::eCLASS_CANTDO
  1858.                             , strWndText());
  1859.     }
  1860.  
  1861.     return *pwndTmp;
  1862. }
  1863.  
  1864.  
  1865. //
  1866. // FUNCTION/METHOD NAME: wndEnumChildren(wndChild, eEnumChild)
  1867. //
  1868. // DESCRIPTION:
  1869. //
  1870. //  This method will find other child windows in other groups or in the
  1871. //  same group as the passed child. This is used to provide tab sequence
  1872. //  management. This guy calls a protected virtual method to let derived
  1873. //  types actual handle this operation. If they don't handle it, then we
  1874. //  use the default PM logic.
  1875. // ---------------------------------------
  1876. //   INPUT: wndChild is the child window from which we start
  1877. //          eEnumChild indicates the relation to the passed child of the
  1878. //              window to find.
  1879. //
  1880. //  OUTPUT: None
  1881. //
  1882. //  RETURN: A reference to the window or NUL_WINDOW if not found.
  1883. //
  1884. WINDOW& PROCEXP
  1885.         WINDOW::wndEnumChildren(const   WINDOW&             wndChild
  1886.                                 ,       tCIDGui::eENUMCHILD eEnumChild)
  1887. {
  1888.     tCIDLib::eBOOL  bHandled    = tCIDLib::eFALSE;
  1889.  
  1890.     // Give derived types the first shot
  1891.     WINDOW& wndTmp = _wndEnumChildren(wndChild, eEnumChild, bHandled);
  1892.  
  1893.     if (bHandled)
  1894.         return wndTmp;
  1895.  
  1896.     HWND hwndNew = WinEnumDlgItem(__hwndThis, wndChild.__hwndThis, eEnumChild);
  1897.     if (!hwndNew)
  1898.         return NUL_WINDOW;
  1899.  
  1900.     // Get the window object address from the window and return that
  1901.     return *((WINDOW*)WinQueryWindowPtr(hwndNew, QWL_USER));
  1902. }
  1903.  
  1904.  
  1905. //
  1906. // FUNCTION/METHOD NAME: wndOwner(wndNewOwner)
  1907. //
  1908. // DESCRIPTION:
  1909. //
  1910. //  This method will set/get the owner window.
  1911. // ---------------------------------------
  1912. //   INPUT: wndNewOwner is the new owner window
  1913. //
  1914. //  OUTPUT: None
  1915. //
  1916. //  RETURN: A reference to the new/current owner window. If none,
  1917. //              then NUL_WINDOW.
  1918. //
  1919. const WINDOW& PROCEXP WINDOW::wndOwner(const WINDOW& wndNewOwner)
  1920. {
  1921.     if (!WinSetOwner(__hwndThis, wndNewOwner))
  1922.     {
  1923.         facCIDGui.LogLastSysErr(__FILE__
  1924.                                 , "WINDOW::wndOwner(WINDOW)"
  1925.                                 , __LINE__
  1926.                                 , "WinSetOwner failed"
  1927.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1928.     }
  1929.     return wndNewOwner;
  1930. }
  1931.  
  1932. WINDOW& PROCEXP WINDOW::wndOwner() const
  1933. {
  1934.     HWND    hwndOwner = WinQueryWindow(__hwndThis, QW_OWNER);
  1935.  
  1936.     if (!hwndOwner)
  1937.         return NUL_WINDOW;
  1938.  
  1939.     WINDOW* pwndTmp = (WINDOW*)WinQueryWindowPtr(hwndOwner, QWL_USER);
  1940.  
  1941.     if (!pwndTmp)
  1942.     {
  1943.         facCIDGui.LogErr(   __FILE__
  1944.                             , "WINDOW::wndOwner"
  1945.                             , __LINE__
  1946.                             , GUIERR_GEN_NOT_CIDLIB_WINDOW
  1947.                             , tCIDLib::eSEV_PROCESS_FATAL
  1948.                             , tCIDLib::eCLASS_CANTDO
  1949.                             , strWndText());
  1950.     }
  1951.     return *pwndTmp;
  1952. }
  1953.  
  1954.  
  1955. //
  1956. // FUNCTION/METHOD NAME: wndParent(wndNewParent, bRedraw)
  1957. //
  1958. // DESCRIPTION:
  1959. //
  1960. //  This method will make the passed window the parent of this window.
  1961. // ---------------------------------------
  1962. //   INPUT: wndNewParent is the new parent window to set
  1963. //          bRedraw indicates whether the window should be redrawn after the
  1964. //              parent is changed.
  1965. //
  1966. //  OUTPUT: None
  1967. //
  1968. //  RETURN: A reference to the parent window object
  1969. //
  1970. const WINDOW& PROCEXP WINDOW::wndParent(const   WINDOW&         wndNewParent
  1971.                                         ,       tCIDLib::eBOOL  bRedraw)
  1972. {
  1973.     if (!WinSetParent(__hwndThis, wndNewParent, bRedraw))
  1974.     {
  1975.         facCIDGui.LogLastSysErr(__FILE__
  1976.                                 , "WINDOW::wndParent"
  1977.                                 , __LINE__
  1978.                                 , "WinSetParent failed"
  1979.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  1980.     }
  1981.  
  1982.     return wndNewParent;
  1983. }
  1984.  
  1985.  
  1986. //
  1987. // FUNCTION/METHOD NAME: wndParent()
  1988. //
  1989. // DESCRIPTION:
  1990. //
  1991. //  This method will get/set the parent window
  1992. // ---------------------------------------
  1993. //   INPUT: None
  1994. //
  1995. //  OUTPUT: None
  1996. //
  1997. //  RETURN: A reference to the parent window object
  1998. //
  1999. WINDOW& PROCEXP WINDOW::wndParent() const
  2000. {
  2001.     HWND    hwndParent = WinQueryWindow(__hwndThis, QW_PARENT);
  2002.  
  2003.     if (!hwndParent)
  2004.     {
  2005.         facCIDGui.LogLastSysErr(__FILE__
  2006.                                 , "WINDOW::wndParent"
  2007.                                 , __LINE__
  2008.                                 , ""
  2009.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  2010.     }
  2011.     WINDOW* pwndTmp = (WINDOW*)WinQueryWindowPtr(hwndParent, QWL_USER);
  2012.  
  2013.     if (!pwndTmp)
  2014.     {
  2015.         facCIDGui.LogErr(   __FILE__
  2016.                             , "WINDOW::wndOwner"
  2017.                             , __LINE__
  2018.                             , GUIERR_GEN_NOT_CIDLIB_WINDOW
  2019.                             , tCIDLib::eSEV_PROCESS_FATAL
  2020.                             , tCIDLib::eCLASS_CANTDO
  2021.                             , STRG16("The parent of window:")
  2022.                             , strWndText());
  2023.     }
  2024.     return *pwndTmp;
  2025. }
  2026.  
  2027.  
  2028. // -----------------------------------------------------------------------------
  2029. //  WINDOW: Protected, virtual methods
  2030. // -----------------------------------------------------------------------------
  2031.  
  2032. //
  2033. // FUNCTION/METHOD NAME: _bQueryWndParms(pParmBuf)
  2034. //                       _bSetWndParms(pParmBuf)
  2035. //
  2036. // DESCRIPTION:
  2037. //
  2038. //  This is the default handler for this message method. It just supports
  2039. //  window text ignores the other queried/set parms.
  2040. // ---------------------------------------
  2041. //   INPUT: None
  2042. //
  2043. //  OUTPUT: pParmBuf is a pointer to a PM WNDPARAMS structure
  2044. //
  2045. //  RETURN: eTRUE to indicate that we handled it
  2046. //
  2047. tCIDLib::eBOOL PROCEXP WINDOW::_bQueryWndParams(tCIDLib::VOID* pParmBuf) const
  2048. {
  2049.     PWNDPARAMS  pwpTmp = (PWNDPARAMS)pParmBuf;
  2050.  
  2051.     // Init everything to 'not handled' statuses as defaults
  2052.     pwpTmp->cchText     = 0;
  2053.     pwpTmp->pszText     = 0;
  2054.     pwpTmp->cbPresParams= 0;
  2055.     pwpTmp->pPresParams = 0;
  2056.     pwpTmp->cbCtlData   = 0;
  2057.     pwpTmp->pCtlData    = 0;
  2058.  
  2059.     //
  2060.     //  We only support the text and text length, so check for them. We leave
  2061.     //  the other flags untouched to indicate that they are not returned.
  2062.     //
  2063.     if (WPM_CCHTEXT & pwpTmp->fsStatus)
  2064.     {
  2065.         pwpTmp->cchText = __strWndText.c4Length();
  2066.         pwpTmp->fsStatus &= ~WPM_CCHTEXT;
  2067.     }
  2068.  
  2069.     if (WPM_TEXT & pwpTmp->fsStatus)
  2070.     {
  2071.         pwpTmp->pszText = __strWndText.pSZ();
  2072.         pwpTmp->fsStatus &= ~WPM_TEXT;
  2073.     }
  2074.     return tCIDLib::eTRUE;
  2075. }
  2076.  
  2077. tCIDLib::eBOOL PROCEXP WINDOW::_bSetWndParams(tCIDLib::VOID* pParmBuf)
  2078. {
  2079.     PWNDPARAMS  pwpTmp = (PWNDPARAMS)pParmBuf;
  2080.  
  2081.     //
  2082.     //  We only support the text, so check for it. If it is set, then assign
  2083.     //  the passed text to the string and clear the status flag. Check for a
  2084.     //  null though.
  2085.     //
  2086.     if (WPM_TEXT & pwpTmp->fsStatus)
  2087.     {
  2088.         if (pwpTmp->pszText)
  2089.             __strWndText = (tCIDLib::CH*)pwpTmp->pszText;
  2090.          else
  2091.             __strWndText.Clear();
  2092.  
  2093.         pwpTmp->fsStatus &= ~WPM_TEXT;
  2094.     }
  2095.     return tCIDLib::eTRUE;
  2096. }
  2097.  
  2098.  
  2099. // -----------------------------------------------------------------------------
  2100. //  WINDOW: Protected, inherited methods
  2101. // -----------------------------------------------------------------------------
  2102.  
  2103. //
  2104. // FUNCTION/METHOD NAME: _bIsEqual(objTarget) const
  2105. //
  2106. // DESCRIPTION:
  2107. //
  2108. // ---------------------------------------
  2109. //   INPUT: objTarget is the target object to compare against
  2110. //
  2111. //  OUTPUT: None
  2112. //
  2113. //  RETURN: eTRUE if the objects are equal, else eFALSE.
  2114. //
  2115. tCIDLib::eBOOL PROCEXP WINDOW::_bIsEqual(const CIDOBJECT& objTarget) const
  2116. {
  2117.     // Call our parent's version first
  2118.     if (!CIDOBJECT::_bIsEqual(objTarget))
  2119.         return tCIDLib::eFALSE;
  2120.  
  2121.     // Look at the object as a window
  2122.     WINDOW* pwndTarget = (WINDOW*)(&objTarget);
  2123.  
  2124.     // Compare the window handles
  2125.     if (__hwndThis != pwndTarget->__hwndThis)
  2126.         return tCIDLib::eFALSE;
  2127.  
  2128.     return tCIDLib::eTRUE;
  2129. }
  2130.  
  2131. // -----------------------------------------------------------------------------
  2132. //  WINDOW: Protected, non-virtual methods
  2133. // -----------------------------------------------------------------------------
  2134.  
  2135. //
  2136. // FUNCTION/METHOD NAME: _CreateCursor(areaCursor, areaClip, eCursorType)
  2137. //
  2138. // DESCRIPTION:
  2139. //
  2140. //  This method will create a PM cursor of the indicate area and type,
  2141. //  clipped to the clip area.
  2142. // ---------------------------------------
  2143. //   INPUT: areaCursor is the area of the new cursor
  2144. //          areaClip is the area to clip the cursor to
  2145. //          eCursorType is the style of the cursor to create
  2146. //
  2147. //  OUTPUT: None
  2148. //
  2149. //  RETURN: None
  2150. //
  2151. tCIDLib::VOID PROCEXP
  2152.         WINDOW::_CreateCursor(  const   AREA&               areaCursor
  2153.                                 , const AREA&               areaClip
  2154.                                 ,       tCIDGui::eCURSORS   eCursorType)
  2155. {
  2156.     RECTL   rectlClip;
  2157.  
  2158.     areaClip.ToRectl(rectlClip, tCIDGui::eRECTL_NONINCLUSIVE);
  2159.     if (!WinCreateCursor(   __hwndThis
  2160.                             , areaCursor.i4X()
  2161.                             , areaCursor.i4Y()
  2162.                             , areaCursor.c4CX()
  2163.                             , areaCursor.c4CY()
  2164.                             , eCursorType
  2165.                             , &rectlClip))
  2166.     {
  2167.         facCIDGui.LogLastSysErr(__FILE__
  2168.                                 , "WINDOW::_CreateCursor"
  2169.                                 , __LINE__
  2170.                                 , "WinCreateCursor failed"
  2171.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  2172.     }
  2173. }
  2174.  
  2175. //
  2176. // FUNCTION/METHOD NAME: _DestroyCursor()
  2177. //
  2178. // DESCRIPTION:
  2179. //
  2180. //  Destroys the current cursor for this window, if one exists.
  2181. // ---------------------------------------
  2182. //   INPUT: None
  2183. //
  2184. //  OUTPUT: None
  2185. //
  2186. //  RETURN: None
  2187. //
  2188. tCIDLib::VOID PROCEXP WINDOW::_DestroyCursor()
  2189. {
  2190.     if (!WinDestroyCursor(__hwndThis))
  2191.     {
  2192.         facCIDGui.LogLastSysErr(__FILE__
  2193.                                 , "WINDOW::_DestroyCursor"
  2194.                                 , __LINE__
  2195.                                 , "WinDestroyCursor failed"
  2196.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  2197.     }
  2198. }
  2199.  
  2200.  
  2201. //
  2202. // FUNCTION/METHOD NAME: _MoveCursor(pntNewPos)
  2203. //
  2204. // DESCRIPTION:
  2205. //
  2206. //  This method will move the current cursor to the indicate position.
  2207. // ---------------------------------------
  2208. //   INPUT: pntNewPos is the new cursor origin
  2209. //
  2210. //  OUTPUT: None
  2211. //
  2212. //  RETURN: None
  2213. //
  2214. tCIDLib::VOID PROCEXP WINDOW::_MoveCursor(const POINT& pntNewPos)
  2215. {
  2216.     if (!WinCreateCursor(   __hwndThis
  2217.                             , pntNewPos.i4X()
  2218.                             , pntNewPos.i4Y()
  2219.                             , 0
  2220.                             , 0
  2221.                             , CURSOR_SETPOS
  2222.                             , 0))
  2223.     {
  2224.         facCIDGui.LogLastSysErr(__FILE__
  2225.                                 , "WINDOW::_MoveCursor"
  2226.                                 , __LINE__
  2227.                                 , "WinMoveCursor failed"
  2228.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  2229.     }
  2230. }
  2231.  
  2232.  
  2233. //
  2234. // FUNCTION/METHOD NAME: _mresHandleMsg(hwndThis, c4Msg, mp1, mp2)
  2235. //
  2236. // DESCRIPTION:
  2237. //
  2238. //  This method is called from the main class' window procedure any time that
  2239. //  a message is received. It will handle getting the message to the correct
  2240. //  place.
  2241. //
  2242. //  NOTE:   To support repeat counts in char messages, WM_CHAR calls the
  2243. //          default window proc manually instead of falling through to
  2244. //          the bottom of the method.
  2245. //
  2246. //  NOTE:   Don't declare any complex local objects because the constructors
  2247. //          will be called on every entry to this method, and recursively to
  2248. //          make matters worse. Each case below allocates the objects it
  2249. //          needs.
  2250. // ---------------------------------------
  2251. //   INPUT: hwndThis is the handle of the window that got the message
  2252. //          c4Msg is the message it got
  2253. //          mp1, mp2 are the message parms
  2254. //
  2255. //  OUTPUT: None
  2256. //
  2257. //  RETURN: If the message is handled by the derived class, then its return
  2258. //              is returned. Else the return of the backup window proc is
  2259. //              returned.
  2260. //
  2261. MRESULT PROCEXP WINDOW::_mresHandleMsg( HWND                hwndThis
  2262.                                         , tCIDLib::CARD4    c4Msg
  2263.                                         , MPARAM            mp1
  2264.                                         , MPARAM            mp2)
  2265. {
  2266.     tCIDLib::eBOOL      bTmp;
  2267.     tCIDLib::CARD2      c2Tmp;
  2268.     tCIDLib::CARD4      c4Index, c4Tmp;
  2269.  
  2270.     if (((c4Msg >= WM_BUTTONCLICKFIRST) && (c4Msg <= WM_BUTTONCLICKLAST))
  2271.     ||  (c4Msg == WM_BUTTON1CLICK)
  2272.     ||  (c4Msg == WM_BUTTON2CLICK)
  2273.     ||  (c4Msg == WM_BUTTON3CLICK)
  2274.     ||  (c4Msg == WM_CHORD))
  2275.     {
  2276.         //
  2277.         //  $CIDWATCH_DEPENUM$
  2278.         //
  2279.         //  Handle button click events. We can cast the message directly to
  2280.         //  the click type parm since they have the same values as their
  2281.         //  message equivalent.
  2282.         //
  2283.         POINT pntPos(SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
  2284.  
  2285.         if (bClick(tCIDGui::eMOUSECLKS(c4Msg), pntPos))
  2286.             return 0;
  2287.     }
  2288.      else if (c4Msg == WM_CHAR)
  2289.     {
  2290.         //
  2291.         //  Parse the character and call the correct character method. We
  2292.         //  only send messages for key down messages, forgoing the ability
  2293.         //  to sense keyup messages in order to simplify things. So get the
  2294.         //  flags word and operate according to what it tells us.
  2295.         //
  2296.         c2Tmp = SHORT1FROMMP(mp1);
  2297.  
  2298.         //
  2299.         //  $CIDWATCH_DEPENUM$
  2300.         //
  2301.         //  We cast PM values into an enum for passing to the window object.
  2302.         //  Check for stuff that we just don't deal with at all. Let them go
  2303.         //  to default window proc.
  2304.         //
  2305.         if (!(c2Tmp
  2306.         &    (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP | KC_KEYUP)))
  2307.         {
  2308.             // Translate the shifts into our type of bit mask
  2309.             c4Tmp = tCIDGui::eSHIFT_NONE;
  2310.             if (c2Tmp & KC_SHIFT)
  2311.                 c4Tmp |= tCIDGui::eSHIFT_SHIFT;
  2312.  
  2313.             if (c2Tmp & KC_ALT)
  2314.                 c4Tmp |= tCIDGui::eSHIFT_ALT;
  2315.  
  2316.             if (c2Tmp & KC_CTRL)
  2317.                 c4Tmp |= tCIDGui::eSHIFT_CTRL;
  2318.  
  2319.             for (c4Index = 0; c4Index < CHAR3FROMMP(mp1); c4Index++)
  2320.             {
  2321.                 if (c2Tmp & KC_VIRTUALKEY)
  2322.                 {
  2323.                     bTmp = bExtendedChar(tCIDGui::eEXTKEYS(SHORT2FROMMP(mp2))
  2324.                                          , tCIDGui::eSHIFTKEYS(c4Tmp));
  2325.                 }
  2326.                  else if (c2Tmp & KC_CHAR)
  2327.                 {
  2328.                     bTmp = bChar(   tCIDLib::CH(SHORT1FROMMP(mp2))
  2329.                                     , tCIDGui::eSHIFTKEYS(c4Tmp));
  2330.                 }
  2331.                 if (!bTmp)
  2332.                     this->__pfnWndProc(hwndThis, c4Msg, mp1, mp2);
  2333.             }
  2334.  
  2335.             // Return that we dealt with the message
  2336.             return MRESULT(1);
  2337.         }
  2338.     }
  2339.      else if (c4Msg == WM_COMMAND)
  2340.     {
  2341.         //
  2342.         //  Pass on commands from our child menus and buttons. The first
  2343.         //  parm is the notification code, the high word of the 1st
  2344.         //  window param. The next parm is the id of the child. If it is
  2345.         //  not handled, let if fall through to the default handler.
  2346.         //
  2347.         if (_bCommand(SHORT1FROMMP(mp1)))
  2348.             return 0;
  2349.     }
  2350.      else if (c4Msg == WM_CONTEXTMENU)
  2351.     {
  2352.         if (__pmenuThis)
  2353.         {
  2354.             // Allowed derived classes to pre-process menu
  2355.             _InitMenu(*__pmenuThis);
  2356.  
  2357.             // Call the popup menu function
  2358.             POINTS  ptsTmp = *((POINTS*)&mp1);
  2359.             POINT   pntPos(ptsTmp.x, ptsTmp.y);
  2360.  
  2361.             bPopUpMenu(pntPos);
  2362.             return MRESULT(1);
  2363.         }
  2364.     }
  2365.      else if (c4Msg == WM_CONTROL)
  2366.     {
  2367.         //
  2368.         //  This is a notifications from a child control.
  2369.         //
  2370.         //  We echo the control message back to the control itself via
  2371.         //  the _bControl() method. He will process it and pass on the
  2372.         //  processed version this window, if this is desired. If he
  2373.         //  does not process it, we let it go to this window (i.e. the
  2374.         //  owner.)
  2375.         //
  2376.         WINDOW& wndChild = wndChildFromId(SHORT1FROMMP(mp1));
  2377.  
  2378.         if (&wndChild)
  2379.         {
  2380.             if (wndChild._bControl( SHORT2FROMMP(mp1)
  2381.                                     , SHORT1FROMMP(mp1)
  2382.                                     , LONGFROMMP(mp2)))
  2383.             {
  2384.                 return 0;
  2385.             }
  2386.         }
  2387.  
  2388.         if (_bControl(  SHORT2FROMMP(mp1)
  2389.                         , SHORT1FROMMP(mp1)
  2390.                         , LONGFROMMP(mp2)))
  2391.         {
  2392.             return 0;
  2393.         }
  2394.     }
  2395.      else if (c4Msg == WM_CREATE)
  2396.     {
  2397.         //
  2398.         //  We should never get this message here because it is handled by
  2399.         //  the window dispatching function. If we do, then log a message and
  2400.         //  return 1 to indicate an error.
  2401.         //
  2402.         facCIDGui.LogErr(   __FILE__
  2403.                             , "WINDOW::_mresHandleMsg"
  2404.                             , __LINE__
  2405.                             , GUIERR_WIN_WM_CREATE
  2406.                             , tCIDLib::eSEV_WARNING
  2407.                             , tCIDLib::eCLASS_INTERNAL);
  2408.         return MRESULT(1);
  2409.     }
  2410.      else if (c4Msg == WM_CLOSE)
  2411.     {
  2412.         //
  2413.         //  Let the derived class handle not allowing a system menu
  2414.         //  operation to close the application. If he returns eTRUE,
  2415.         //  then he has handled it and we don't pass it on to the
  2416.         //  default handler.
  2417.         //
  2418.         if (bClose())
  2419.             return 0;
  2420.     }
  2421.      else if (c4Msg == WM_DESTROY)
  2422.     {
  2423.         //
  2424.         //  Let the derived classes see this. If the __bDestructing flag is
  2425.         //  set, then we are done because we go here via a call to the
  2426.         //  destructor. Otherwise, we need to call the destructor, clearing
  2427.         //  the window handle first to let him know that we are causing it
  2428.         //  (so he will not try to destroy the window again.)
  2429.         //
  2430.         bDestroy();
  2431.  
  2432.         if (!__bDestructing)
  2433.         {
  2434.             __hwndThis = 0;
  2435.             delete this;
  2436.         }
  2437.         return 0;
  2438.     }
  2439.      else if (c4Msg == WM_ENABLE)
  2440.     {
  2441.         bTmp = SHORT1FROMMP(mp1) ? tCIDLib::eTRUE : tCIDLib::eFALSE;
  2442.  
  2443.         if (bEnableState(bTmp))
  2444.             return 0;
  2445.     }
  2446.      else if ((c4Msg == WM_HSCROLL) || (c4Msg == WM_VSCROLL))
  2447.     {
  2448.         if (bScrollEvent(   SHORT1FROMMP(mp1)
  2449.                             , tCIDGui::eSCROLLEV(SHORT2FROMMP(mp2))
  2450.                             , tCIDLib::INT4(SHORT1FROMMP(mp2))))
  2451.         {
  2452.             return 0;
  2453.         }
  2454.     }
  2455.      else if (c4Msg == WM_MINMAXFRAME)
  2456.     {
  2457.         // Convert the SWP structure to individual parms
  2458.         SWP&                swpTmp = *(SWP*)mp1;
  2459.         AREA                areaNew(swpTmp);
  2460.         tCIDGui::eSWPFLAGS  eFlags = tCIDGui::eSWPFLAGS(swpTmp.fl);
  2461.  
  2462.         //
  2463.         //  Let the frame handle the min/max change
  2464.         //
  2465.         if (_bMinMaxFrame(eFlags, areaNew))
  2466.             return MPARAM(1);
  2467.  
  2468.         // If the user modified the area
  2469.         areaNew.ToSwp(swpTmp);
  2470.         swpTmp.fl = eFlags;
  2471.     }
  2472.      else if (c4Msg == WM_MOVE)
  2473.     {
  2474.         if (bMoved())
  2475.             return 0;
  2476.     }
  2477.      else if (c4Msg == WM_MOUSEMOVE)
  2478.     {
  2479.         //
  2480.         //  Convert the position to a POINT object and pass it along to the
  2481.         //  method.
  2482.         //
  2483.         if (bMouseMove(POINT(SHORT1FROMMP(mp1), SHORT2FROMMP(mp1))))
  2484.             return MPARAM(1);
  2485.     }
  2486.      else if (c4Msg == WM_PAINT)
  2487.     {
  2488.         if (!__bPMPaint)
  2489.         {
  2490.             tCIDLib::eBOOL  bHandled;
  2491.             RECTL           rectlTmp;
  2492.  
  2493.             // Start the paint and get the invalid rectangle
  2494.             HPS hPS = WinBeginPaint(__hwndThis, 0, &rectlTmp);
  2495.  
  2496.             if (!hPS)
  2497.             {
  2498.                 // Log a message
  2499.                 facCIDGui.LogLastSysErr(__FILE__
  2500.                                         , "WINDOW::_mresHandleMsg"
  2501.                                         , __LINE__
  2502.                                         , "WinBeginPaint failed"
  2503.                                         , tCIDLib::eSEV_PROCESS_FATAL);
  2504.             }
  2505.  
  2506.             // Convert the rectangle to an area. The rect is non-inclusive
  2507.             AREA areaInvalid(rectlTmp, tCIDGui::eRECTL_NONINCLUSIVE);
  2508.  
  2509.             //
  2510.             //  Get a paint brush for this window. We call the special,
  2511.             //  protected version is just for paint messages, as it takes a
  2512.             //  PS as a parm instead of creating one. The last parm indicates
  2513.             //  this is a paint PS, as apposed to a persistant one.
  2514.             //
  2515.             PAINTBRUSH* pptbTmp = new PAINTBRUSH(    hPS         
  2516.                                                     , *this
  2517.                                                     , PAINTBRUSH::ePS_PAINT);
  2518.             bHandled = bPaint(areaInvalid, *pptbTmp);
  2519.  
  2520.             // Destroy the paint brush
  2521.             delete pptbTmp;
  2522.  
  2523.             //
  2524.             //  If the message was handled, then return; else, let it go
  2525.             //  the the default
  2526.             //
  2527.             if (bHandled)
  2528.                 return 0;
  2529.         }
  2530.     }
  2531.      else if (c4Msg == WM_PRESPARAMCHANGED)
  2532.     {
  2533.         if (bPresParamChanged())
  2534.             return 0;
  2535.     }
  2536.      else if (c4Msg == WM_QUERYWINDOWPARAMS)
  2537.     {
  2538.         //
  2539.         //  Give the derived class a chance to provide window params. Its
  2540.         //  primary use is for the WINDOW class to support PM window text
  2541.         //  like other windows. Actual PM control classes must override
  2542.         //  this guy and just return eFALSE to let it go to the default
  2543.         //  handler.
  2544.         //
  2545.         if (_bQueryWndParams((tCIDLib::VOID*)mp1))
  2546.             return MRESULT(1);
  2547.     }
  2548.      else if (c4Msg == WM_SETFOCUS)
  2549.     {
  2550.         //
  2551.         //  Call either the losing or getting focus method. If the object
  2552.         //  handles the message, then return 0.
  2553.         //
  2554.         if (SHORT1FROMMP(mp2))
  2555.             bTmp = bGettingFocus();
  2556.           else
  2557.             bTmp = bLosingFocus();
  2558.         if (bTmp)
  2559.             return 0;
  2560.     }
  2561.      else if (c4Msg == WM_SHOW)
  2562.     {
  2563.         bTmp = SHORT1FROMMP(mp1) ? tCIDLib::eTRUE : tCIDLib::eFALSE;
  2564.  
  2565.         if (bShowState(bTmp))
  2566.             return 0;
  2567.     }
  2568.      else if (c4Msg == WM_SIZE)
  2569.     {
  2570.         // Convert the new and old sizes to a AREAs that are 0 based
  2571.         AREA    areaNew(0, 0, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
  2572.         AREA    areaOld(0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
  2573.  
  2574.         if (bSizeChanged(areaNew, areaOld))
  2575.             return 0;
  2576.     }
  2577.      else if (c4Msg == WM_SYSCOMMAND)
  2578.     {
  2579.         if (bIsDescendantOf("FRAMEWND"))
  2580.         {
  2581.             FRAMEWND*   pfrmwTmp = (FRAMEWND*)this;
  2582.  
  2583.             if (pfrmwTmp->bSysCommand(tCIDGui::eSYSCMDS(SHORT1FROMMP(mp1))))
  2584.                 return 0;
  2585.         }
  2586.     }
  2587.      else if (c4Msg == WM_SYSCOLORCHANGE)
  2588.     {
  2589.         if (bSysColorChanged())
  2590.             return 0;
  2591.     }
  2592.      else if (c4Msg >= WM_USER)
  2593.     {
  2594.         //
  2595.         //  It is a user message so call the generic user message event.
  2596.         //
  2597.         if (bUserMsg(c4Msg, tCIDLib::CARD4(mp1), tCIDLib::CARD4(mp2)))
  2598.             return 0;
  2599.     }
  2600.  
  2601.     // If the default window proc is not set in this object, then abort
  2602.     if (!this->__pfnWndProc)
  2603.     {
  2604.         facCIDGui.LogErr(   __FILE__
  2605.                             , "WINDOW::_mresHandleMsg"
  2606.                             , __LINE__
  2607.                             , GUIERR_WIN_NO_WNDPROC
  2608.                             , tCIDLib::eSEV_PROCESS_FATAL
  2609.                             , tCIDLib::eCLASS_INTERNAL
  2610.                             , clsIsA());
  2611.     }
  2612.  
  2613.     //
  2614.     //  No one handled it so call the object's default proc and return its
  2615.     //  return
  2616.     //
  2617.     return this->__pfnWndProc(hwndThis, c4Msg, mp1, mp2);
  2618. }
  2619.  
  2620.  
  2621. //
  2622. // FUNCTION/METHOD NAME: _SendControl(c4Code, c4SrcWndId, c4Data1, c4Data2)
  2623. //
  2624. // DESCRIPTION:
  2625. //
  2626. //  This method will send a control message to the owner window if one
  2627. //  exists.
  2628. // ---------------------------------------
  2629. //   INPUT: c4Code is the notification code
  2630. //          c4SrcWndId is the source window id
  2631. //          c4Data1, c4Data2 are the optional data parms. They default to
  2632. //              0.
  2633. //
  2634. //  OUTPUT: None
  2635. //
  2636. //  RETURN: None
  2637. //
  2638. tCIDLib::VOID PROCEXP WINDOW::_SendControl( tCIDLib::CARD4      c4Code
  2639.                                             , tCIDLib::CARD4    c4SrcWndId
  2640.                                             , tCIDLib::CARD4    c4Data1
  2641.                                             , tCIDLib::CARD4    c4Data2)
  2642. {
  2643.     WINDOW& wndTarget = wndOwner();
  2644.  
  2645.     if (!(&wndTarget))
  2646.     {
  2647.         // Log a message here!!!!!!!
  2648.         return;
  2649.     }
  2650.     wndTarget._bControl(c4Code, c4SrcWndId, c4Data1, c4Data2);
  2651. }
  2652.  
  2653.  
  2654. //
  2655. // FUNCTION/METHOD NAME: _ShowCursor(bState)
  2656. //
  2657. // DESCRIPTION:
  2658. //
  2659. //  This method will set the cursor visible state of this window's cursor.
  2660. // ---------------------------------------
  2661. //   INPUT: bState is the new state
  2662. //
  2663. //  OUTPUT: None
  2664. //
  2665. //  RETURN: None
  2666. //
  2667. tCIDLib::VOID PROCEXP WINDOW::_ShowCursor(tCIDLib::eBOOL bState)
  2668. {
  2669.     if (!WinShowCursor(__hwndThis, bState))
  2670.     {
  2671.         facCIDGui.LogLastSysErr(__FILE__
  2672.                                 , "WINDOW::_ShowCursor"
  2673.                                 , __LINE__
  2674.                                 , "WinShowCursor failed"
  2675.                                 , tCIDLib::eSEV_PROCESS_FATAL);
  2676.     }
  2677. }
  2678.