TWindow

Core Class Root Class source/classes/window.prg

TWindow is the root class of the entire FiveWin class hierarchy. Every visible element in a FiveWin application — dialogs, controls, MDI frames, MDI children — ultimately inherits from TWindow. It wraps a Win32 HWND and provides the foundational API for window creation, event handling, painting, coordinate management, drag-and-drop, tooltips, and more.

Inheritance Hierarchy

TWindow sits at the top of the hierarchy. All major FiveWin classes derive from it directly or indirectly:

classDiagram class TWindow { +hWnd +cCaption +oMenu +oMsgBar +aControls +Activate() +End() +Center() } TWindow <|-- TMDIFrame TWindow <|-- TMDIChild TWindow <|-- TDialog TWindow <|-- TControl TControl <|-- TButton TControl <|-- TGet TControl <|-- TXBrowse TControl <|-- TSay TControl <|-- TFolder TMDIFrame : +oWndClient TMDIChild : +oWndParent TDialog : +lModal TDialog : +lTruePixel

Key DATA Members

DATATypeDefaultDescription
hWndNumeric0Win32 window handle. Assigned after Create() or Activate().
cCaptionCharacternilWindow title bar text.
nTop, nLeft, nBottom, nRightNumeric0Window coordinates (pixels after creation).
oFontTFontnilFont object used for painting and child controls.
oBrushTBrushnilBackground brush. Set via SetColor() or explicitly.
oIconTIconnilWindow icon (title bar and taskbar).
oMenuTMenunilMain menu bar object.
oBarTBarnilToolbar (button bar) docked at the top.
oMsgBarTMsgBarnilStatus/message bar at the bottom.
lVisibleLogical.F.Whether the window is currently shown.
lActiveLogical.T.Whether the window is enabled (accepts input).
aControlsArray{}Array of child control objects.
nClrPaneNumericnilBackground (pane) color.
nClrTextNumericnilDefault text color.
oVScroll, oHScrollTScrollBarnilVertical and horizontal scroll bar objects.
CargoAnynilGeneral-purpose user data slot.
cToolTipCharacternilTooltip text shown on hover.
aGradColorsArraynilGradient color pairs for background painting.
lUnicodeLogical.F.Whether the window uses Unicode (wide-char) API.
hAlphaColorNumericnilAlpha-blend overlay color (RGB value). When set, the window background is blended with this color at hAlphaLevel opacity.
hAlphaLevelNumeric0Alpha blend opacity level (0-255). Used with hAlphaColor.
aMinMaxInfoArraynilArray { nMinW, nMaxW, nMinH, nMaxH } restricting min/max window size.
l2007Logical.F.Enable Office 2007-style theme for the window and its controls.
l2010Logical.F.Enable Office 2010-style theme.
l2013Logical.F.Enable Office 2013-style flat theme.
l2015Logical.F.Enable Office 2015-style theme.
oTopTControlnilControl docked to the top edge. oClient respects this slot during AdjClient().
oLeftTControlnilControl docked to the left edge.
oBottomTControlnilControl docked to the bottom edge (above the message bar).
oRightTControlnilControl docked to the right edge.
oClientTControlnilControl that fills the remaining client area after all docked slots.

Event Code Blocks

TWindow exposes a rich set of code blocks that fire on Win32 events. Assign a block to hook into any event:

Code BlockParametersDescription
bInit|Self|Fires after window creation, before the message loop.
bPainted|hDC, cPS, Self|Custom painting inside WM_PAINT.
bLClicked|nRow, nCol, nFlags|Left mouse button click.
bRClicked|nRow, nCol, nFlags|Right mouse button click.
bKeyDown|nKey, nFlags, Self|Key pressed.
bResized|nSizeType, nWidth, nHeight|Window resized.
bMoved|Self|Window moved.
bValid|Self|Must return .T. to allow closing.
bGotFocus|Self, hFrom|Window received focus.
bLostFocus|Self, hTo|Window lost focus.
bDropFiles|hDrop, Self|Files dropped onto window.
bMouseWheel|nDelta, nKeys|Mouse wheel scrolled.
bKeyChar|nKey, nFlags|Character key pressed (WM_CHAR).
bLButtonDown|nRow, nCol, nFlags|Left mouse button pressed.
bLButtonUp|nRow, nCol, nFlags|Left mouse button released.
bRButtonDown|nRow, nCol, nFlags|Right mouse button pressed.
bMMoved|nRow, nCol, nFlags|Mouse moved over the client area.
bWhen|Self|Must return .T. for window to receive focus.
bPostEnd|Self|Fires after the window has been closed (WM_DESTROY processed).
bDestroy|Self|Fires during WM_DESTROY.
bHelp|nHelpId, Self|Fires on F1 or Help button.
bTimer|hWnd, nMsg, nId, nTime|Fires on each WM_TIMER tick. Use SetTimer().
bCommand|nCtrlId, nNotify|General WM_COMMAND handler.
bMeasureItem|nId, nCtlType|Returns { nW, nH } for owner-drawn items.
bDrawItem|nId, nCtlType, hDC, aRect, nState|Custom owner-draw rendering.
bDragBegin|nRow, nCol, oCtrl|Fires when drag begins. Return .T. to allow.
bDragOver|nRow, nCol, oSource|Dragged object moves over the window.
bDrop|nRow, nCol, oSource|Dragged object dropped on the window.

Key Methods

New() — Constructor

METHOD New( nTop, nLeft, nBottom, nRight, cTitle, nStyle, oMenu,
      oBrush, oIcon, oWnd, lVScroll, lHScroll, nClrFore, nClrBack,
      oCursor, cBorder, lSysMenu, lCaption, lMin, lMax, lPixel,
      nExStyle, cVarName, nHelpId, lUnicode, nWidth, nHeight )

Creates a new TWindow instance but does not show it. The window handle hWnd is not yet created; that happens during Activate().

Activate()

METHOD Activate( cShow, bLClicked, bRClicked, bMoved, bResized,
      bPainted, bKeyDown, bInit, bUp, bDown, bPgUp, bPgDown,
      bLeft, bRight, bPgLeft, bPgRight, bValid, bDropFiles,
      bLButtonUp, lCentered, oMonitor )

Creates the Win32 window, shows it, and enters the message loop. The cShow parameter can be "MAXIMIZED", "ICONIZED", or "NORMAL" (default). The method does not return until the window is closed.

End()

Sends WM_CLOSE to the window. If bValid is set, it is evaluated first; closing is cancelled when bValid returns .F..

Other Essential Methods

MethodDescription
Center( oWnd )Centers the window on screen or within the given parent.
Maximize()Maximizes the window via ShowWindow( SW_MAXIMIZE ).
Minimize()Minimizes the window to the taskbar.
Restore()Restores a minimized or maximized window to normal state.
Move( nTop, nLeft, nWidth, nHeight )Repositions and optionally resizes the window.
SetText( cText )Changes the window caption / title bar text.
SetFont( oFont )Assigns a new font and refreshes all child controls.
SetColor( nClrText, nClrBack )Sets foreground and background colors, creating a brush.
SetSize( nWidth, nHeight )Resizes the window to exact pixel dimensions.
Enable() / Disable()Enables or disables user interaction.
Show() / Hide()Controls visibility without destroying the window.
Refresh()Forces a repaint (InvalidateRect + UpdateWindow).
AddControl( oCtrl )Adds a child control to aControls.
DispBegin() / DispEnd()Bracket double-buffered painting to eliminate flicker.
CoorsUpdate()Synchronizes nTop/nLeft/nBottom/nRight with the actual window rect.
GetCliRect()Returns the client area rectangle as an array { nTop, nLeft, nBottom, nRight }.
Create( cClass, nStyle, nExStyle )Creates the Win32 window via CreateWindowEx().
Resize( nW, nH )Resize the window. Triggers bResized.
SetMenu( oMenu )Assign a TMenu as the main menu bar.
DefControl( oCtrl )Set the default focus control for the window.
Destroy()DestroyWindow() immediately; skips bValid.
Say( nRow, nCol, cText, hDC, nClrT, nClrB, oFont, nAlign, lPixel )Draw text directly on the window.
GetDC() / ReleaseDC( hDC )Obtain/release a device context for manual GDI drawing.
SaveState( cSection, cFile )Save window position, size, and state to INI.
RestoreState( cSection, cFile )Restore window position, size, and state from INI.

Commands: DEFINE WINDOW / ACTIVATE WINDOW

FiveWin provides preprocessor commands that translate to TWindow method calls. This is the recommended way to create windows:

DEFINE WINDOW

DEFINE WINDOW oWnd ;
   [ FROM nTop, nLeft TO nBottom, nRight ] ;
   [ TITLE cTitle ] ;
   [ STYLE nStyle ] ;
   [ MENU oMenu ] ;
   [ BRUSH oBrush ] ;
   [ ICON oIcon ] ;
   [ OF oParent ] ;
   [ VSCROLL ] [ HSCROLL ] ;
   [ COLOR nClrText, nClrBack ] ;
   [ CURSOR oCursor ] ;
   [ BORDER cBorder ] ;   // "NONE", "SINGLE"
   [ NOSYSMENU ] ;
   [ NOCAPTION ] ;
   [ NOMINIMIZE ] ;
   [ NOMAXIMIZE ] ;
   [ PIXEL ] ;
   [ HELPID nHelpId ] ;
   [ UNICODE ]

ACTIVATE WINDOW

ACTIVATE WINDOW oWnd ;
   [ MAXIMIZED | ICONIZED | NORMAL ] ;
   [ ON LEFT CLICK bLClicked ] ;
   [ ON RIGHT CLICK bRClicked ] ;
   [ ON MOVE bMoved ] ;
   [ ON RESIZE bResized ] ;
   [ ON PAINT bPainted ] ;
   [ ON KEYDOWN bKeyDown ] ;
   [ ON INIT bInit ] ;
   [ ON UP bUp ] [ ON DOWN bDown ] ;
   [ ON PAGEUP bPgUp ] [ ON PAGEDOWN bPgDown ] ;
   [ ON LEFT bLeft ] [ ON RIGHT bRight ] ;
   [ VALID bValid ] ;
   [ ON DROP bDropFiles ] ;
   [ CENTERED ]

Window Lifecycle

flowchart LR A["DEFINE WINDOW
(TWindow:New)"] --> B["Build Menu,
Toolbar, StatusBar"] B --> C["ACTIVATE WINDOW
(TWindow:Activate)"] C --> D["Win32 CreateWindow"] D --> E["ON INIT
bInit block"] E --> F["Message Loop
(user interaction)"] F --> G{"User closes
or End()"} G -->|"bValid returns .T."| H["WM_CLOSE /
DestroyWindow"] G -->|"bValid returns .F."| F H --> I["Activate() returns"]

The key insight is that Activate() is a blocking call that runs the Windows message loop. Code placed after ACTIVATE WINDOW only runs after the window has been closed.

Example: Main Window with Menu, Toolbar, and StatusBar

#include "FiveWin.ch"

function Main()

   local oWnd, oBar, oFont

   DEFINE FONT oFont NAME "Segoe UI" SIZE 0, -14

   DEFINE WINDOW oWnd TITLE "My Application" ;
      COLOR CLR_BLACK, CLR_WHITE

   DEFINE BUTTONBAR oBar OF oWnd SIZE 56, 56 2007

   DEFINE BUTTON OF oBar RESOURCE "NEW"  ;
      ACTION MsgInfo( "New document" )    ;
      TOOLTIP "New"

   DEFINE BUTTON OF oBar RESOURCE "OPEN" ;
      ACTION MsgInfo( "Open file" )       ;
      TOOLTIP "Open"

   DEFINE BUTTON OF oBar RESOURCE "SAVE" ;
      ACTION MsgInfo( "Save file" )       ;
      TOOLTIP "Save"

   SET MESSAGE OF oWnd TO "Ready" ;
      CENTERED CLOCK DATE KEYBOARD

   MENU oMenu
      MENUITEM "&File"
      MENU
         MENUITEM "&New"    ACTION MsgInfo( "New" )    MESSAGE "Create new document"
         MENUITEM "&Open"   ACTION MsgInfo( "Open" )   MESSAGE "Open existing file"
         MENUITEM "&Save"   ACTION MsgInfo( "Save" )   MESSAGE "Save current file"
         SEPARATOR
         MENUITEM "E&xit"   ACTION oWnd:End()          MESSAGE "Exit application"
      ENDMENU
      MENUITEM "&Help"
      MENU
         MENUITEM "&About"  ACTION MsgAbout()
      ENDMENU
   ENDMENU

   oWnd:SetMenu( oMenu )
   oWnd:SetFont( oFont )

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT ( oWnd:SetFocus() ) ;
      VALID ( MsgYesNo( "Exit application?" ) )

   oFont:End()

return nil

Example: MDI Application

MDI (Multiple Document Interface) allows a main frame window to host multiple child windows. FiveWin provides TMDIFrame and TMDIChild, both derived from TWindow:

#include "FiveWin.ch"

static oWnd

function Main()

   local oBar

   DEFINE WINDOW oWnd TITLE "MDI Application" MDI ;
      COLOR CLR_BLACK, GetSysColor( COLOR_APPWORKSPACE )

   DEFINE BUTTONBAR oBar OF oWnd SIZE 56, 56 2007

   DEFINE BUTTON OF oBar RESOURCE "NEW" ;
      ACTION NewChild() TOOLTIP "New Document"

   SET MESSAGE OF oWnd TO "Ready" CENTERED CLOCK DATE

   MENU oMenu
      MENUITEM "&File"
      MENU
         MENUITEM "&New Child"  ACTION NewChild()
         SEPARATOR
         MENUITEM "E&xit"       ACTION oWnd:End()
      ENDMENU
      MENUITEM "&Window"
      MENU
         MENUITEM "&Tile"       ACTION oWnd:Tile()
         MENUITEM "Ca&scade"    ACTION oWnd:Cascade()
         MENUITEM "Arrange &Icons" ACTION oWnd:IconArrange()
         SEPARATOR
         MENUITEM "Close &All"  ACTION oWnd:CloseAll()
      ENDMENU
   ENDMENU

   oWnd:SetMenu( oMenu )

   ACTIVATE WINDOW oWnd MAXIMIZED

return nil

//--------------------------------------------------------------------//

static function NewChild()

   local oChild
   static nCount := 0

   nCount++

   DEFINE WINDOW oChild TITLE "Document " + LTrim( Str( nCount ) ) ;
      MDICHILD OF oWnd

   ACTIVATE WINDOW oChild

return nil

Usage Tips

Docking Bars

TWindow provides dedicated docking slots for arranging controls around the window edges. Assign a control to the appropriate slot and call the corresponding adjustment method to create resizable layouts:

SlotDataAdj MethodPosition
Top toolbaroBarAuto-dockedTop edge, full width
Top dockoTopAdjTop()Top edge, below oBar
Bottom dockoBottomAdjBottom()Bottom edge, above oMsgBar
Left dockoLeftAdjLeft()Left edge, between top and bottom
Right dockoRightAdjRight()Right edge, between top and bottom
Client areaoClientAdjClient()Fills remaining space
Status baroMsgBarAuto-dockedBottom edge

The docking system follows a standard layout algorithm: the message bar occupies the bottom, the toolbar the top, then left/right docks claim their widths, and the client control fills whatever space remains. Assign a control to the slot and call AdjClient() (or the specific Adj*() method) to position it. In the ON RESIZE handler, call the methods again to adapt to size changes.

Ver También