Hi,
Is it possible to change the style in the TFolderEx dialog? I tried this
oDlg:oFolder:aDialogs[1]:winstyle(nOr(oDlg:oFolder:aDialogs[1]:nStyle, WS_VSCROLL), .T.)the window has not changed
Hi,
Is it possible to change the style in the TFolderEx dialog? I tried this
oDlg:oFolder:aDialogs[1]:winstyle(nOr(oDlg:oFolder:aDialogs[1]:nStyle, WS_VSCROLL), .T.)the window has not changed
Dear Yuri,
Yes, it is possible, but your current approach has three distinct problems that prevent it from working.
The
Inside
Your call passes
The correct call is simply:
aDialogs[1]:WinStyle( WS_VSCROLL, .T. )passing only the flag bit as the first argument, not the combined style.
Even with the correct
Adding the style afterward leaves
In
This means after
The canonical example of this pattern (for
After activation, configure the
</s> flowchart TD A["DEFINE FOLDEREX oFld ... OF oDlg"] --> B["TFolderEx:New() โ creates aDialogs entries (no hWnd yet)"] B --> C[">>> SET aDialogs[n]:nStyle := nOr(..., WS_VSCROLL) HERE <<<"] C --> D["ACTIVATE DIALOG oDlg"] D --> E["TFolderEx:Initiate() โ Default()"] E --> F["ACTIVATE DIALOG aDialogs[n] NOWAIT"] F --> G["TDialog:Initiate() checks lAnd(nStyle, WS_VSCROLL)"] G --> H["oVScroll is auto-created and ready to configure"] <e>
File: source/classes/window.prg (L2606-2617)
METHOD ToolWindow( nStyle ) CLASS TWindow
DEFAULT nStyle := SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_FRAMECHANGED
SetWindowLong( ::hWnd, GWL_EXSTYLE,;
nOr( GetWindowLong( ::hWnd, GWL_EXSTYLE ), WS_EX_TOOLWINDOW ) )
SetWindowPos( ::hWnd, 0, ::nTop, ::nLeft, ::nRight - ::nLeft + 1,;
::nBottom - ::nTop + 1, nStyle ) // 55 )
// 55 is nOr( SWP_NOSIZE, SWP_NOMOVE, SWP_NOZORDER,;
// SWP_NOACTIVATE, SWP_FRAMECHANGED )
return nilFile: source/classes/window.prg (L3903-3931)
METHOD GetSetGWLStyle( lExtended, nStyle, lOnOff ) CLASS TWindow
local nGwl := If( lExtended, GWL_EXSTYLE, GWL_STYLE )
local nSet, uRet
nSet := If( Empty( ::hWnd ), If( lExtended, ::nExStyle, ::nStyle ), GetWindowLong( ::hWnd, nGwl ) )
uRet := nSet
if ValType( nStyle ) == 'N'
uRet := lAnd( nSet, nStyle )
if ValType( lOnOff ) == 'L'
if Empty( ::hWnd )
nSet := If( lOnOff, nOr( nSet, nStyle ), nAnd( nSet, nNot( nStyle ) ) )
if lExtended
::nExStyle := nSet
else
::nStyle := nSet
endif
else
if uRet .and. !lOnOff
SetWindowLong( ::hWnd, nGwl, nAnd( nSet, nNot( nStyle ) ) )
elseif ! uRet .and. lOnOff
SetWindowLong( ::hWnd, nGwl, nOr( nSet, nStyle ) )
endif
endif
endif
endif
return uRetFile: source/classes/btnbmp.prg (L906-906)
nOr( SWP_NOMOVE, SWP_NOSIZE, SWP_FRAMECHANGED ), 1 )File: source/classes/dialog.prg (L945-951)
if lAnd( ::nStyle, WS_VSCROLL )
DEFINE SCROLLBAR ::oVScroll VERTICAL OF Self
endif
if lAnd( ::nStyle, WS_HSCROLL )
DEFINE SCROLLBAR ::oHScroll HORIZONTAL OF Self
endifFile: source/classes/tfoldex.prg (L371-385)
for n = 1 to nLen
DEFINE DIALOG oDlg OF Self STYLE nOR( WS_CHILD, If( ! ::oWnd:IsKindOf( "TDIALOG"), WS_CLIPCHILDREN, 0 ) );
FROM 0, 1 TO ::nHeight(), ::nWidth() PIXEL ;
FONT ::ownd:oFont ;
HELPID If( Len( ::aHelps ) >= n , ::aHelps[ n ] , NIL )
oDlg:SetBrush( ::oBrush )
::aDialogs[ n ] = oDlg
oDlg:cVarName := "Page" + AllTrim( Str( n ) )
oDlg:Hide()
// oDlg:lTransparent := .T.
nextFile: source/classes/tfoldex.prg (L841-846)
if oDlg:hWnd == NIL
ACTIVATE DIALOG oDlg NOWAIT VALID ( Self, .f. );
ON INIT ::Move( aMove[ 1 ], aMove[ 2 ] )
endif
oDlg:SetSize( aMove[ 3 ], aMove[ 4 ] + 2 )
oDlg:Hide()File: source/classes/tfoldex.prg (L1029-1041)
METHOD Initiate( hDlg ) CLASS TFolderEx
LOCAL uValue := ::Super:Initiate( hDlg )
LOCAL nStyle := nOR( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_CLIPCHILDREN )
//force style
SetWindowLong( ::hWnd, -16, nStyle )
::UpdateRegion()
::Default()
RETURN uValueFile: samples/misc/don.prg (L40-60)
for i := 1 to len( ofolder:adialogs )
DEFINE DIALOG ODIALOG OF OFOLDER ;
STYLE NOR( WS_VISIBLE, WS_DLGFRAME, WS_CHILD, WS_VSCROLL, WS_HSCROLL)
if i = 1
@ 1, 1 BUTTON "&Hello" OF odialog ;
ACTION MsgInfo( "Hello world! from page 1")
elseif i = 2
@ 2, 2 BUTTON "&Hello" OF odialog ;
ACTION MsgInfo( "Hello world! from page 2")
elseif i = 3
@ 3, 3 BUTTON "&Hello" OF odialog ;
ACTION MsgInfo( "Hello world! from page 3")
endif
ofolder:adialogs[ i ] := odialog
next
return ofolderFile: samples/misc/don.prg (L79-114)
function SetScrollBarsValues( ofolder )
local i, ovscroll, OHSCROLL
for i := 1 to len( ofolder:adialogs )
OVSCROLL := oFolder:aDialogs[ i ]:OVSCROLL
OVSCROLL:SETRANGE( 1, 100 )
OVSCROLL:bPAGEDOWN = { | | msgstop( 'page down' ) }
OVSCROLL:bGoDOWN = { | | msgstop( 'go down' ) }
OVSCROLL:bPAGEUP = { | | msgstop( 'page up ' ) }
OVSCROLL:bGoUP = { | | msgstop( 'go up ' ) }
// THUMBPOSITION
OVSCROLL:bPOS = { | NPOS | msgstop( 'bpos block') }
OVSCROLL:bTRACK = { | NPOS | msgstop( 'btack block' ) }
OHSCROLL := oFolder:aDialogs[ i ]:OHSCROLL
OHSCROLL:SETRANGE( 1, 100 )
OHSCROLL:bPAGEDOWN = { | | msgstop( 'page RITE' ) }
OHSCROLL:bGoDOWN = { | | msgstop( 'go RITE' ) }
OHSCROLL:bPAGEUP = { | | msgstop( 'page LEFT' ) }
OHSCROLL:bGoUP = { | | msgstop( 'go LEFT ' ) }
// THUMBPOSITION
OHSCROLL:bPOS = { | NPOS | msgstop( 'bpos block') }
OHSCROLL:bTRACK = { | NPOS | msgstop( 'btack block' ) }
OHSCROLL:LUPDATE := .T.
next
return ofolderThank you, Antonio! I'll try. :shock:
Here is a complete walkthrough of how the pattern works, backed entirely by the actual source code.
sequenceDiagram
"Main()" ->> "build_pages()": "creates FOLDER, calls build_pages(oFld)"
"build_pages()" ->> "DEFINE DIALOG": "per tab: STYLE NOR(WS_CHILD, WS_VSCROLL, ...)"
"Main()" ->> "ACTIVATE DIALOG": "ON INIT SetScrollBarsValues(oFld)"
"ACTIVATE DIALOG" ->> "TDialog:Initiate()": "detects WS_VSCROLL in nStyle"
"TDialog:Initiate()" ->> "TScrollBar:WinNew()": "auto-creates ::oVScroll on each page dialog"
"SetScrollBarsValues()" ->> "oVScroll:SetRange()": "SetRange(1, 100)"
"SetScrollBarsValues()" ->> "oVScroll callbacks": "bGoDown, bGoUp, bPageDown, bPageUp, bPos, bTrack"The outer
Inside
Inside
After activation (in
Style must be set before
The
File: samples/misc/don.prg (L7-31)
function Main()
local oDlg, oFld
ALTD(1)
ALTD( )
DEFINE DIALOG oDlg TITLE "FiveWin Dynamic folders" ;
FROM 5, 5 TO 30, 80
ODLG:NSTYLE := nOR( DS_MODALFRAME, ;
WS_MINIMIZEBOX , ;
WS_VISIBLE, WS_CAPTION, ;
WS_SYSMENU, WS_THICKFRAME, WS_MAXIMIZEBOX )
@ 0.5, 1 FOLDER oFld PROMPT "&xBase", "&And OOP", "&Power" ;
OF oDlg SIZE 160, 90
ofld := build_pages( ofld )
ODLG:BRESIZED := {| | FOLDRESIZE( ODLG ) }
ACTIVATE DIALOG oDlg CENTERED ;
ON INIT SetScrollBarsValues( oFld )File: samples/misc/don.prg (L37-60)
function build_pages( ofolder )
local odialog, i
for i := 1 to len( ofolder:adialogs )
DEFINE DIALOG ODIALOG OF OFOLDER ;
STYLE NOR( WS_VISIBLE, WS_DLGFRAME, WS_CHILD, WS_VSCROLL, WS_HSCROLL)
if i = 1
@ 1, 1 BUTTON "&Hello" OF odialog ;
ACTION MsgInfo( "Hello world! from page 1")
elseif i = 2
@ 2, 2 BUTTON "&Hello" OF odialog ;
ACTION MsgInfo( "Hello world! from page 2")
elseif i = 3
@ 3, 3 BUTTON "&Hello" OF odialog ;
ACTION MsgInfo( "Hello world! from page 3")
endif
ofolder:adialogs[ i ] := odialog
next
return ofolderFile: samples/misc/don.prg (L79-114)
function SetScrollBarsValues( ofolder )
local i, ovscroll, OHSCROLL
for i := 1 to len( ofolder:adialogs )
OVSCROLL := oFolder:aDialogs[ i ]:OVSCROLL
OVSCROLL:SETRANGE( 1, 100 )
OVSCROLL:bPAGEDOWN = { | | msgstop( 'page down' ) }
OVSCROLL:bGoDOWN = { | | msgstop( 'go down' ) }
OVSCROLL:bPAGEUP = { | | msgstop( 'page up ' ) }
OVSCROLL:bGoUP = { | | msgstop( 'go up ' ) }
// THUMBPOSITION
OVSCROLL:bPOS = { | NPOS | msgstop( 'bpos block') }
OVSCROLL:bTRACK = { | NPOS | msgstop( 'btack block' ) }
OHSCROLL := oFolder:aDialogs[ i ]:OHSCROLL
OHSCROLL:SETRANGE( 1, 100 )
OHSCROLL:bPAGEDOWN = { | | msgstop( 'page RITE' ) }
OHSCROLL:bGoDOWN = { | | msgstop( 'go RITE' ) }
OHSCROLL:bPAGEUP = { | | msgstop( 'page LEFT' ) }
OHSCROLL:bGoUP = { | | msgstop( 'go LEFT ' ) }
// THUMBPOSITION
OHSCROLL:bPOS = { | NPOS | msgstop( 'bpos block') }
OHSCROLL:bTRACK = { | NPOS | msgstop( 'btack block' ) }
OHSCROLL:LUPDATE := .T.
next
return ofolderFile: source/classes/dialog.prg (L945-968)
if lAnd( ::nStyle, WS_VSCROLL )
DEFINE SCROLLBAR ::oVScroll VERTICAL OF Self
endif
if lAnd( ::nStyle, WS_HSCROLL )
DEFINE SCROLLBAR ::oHScroll HORIZONTAL OF Self
endif
if ::oIcon != nil
::SendMsg( WM_SETICON, 0, ::oIcon:hIcon )
endif
::SetAlphaLevel()
if ::oBar != nil // added 2016-04-06. It is not necessary to call
::oBar:Adjust() // oDlg:Resize() in ON INIT clause
endif
if ::bInit != nil
lResult = Eval( ::bInit, Self )
if ValType( lResult ) == "L" .and. ! lResult
lFocus = .f.
endif
endifFile: source/classes/scrllbar.prg (L15-99)
CLASS TScrollBar FROM TControl
DATA lVertical, lReDraw, lIsChild, nMin, nMax, nPgStep
DATA bGoUp, bGoDown, bGoTop, bGoBottom, bPageUp, bPageDown, bPos
DATA bTrack
CLASSDATA aProperties INIT { "cVarName", "nMin", "nMax",;
"nPgStep", "nTop", "nLeft", "nWidth", "nHeight",;
"Cargo", "nOrientation" }
METHOD New( nRow, nCol, nMin, nMax, nPgStep, lVertical, oWnd, nWidth, nHeight,;
bUpAct, bDownAct, bPgUp, bPgDown, bPos, lPixel, nClrText,;
nClrBack, cMsg, lUpdate, bWhen, bValid, lDesign ) CONSTRUCTOR
METHOD WinNew( nMin, nMax, nPgStep, lVertical, oWnd, bUpAction,;
bDownAction, bPgUp, bPgDown, bPos, nClrText, nClrBack,;
lUpdate, bWhen, bValid ) CONSTRUCTOR
METHOD ReDefine( nID, nMin, nMax, nPgStep, oWnd, bUpAction, bDownAction, ;
bPgUp, bPgDown, bPos, nClrText, nClrBack, cMsg,;
lUpdate, bWhen, bValid ) CONSTRUCTOR
METHOD cToChar() INLINE ::Super:cToChar( "SCROLLBAR" )
METHOD GetPos() INLINE GetScrollPos( If( ::lIsChild, ::oWnd:hWnd, ::hWnd ),;
If( ::lIsChild, If( ::lVertical, SB_VERT, SB_HORZ ), SB_CTL ) )
METHOD GetRange() INLINE GetScrollRange( If( ::lIsChild, ::oWnd:hWnd, ::hWnd ),;
If( ::lIsChild, If( ::lVertical, SB_VERT, SB_HORZ ), SB_CTL ) )
METHOD HandleEvent( nMsg, nWParam, nLParam )
METHOD Initiate( hDlg ) INLINE ::Super:Initiate( hDlg ), ;
::SetRange( ::nMin, ::nMax ),;
::SetPos( ::nMin )
// These two have to be BLOCK
METHOD GoUp() BLOCK { | Self, nPos | nPos := ::GetPos(),;
if( nPos > ::nMin,;
::SetPos( --nPos ), ),;
If( ::bGoUp != nil, Eval( ::bGoUp ),) }
METHOD GoDown() BLOCK { | Self, nPos | nPos := ::GetPos(),;
if( nPos < ::nMax,;
::SetPos( ++nPos ), ),;
If( ::bGoDown != nil, Eval( ::bGoDown ),) }
METHOD GoTop() INLINE ::SetPos( ::nMin ),;
If( ::bGoTop != nil, Eval( ::bGoTop ),)
METHOD GoBottom() INLINE ::SetPos( ::nMax ),;
If( ::bGoBottom != nil, Eval( ::bGoBottom ),)
METHOD PageUp() INLINE ::SetPos( ::GetPos() - ::nPgStep ),;
If( ::bPageUp != nil, Eval( ::bPageUp ),)
METHOD PageDown() INLINE ::SetPos( ::GetPos() + ::nPgStep ),;
If( ::bPageDown != nil, Eval( ::bPageDown ),)
METHOD SetPage( nSize, lReDraw )
METHOD SetPos( nPos ) INLINE ;
SetScrollPos( if( ::lIsChild, ::oWnd:hWnd, ::hWnd ),;
If( ::lIsChild, If( ::lVertical, SB_VERT, SB_HORZ ), SB_CTL ),;
nPos, ::lReDraw )
METHOD SetRange( nMin, nMax ) INLINE ;
::nMin := nMin, ::nMax := nMax, ;
SetScrollRange( if( ::lIsChild, ::oWnd:hWnd, ::hWnd ), ;
if( ::lIsChild, If( ::lVertical, SB_VERT, SB_HORZ ), SB_CTL ), ;
nMin, nMax, ::lReDraw )
METHOD ThumbPos( nPos ) INLINE If( ::bPos != nil, Eval( ::bPos, nPos ),)
METHOD MouseMove( nRow, nCol, nKeyFlags )
METHOD ThumbTrack( nPos ) INLINE If( ::bTrack != nil, Eval( ::bTrack, nPos ),)
METHOD nOrientation() INLINE If( ::lVertical, 1, 2 )
METHOD _nOrientation( n )
ENDCLASSFile: source/classes/scrllbar.prg (L171-200)
METHOD WinNew( nMin, nMax, nPgStep, lVertical, oWnd, bUpAction,;
bDownAction, bPgUp, bPgDown, bPos, nClrText, nClrBack,;
lUpdate, bWhen, bValid ) CLASS TScrollBar
DEFAULT nMin := 1, nMax := 2, nPgStep := 1, lVertical := .t.,;
nClrText := GetSysColor( COLOR_WINDOW ),;
nClrBack := GetSysColor( COLOR_SCROLLBAR ),;
lUpdate := .f.
::oWnd = oWnd
::lVertical = lVertical
::lReDraw = .t.
::lIsChild = .t.
::nMin = nMin
::nMax = nMax
::nPgStep = nPgStep
::bGoUp = bUpAction
::bGoDown = bDownAction
::bPageUp = bPgUp
::bPageDown = bPgDown
::bPos = bPos
::lUpdate = lUpdate
::bWhen = bWhen
::bValid = bValid
::hWnd = 0
::SetRange( nMin, nMax )
::SetPos( nMin )
return SelfFile: source/classes/tfoldex.prg (L37-41)
CLASS TFolderEx FROM TControl
CLASSDATA lRegistered AS LOGICAL
DATA aDialogsFile: source/classes/tfoldex.prg (L264-385)
::aDialogs = {}
::aEnable = {}
::aPos = {}
::aVisible = {}
::aPrompts = CheckArr( aPrompts )
::aOrder = {}
::aLines = {}
nLen = Len( ::aPrompts )
if aAlign == NIL
aAlign = Array( nLen )
endif
if aHelps == NIL
aHelps = Array( nLen )
endif
if aBitmaps == NIL
aHelps = Array( nLen )
endif
::aVisible = Array( nLen )
::aEnable = Array( nLen )
AFill( ::aVisible, .T. )
AFill( ::aEnable, .T. )
//////////////////////// begin -->> byte-one 2010
#ifdef OLDCODE // upto FWH 14.06 : Modified on 2014-07-25
// verify font by user
if oFont == nil
// verify font by paren
if ::oWnd:oFont == nil
oFont := TFont():New()
oFont:hFont := GetStockObject( DEFAULT_GUI_FONT )
aFontInfo = GetFontInfo( oFont:hFont )
else
aFontInfo := GetFontInfo( ::oWnd:oFont:hFont )
endif
else
aFontInfo := GetFontInfo( oFont:hFont )
endif
IF ::nLayOut == LAYOUT_RIGHT .OR. ::nLayOut == LAYOUT_LEFT
if hb_isObject( oFont ) // oFont is external and user provided
oFont:end() // This font should not :End() here 2014-07-25
endif
DEFINE FONT oFont NAME aFontInfo[ 4 ] ;
SIZE aFontInfo[ 2 ], aFontInfo[ 1 ] NESCAPEMENT 900 * If( ::nLayOut == LAYOUT_RIGHT, -1, 1 )
ELSE
DEFINE FONT oFont NAME aFontInfo[ 4 ] ;
SIZE aFontInfo[ 2 ], aFontInfo[ 1 ]
ENDIF
::SetFont( oFont )
oFont:End()
#else
if oFont == nil
::GetFont()
else
::SetFont( oFont )
endif
if ::nLayOut == LAYOUT_RIGHT .OR. ::nLayOut == LAYOUT_LEFT
oFont := ::oFont:Escapement( If( ::nLayOut == LAYOUT_RIGHT, 2700, 900 ) )
::SetFont( oFont )
oFont:End()
endif
#endif
// Replaced on 2014-07-25 FWH 14.07
// Old code was prematurely destroying the parameter font in cases of RIGHT & LEFT
// Old code was stripping of attributes like Bold,Italic,etc from the provided font
//
//
if ::lTransparent
if ::oWnd:oBrush != NIL
::SetBrush( ::oWnd:oBrush )
else
::oBrush = TBrush():New( , ::oWnd:nClrPane )
endif
else
::oBrush = TBrush():New( , nClrPane )
endif
::nFolderHeight := max( ::nFolderHeight, ::oFont:nHeight * 1.2 )
//////////////////////////end -->> byte-one 2010
::bClrTabs = bClrTabs
::bClrText = bClrText
::aAlign = CheckArr( aAlign )
::aHelps = CheckArr( aHelps )
::bPopUp = bPopUp
::aDialogs = Array( nLen )
::aBitmaps = {}
::aBrightBmp = {}
::LoadBitmaps( aBitmaps )
DEFAULT cVarName := "oFldEx" + ::GetCtrlIndex()
::cVarName = cVarName
for n = 1 to nLen
DEFINE DIALOG oDlg OF Self STYLE nOR( WS_CHILD, If( ! ::oWnd:IsKindOf( "TDIALOG"), WS_CLIPCHILDREN, 0 ) );
FROM 0, 1 TO ::nHeight(), ::nWidth() PIXEL ;
FONT ::ownd:oFont ;
HELPID If( Len( ::aHelps ) >= n , ::aHelps[ n ] , NIL )
oDlg:SetBrush( ::oBrush )
::aDialogs[ n ] = oDlg
oDlg:cVarName := "Page" + AllTrim( Str( n ) )
oDlg:Hide()
// oDlg:lTransparent := .T.
nextFile: source/classes/tfoldex.prg (L841-859)
if oDlg:hWnd == NIL
ACTIVATE DIALOG oDlg NOWAIT VALID ( Self, .f. );
ON INIT ::Move( aMove[ 1 ], aMove[ 2 ] )
endif
oDlg:SetSize( aMove[ 3 ], aMove[ 4 ] + 2 )
oDlg:Hide()
NEXT
IF Len( ::aDialogs ) > 0
IF ::nOption <= Len( ::aDialogs )
::aDialogs[ ::nOption ]:Show()
ENDIF
ENDIF
::ReSize()
RETURN NIL