Hi,
let me show what i did with the resizing problem. Hope you find it simple enough and a good starting point.
I needed to resize controls as the container dialog also resizes, and the usual solution (oClient, oTop, etc) didn't seem to be right.
First thing first. After thinking a little bit about what behavoir would be wanted in every control, it can be resumed in 3 types:
1: No Change: the control's coordinates are hooked or anchored to the top/left window/dialog coordinates, so no change is made when windows is resized (e.g. left toolbar)
2: Proportional: used mostly with graphic controls, every control coordinate is changed proportionally to the dialog size.
3: Anchored: one ore more control's coordinates are hooked to the bottom/right edges, so control's size and/or position are changed acording to the new dialog size (this is the kind of behavoir Rick is looking for, i think).
To achieve this, we need to know:
a) Window/Dialog and controls original sizes, as they where defined
b) For every control, what behavoir is desired,
and then activate our new resizing strategy on windows/dlg resize, usually using bResize Twindows's DATA
Let's the code speak by itself.
#define GW_CHILD 5
#define GW_HWNDNEXT 2
FUNCTION PreResize( oDlg )
LOCAL hWnd:= oDlg:hWnd
LOCAL aSize, aChildren, aSizeWnd
LOCAL hCtrl
IF !Empty( hWnd )
aSizeWnd:= GetClientRect( hWnd )
aSize:= GetWndRect( hWnd )
aChildren:= {}
hCtrl := GetWindow( hWnd, GW_CHILD )
While hCtrl != 0
aSize:= GetWndRect( hCtrl )
aSize[3]-= aSize[1]
aSize[4]-= aSize[2]
ScreenToClient( hWnd, ASize )
AAdd( aChildren, { hCtrl, aSize } )
hCtrl = GetWindow( hCtrl, GW_HWNDNEXT )
END
// We need to store this somewhere, if you feel you have a better place just say it, you sugestions are welcome
oDlg:Cargo:= { aSizeWnd, aChildren }
// This could be another option... We use this function to setup the min/Max info...
oDlg:aMinMaxInfo = { GetSysMetrics(0), GetSysMetrics(1),; // xMaxSize, yMaxSize
0, 0 /*GetSysMetrics(0), GetSysMetrics(1) */ ,; // xMaxPosition, yMaxPosition
oDlg:nWidth, oDlg:nHeight,; // xMinTrackSize, yMinTrackSize
GetSysMetrics(0), GetSysMetrics(1), ; // xMaxTrackSize, yMaxTrackSize
aSizeWnd, aChildren }
ENDIF
RETURN NIL
// this is the function that does the real work
FUNCTION DlgResizeCtrl( oDlg, nWidth, nHeight, nSizeType )
LOCAL hWnd, oCtrl, nPos
LOCAL aSize, aChildren, aSizeWnd, aCargo
LOCAL hCtrl, aCtrl
LOCAL nTop, nLeft, nOrigWidth, nOrigHeight, nBottom, nRight
LOCAL nStyle, nKV, nKH // keep, Proporcional, bound to bottom,
IF ValType(oDlg:Cargo) == 'A'
nTop:= oDlg:Cargo[1][1]
nLeft:= oDlg:Cargo[1][2]
nOrigHeight := oDlg:Cargo[1][3] - nTop
nOrigWidth := oDlg:Cargo[1][4] - nLeft
aSizeWnd:= GetClientRect( oDlg:hWnd )
nHeight:= aSizeWnd[3]
nWidth := aSizeWnd[4]
nKH:= nWidth / nOrigWidth
nKV:= nHeight / nOrigHeight
nDH:= nWidth - nOrigWidth
nDV:= nHeight - nOrigHeight
aChildren:= oDlg:Cargo[2]
FOR EACH aCtrl IN aChildren
IF ( nPos:= GetProp( aCtrl[1], "RSZ" ) ) != 0
nStyle:= nPos % 256
nPos:= Int( nPos / 256 )
nTop := (nPos % 16) >= 8
nLeft := (nPos % 8) >= 4
nBottom := (nPos % 4) >= 2
nRight := (nPos % 2) == 1
Do Case
Case nStyle == 0 // keep, do nothing
// SetWindowPos( aCtrl[1], 0, aCtrl[2][1], aCtrl[2][2], aCtrl[2][4], aCtrl[2][3], 4 )
Case nStyle == 1 // Proportional
SetWindowPos( aCtrl[1], 0, Int( aCtrl[2][1] * nKV ), Int( aCtrl[2][2] * nKH ), Int( aCtrl[2][4] * nKH ), Int( aCtrl[2][3] * nKV ), 4 )
Case nStyle == 2 // Anchors
SetWindowPos( aCtrl[1], 0, ;
If( nTop, aCtrl[2][1]+nDV, aCtrl[2][1] ), ;
If( nLeft, aCtrl[2][2]+nDH, aCtrl[2][2] ), ;
If( nRight, aCtrl[2][4]+nDH, aCtrl[2][4] ), ;
If( nBottom, aCtrl[2][3]+nDV, aCtrl[2][3] ), ;
4 )
EndCase
ENDIF
EndFor
oDlg:Refresh()
ENDIF
RETURN NIL
// USAGE sample
//--------------------------------------------------------------------------
FUNCTION BrowseText( cTextFile, cTitle, bOnKey )
//--------------------------------------------------------------------------
Local oDlg, oBrush, oBrowse, nResult:= 0, oTxt
Local oBtn1, oBtn2, oBtn3, oBtn4
DEFINE DIALOG oDlg RESOURCE "VISUALIZA2" COLORS 0, RGB(147,179,162) TITLE 'Vista Previa'
REDEFINE BROWSE oBrowse ID 110 OF oDlg FONT oFontTexto
oBrowse:nClrFocuBack:= {|nPos| if(nPos%2 = 0,CLR_LIGHTBLUE,CLR_WHITE)}
oBrowse:Setcolor( { 1, 2 }, { CLR_BLACK, {|| If( oBrowse:nLogicPos() % 2 = 0, CLR_NBLUE, CLR_WHITE ) } } )
oTxt:= AtiTxtFile():New( cTextFile, 0 )
oBrowse:lNoLiteBar:= .F.
oBrowse:lDrawHeaders:= .T.
If ValType( bOnKey ) == 'B'
oBrowse:bLDblClick := {|| Eval( bOnKey, oBrowse:oTxtFile:ReadLine() ) }
EndIf
REDEFINE BUTTON oBtn1 ID 172 OF oDlg ACTION ( CopiaTexto( cTextFile ) ) // Fichero
REDEFINE BUTTON oBtn2 ID 123 OF oDlg ACTION ( PrintTexto( cTextFile, .T. ) ) // Imprimir
REDEFINE BUTTON oBtn3 ID 128 OF oDlg ACTION ( nResult:= 0, oDlg:End() ) // Atras
oDlg:bKeyDown := {|nKey| BrowseTextOnKey( nKey, oBrowse, cTextFile, bOnKey ) }
// !IMPORTANT
oDlg:bResized := {|nSizeType, nWidth, nHeight| DlgResizeCtrl( oDlg, nWidth, nHeight, nSizeType ) }
ACTIVATE DIALOG oDlg CENTERED ON INIT ( PreResize( oDlg ), SetProp( oBrowse:hWnd, 'RSZ', 0x302 ), SetProp( oBtn1:hWnd, 'RSZ', 0xf02 ), SetProp( oBtn2:hWnd, 'RSZ', 0xf02 ), SetProp( oBtn3:hWnd, 'RSZ', 0xf02 ) )
Return nResult
Please pay attention to oDlg:bResized and the ACTIOVATE .. ON INIT . There PreResize() is called first, then oBrowse, oBtn1, oBtn2 and oBtn3 are configured to behave in its particular way.
Windows properties are used to store the desired behavoir in every control, using setprop() and getprop(). The name choosen for the property it was 'RSZ', and stores an integer that indicates with 0, 1 or 2 if you want no_change, proportional, or edge anchoring respectively. In the last case, a high order byte indicates which edge every side is anchored to the right and bottom edges.
oBrowse will react having its right and bottom sides anchored to the right and bottom of the dialog, and the three button will have all their coordinates (0xF) bounded to the dialog right-bottom corner.
I hope everyone finds easy to try the code, just including 2 functions and add the necesary changes in the running code so you can try.
Obviously the complexity of setting properties and the weird 'encoding' used in control's setup can be improved and polished a lot, but, well, you know...
