Test code, Example.bas
lsxLibrary.inc
Code:
' This example program was written using PBWin9 DDT commands. '----------------------------------------------------------------------------(') #COMPILE EXE "Example.exe" #DIM ALL '----------------------------------------------------------------------------(') %USEMACROS = 1 '----------------------------------------------------------------------------(') #IF NOT %DEF( %WINAPI ) #INCLUDE "WIN32API.INC" #ENDIF #IF NOT %DEF( %COMMCTRL_INC ) #INCLUDE "COMMCTRL.INC" #ENDIF #INCLUDE "lsxLibrary.inc" ' Include the lsx library somewhere after win32api.inc" '----------------------------------------------------------------------------(') %btnButton1 = 1001 %btnButton2 = 1002 %btnButton3 = 1003 %cbxCombobox = 1004 %dlgExample = 1005 %edtEditBox1 = 1006 %edtEditBox2 = 1007 %lblComboBox = 1008 %lblEditBox1 = 1009 %stbStatusbar = 1010 %tvwTreeview = 1011 '----------------------------------------------------------------------------(') FUNCTION PBMAIN( ) INITCOMMONCONTROLS CreateExampleDialog %HWND_DESKTOP END FUNCTION '----------------------------------------------------------------------------(') CALLBACK FUNCTION ExampleDialogCallback( ) SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG ' Fill in some sample data SampleComboBox CB.HNDL, %cbxCombobox, 30 SampleTreeView CB.HNDL, %tvwTreeview, 5 ' Register the controls you want to manage lsxEngine CB.HNDL, %lblComboBox, %lsxRegister lsxEngine CB.HNDL, %cbxCombobox, %lsxRegister lsxEngine CB.HNDL, %tvwTreeview, %lsxRegister lsxEngine CB.HNDL, %edtEditBox2, %lsxRegister lsxEngine CB.HNDL, %btnButton1, %lsxRegister lsxEngine CB.HNDL, %btnButton2, %lsxRegister lsxEngine CB.HNDL, %btnButton3, %lsxRegister CASE %WM_SIZE CONTROL SEND CBHNDL, %stbStatusbar, CBMSG, CBWPARAM, CBLPARAM ' Tell the engine how you want the controls to react lsxEngine CB.HNDL, %lblComboBox, %lsxCalcX lsxEngine CB.HNDL, %cbxCombobox, %lsxCalcX lsxEngine CB.HNDL, %tvwTreeview, %lsxCalcW OR %lsxCalcH lsxEngine CB.HNDL, %edtEditBox2, %lsxCalcY OR %lsxCalcW lsxEngine CB.HNDL, %btnButton1, %lsxCalcX OR %lsxCalcY lsxEngine CB.HNDL, %btnButton2, %lsxCalcX OR %lsxCalcY lsxEngine CB.HNDL, %btnButton3, %lsxCalcX OR %lsxCalcY CASE %WM_GETMINMAXINFO ' This is here just so the dialog deosn't shrink TOO small LOCAL udtMinMaxInfo AS MINMAXINFO PTR LOCAL lngResult AS LONG lngResult = DEFWINDOWPROC( CB.HNDL, CB.MSG, CB.WPARAM, CB.LPARAM ) udtMinMaxInfo = CB.LPARAM @udtMinMaxInfo.ptMinTrackSize.x = 500 @udtMinMaxInfo.ptMinTrackSize.y = 350 FUNCTION = 0 CASE %WM_NCACTIVATE STATIC hWndSaveFocus AS DWORD IF ISFALSE CBWPARAM THEN hWndSaveFocus = GETFOCUS( ) ELSEIF hWndSaveFocus THEN SETFOCUS( hWndSaveFocus ) hWndSaveFocus = 0 END IF END SELECT END FUNCTION '----------------------------------------------------------------------------(') FUNCTION SampleComboBox( BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _ AS LONG ) AS LONG LOCAL i AS LONG CONTROL SEND hDlg, lID, %CB_SETEXTENDEDUI, %TRUE, 0 FOR i = 1 TO lCount COMBOBOX ADD hDlg, lID, USING$( "Test Item #", i ) NEXT i END FUNCTION '----------------------------------------------------------------------------(') FUNCTION SampleTreeView( BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _ AS LONG ) AS LONG LOCAL i AS LONG LOCAL j AS LONG LOCAL k AS LONG LOCAL hRoot AS DWORD LOCAL hParent AS DWORD LOCAL hChild AS DWORD FOR i = 1 TO lCount TREEVIEW INSERT ITEM hDlg, lID, %TVI_ROOT, %TVI_LAST, 0, 0, USING$( "Root#", i ) TO hRoot FOR j = 1 TO lCount TREEVIEW INSERT ITEM hDlg, lID, hRoot, %TVI_LAST, 0, 0, USING$( "Item#", j ) TO hParent FOR k = 1 TO lCount TREEVIEW INSERT ITEM hDlg, lID, hParent, %TVI_LAST, 0, 0, USING$( "SubItem#", k ) TO hChild NEXT k NEXT j NEXT i END FUNCTION '----------------------------------------------------------------------------(') FUNCTION CreateExampleDialog( BYVAL hParent AS DWORD ) AS LONG LOCAL lngResult AS LONG LOCAL hDlg AS DWORD DIALOG NEW hParent, "Example DDT Dialog", 157, 83, 376, 300, %WS_POPUP OR _ %WS_BORDER OR %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_SYSMENU OR _ %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR _ %WS_VISIBLE OR %DS_MODALFRAME OR %DS_CENTER OR %DS_3DLOOK OR _ %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CLIENTEDGE OR _ %WS_EX_WINDOWEDGE OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD LABEL, hDlg, %lblEditBox1, "Edit Box 1", 7, 7, 42, 13, _ %WS_CHILD OR %WS_VISIBLE OR %SS_LEFT OR %SS_CENTERIMAGE, %WS_EX_LEFT _ OR %WS_EX_LTRREADING CONTROL ADD TEXTBOX, hDlg, %edtEditBox1, "I don't move", 49, 7, 114, 13 CONTROL ADD LABEL, hDlg, %lblComboBox, "Combobox", 224, 7, 42, 13, _ %WS_CHILD OR %WS_VISIBLE OR %SS_LEFT OR %SS_CENTERIMAGE, %WS_EX_LEFT _ OR %WS_EX_LTRREADING CONTROL ADD COMBOBOX, hDlg, %cbxCombobox,, 266, 7, 105, 77, %WS_CHILD OR _ %WS_VISIBLE OR %WS_TABSTOP OR %CBS_DROPDOWNLIST OR %CBS_SORT, _ %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR CONTROL ADD TREEVIEW, hDlg, %tvwTreeview, "", 7, 28, 364, 182, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %TVS_HASBUTTONS OR _ %TVS_HASLINES OR %TVS_LINESATROOT OR %TVS_SHOWSELALWAYS OR _ %TVS_CHECKBOXES, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR CONTROL ADD TEXTBOX, hDlg, %edtEditBox2, "Edit box 2 ( in read only " + _ "mode)", 7, 217, 280, 63, %WS_CHILD OR %WS_VISIBLE OR %ES_LEFT OR _ %ES_MULTILINE OR %ES_READONLY, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR CONTROL ADD BUTTON, hDlg, %btnButton1, "Button1", 294, 217, 35, 28 CONTROL ADD BUTTON, hDlg, %btnButton2, "Button2", 336, 217, 35, 28 CONTROL ADD BUTTON, hDlg, %btnButton3, "Button 3", 294, 252, 77, 28 CONTROL ADD STATUSBAR, hDlg, %stbStatusbar, "", 0, 287, 375, _ 13, %WS_CHILD OR %WS_VISIBLE, %WS_EX_TRANSPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR DIALOG SHOW MODAL hDlg, CALL ExampleDialogCallback TO lngResult FUNCTION = lngResult END FUNCTION
Code:
'======================================================================' ' "LSX Engine" (Location Size eXchanger) ' ' ' ' An include library written in PB9 to easily relocate or resize ' ' DDT controls when a dialog is resized. ' ' ' ' Written by: George W. Bleck ' ' Revision: 1.0 ' ' Date: 2009/04/26 ' '======================================================================' ' To use the engine, you must first pre-register each control you wish ' ' to update later. Registration is easy and would typically be done ' ' in your dialog's WM_INITIALIZE. ' ' ' ' Here is an example of a registration: ' ' ' ' lsxEngine {Dialog Handle}, {Control ID}, %lsxRegister ' ' ' ' If you manually relocate or resize a control and want to manage the ' ' new parameters it has, just register the control again. It will ' ' update the database with the new information. Be aware this command ' ' cannot be combined with other commands. ' '======================================================================' ' To have that control Relocate/Resize properly in your dialog you ' ' just need to call the engine again under you dialog's WM_SIZE event. ' ' ' ' For example, if you wanted the control to move horizontally as the ' ' dialog widened just put the following under WM_SIZE: ' ' ' ' lsxEngine {Dialog Handle}, {Control ID}, %lsxCalcX ' ' ' ' Note the example did not specify anything about the control's width ' ' or about it's Y position or height. The engine only changes the ' ' constraints you tell it to. All other constraints are left as is. ' ' ' ' This leads us to combined commands. You can combine commands using ' ' the OR operator to have cumulative effects. Another example is in ' ' order. If you wanted a control to widen as your dialog is widened ' ' but it should slide down as the dialog height is stretched, just do ' ' the following in your WM_SIZE for that control: ' ' ' ' lsxEngine {Dialog Handle}, {Control ID}, %lsxCalcY OR %lsxCalcW ' ' ' ' It's that simple! Just create a WM_SIZE entry for each control ' ' detailing how you want it to act when the dialog size is changed. ' '======================================================================' ' There is also a command to ERASE the entire control database in the ' ' event you want to rebuild the database. An example of this would be ' ' If you destroy and recreate all your dialogs. Also be aware that ' ' This command cannot be combined with other commands. ' '======================================================================' ' Lastly, given the simplicity of the mechanisms you can create some ' ' interesting effects by combining seemingly opposite commands. ' ' Combining the %lsxCalcX command with the %lsxCalcW command would ' ' cause a control to get wider and move to the right as a dialog is ' ' stretched wider. ' ' Not quite sure of a viable use but HEY you never know! ' '======================================================================' '----------------------------------------------------------------------------(') ' Custom constants %lsxRegister = &B000001 ' Registers a control in the control database %lsxCalcX = &B000010 ' Causes a control to move horizontally as a dialog's width is changed %lsxCalcY = &B000100 ' Causes a control to move vertically as a dialog's height is changed %lsxCalcW = &B001000 ' Causes a control to get wider/narrower as a dialog's width is changed %lsxCalcH = &B010000 ' Causes a control to get taller/shorter as a dialog's height is changed %lsxReset = &B100000 ' ERASES the entire control database '----------------------------------------------------------------------------(') ' Custom data type declaration TYPE lsxDataType hDlg AS DWORD lngControlID AS LONG lngX AS LONG lngY AS LONG lngW AS LONG lngH AS LONG lngCalcX AS LONG lngCalcW AS LONG lngCalcY AS LONG lngCalcH AS LONG END TYPE '----------------------------------------------------------------------------(') ' Internally used function, determines if a control is already in the database and returns it's array index FUNCTION lsxGetDBIndex( BYVAL hDlg AS DWORD, BYVAL lngControlID AS LONG, udtControlInfo( ) AS lsxDataType, BYVAL lngControlCount AS LONG ) AS DWORD LOCAL lngControlIndex AS LONG FOR lngControlIndex = 1 TO lngControlCount IF udtControlInfo( lngControlIndex ).hDlg = hDlg AND udtControlInfo( lngControlIndex ).lngControlID = lngControlID THEN FUNCTION = lngControlIndex EXIT FUNCTION END IF NEXT lngControlIndex END FUNCTION '----------------------------------------------------------------------------(') SUB lsxEngine( BYVAL hDlg AS DWORD, BYVAL lngControlID AS LONG, BYVAL dwdCommand AS DWORD ) DIM udtControlInfo( 0 ) AS STATIC lsxDataType STATIC lngControlCount AS LONG LOCAL udtNewControlInfo AS lsxDataType LOCAL lngDlgW AS LONG LOCAL lngDlgH AS LONG LOCAL lngSearchIndex AS LONG DIALOG GET CLIENT hDlg TO lngDlgW, lngDlgH ' Record the control's existing information IF (dwdCommand AND %lsxRegister) = %lsxRegister THEN lngSearchIndex = lsxGetDBIndex( hDlg, lngControlID, udtControlInfo( ), lngControlCount ) IF lngSearchIndex = 0 THEN INCR lngControlCount REDIM PRESERVE udtControlInfo( lngControlCount ) lngSearchIndex = lngControlCount END IF ' Record the dialog handle and control id udtControlInfo( lngSearchIndex ).hDlg = hDlg udtControlInfo( lngSearchIndex ).lngControlID = lngControlID ' Get the controls initial loc and size information CONTROL GET LOC hDlg, lngControlID TO udtControlInfo( lngSearchIndex ).lngX, udtControlInfo( lngSearchIndex ).lngY CONTROL GET SIZE hDlg, lngControlID TO udtControlInfo( lngSearchIndex ).lngW, udtControlInfo( lngSearchIndex ).lngH ' Precalculate the offsets that are used later to make life easier/faster udtControlInfo( lngSearchIndex ).lngCalcX = lngDlgW - udtControlInfo( lngSearchIndex ).lngX udtControlInfo( lngSearchIndex ).lngCalcW = lngDlgW - udtControlInfo( lngSearchIndex ).lngW udtControlInfo( lngSearchIndex ).lngCalcY = lngDlgH - udtControlInfo( lngSearchIndex ).lngY udtControlInfo( lngSearchIndex ).lngCalcH = lngDlgH - udtControlInfo( lngSearchIndex ).lngH EXIT SUB END IF ' Reset the database and control count, deletes all existing control info IF (dwdCommand AND %lsxReset) = %lsxReset THEN ERASE udtControlInfo( ) lngControlCount = 0 EXIT SUB END IF ' If we got this far client wants us to actually do calculate a controls Loc and or Size' ' ' ' Be aware this is GIGO, so a combo like "%lsxCalcX OR %lsxCalcW" can be passed. ' ' ' ' In the above example, if you widened a dialog it would cause the control to not ' ' only move to the right, but widen as well! Probably not an expected result. ' ' But hey, you never know what someone might want right??? ' lngSearchIndex = lsxGetDBIndex( hDlg, lngControlID, udtControlInfo( ), lngControlCount ) IF lngSearchIndex THEN udtNewControlInfo = udtControlInfo( lngSearchIndex ) IF ( dwdCommand AND %lsxCalcX ) = %lsxCalcX THEN udtNewControlInfo.lngX = lngDlgW - udtNewControlInfo.lngCalcX END IF IF ( dwdCommand AND %lsxCalcY ) = %lsxCalcY THEN udtNewControlInfo.lngY = lngDlgH - udtNewControlInfo.lngCalcY END IF IF ( dwdCommand AND %lsxCalcW ) = %lsxCalcW THEN udtNewControlInfo.lngW = lngDlgW - udtNewControlInfo.lngCalcW END IF IF ( dwdCommand AND %lsxCalcH ) = %lsxCalcH THEN udtNewControlInfo.lngH = lngDlgH - udtNewControlInfo.lngCalcH END IF CONTROL SET LOC hDlg, lngControlID, udtNewControlInfo.lngX, udtNewControlInfo.lngY CONTROL SET SIZE hDlg, lngControlID, udtNewControlInfo.lngW, udtNewControlInfo.lngH CONTROL REDRAW hDlg, lngControlID EXIT SUB END IF END SUB
Comment