Announcement

Collapse
No announcement yet.

Frame add controls to a group

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • colin glenn
    replied
    I know this is something of an old topic, but thought I'd post something I did to make a group of controls show / hide / move with a single command, and that was I embedded dialogs in the dialog, ...

    Leave a comment:


  • Dale Yarker
    replied
    a frame is like a label with a box, saves you from using a label and 5 lines; thats all.

    Another way to move it and other controls inside, is press and hold left mouse button outside one corner, go to outside diagonally opposite corner and release mouse button. now you can grab all with mouse and drag, or use arrow keys.

    I've only used %WS_GROUP around option/radio buttons. It causes the "only one checked" behavior, and/or allows multiple groups of radio buttons without unfortunate interaction between groups.
    Last edited by Dale Yarker; 1 Oct 2008, 01:20 PM.

    Leave a comment:


  • Richard Angell
    replied
    PBForms 1.51 does not handle the grouping so you can select the frame and move all the controls. You have to re-assign the controls in PBWin so that their parent is the frame control. Subclass the frame control, if memory serves, so you can then handle all the messages for it's children. I posted an example of this some time back in the last several years.

    That said, I have not tried the new and improved DDT for individual control callback, but perhaps it will still be necessary to follow the route suggested above. However this is not going to help you move the controls in the current PBForms.

    If you are looking to handle resize actions, then you just need to re-assign the "child controls" X,y as the frame X.Y plus offset values.

    Leave a comment:


  • Chris Boss
    replied
    Well scratch that idea!

    It appears DDT can't handle the forwarding of notification messages from a child control acting as a parent. It messes up the control callbacks. This means you would have to process the WM_COMMAND yourself, instead of using control callbacks.

    Here is my test code which demonstrates how the control callbacks no longer work:

    Code:
    ' ***************************************************************
    '   This code can be used Royalty Free and Freely Distributed !
    ' ***************************************************************
    #COMPILE EXE
    #REGISTER NONE
    #DIM ALL          '  This is helpful to prevent errors in coding
    
    #INCLUDE "win32api.inc"   ' Must come first before other include files !
    ' *************************************************************
    '                  Constants and Declares (#1)
    ' *************************************************************
    DECLARE SUB LIB_InitColors()
    DECLARE SUB LIB_DeleteBrushes()
     
    %FORM1_FRAME1             = 100
    %FORM1_LABEL1             = 105
    %FORM1_BUTTON1            = 110
    %FORM1_BUTTON2            = 115
    ' --------------------------------------------------
    DECLARE SUB ShowDialog_Form1(BYVAL hParent&)
    DECLARE CALLBACK FUNCTION Form1_DLGPROC
    ' --------------------------------------------------
    ' ------------------------------------------------
    DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON1()
    DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON2()
     
    
    ' *************************************************************
    '               Application Globals Variables (#2)
    ' *************************************************************
    GLOBAL App_Brush&()
    GLOBAL App_Color&()
    GLOBAL hForm1&    ' Dialog handle
     
     
    ' *************************************************************
    '                    Application Entrance
    ' *************************************************************
    FUNCTION PBMAIN
        LOCAL Count&
        LIB_InitColors
        ShowDialog_Form1 0
        DO
            DIALOG DOEVENTS TO Count&
        LOOP UNTIL Count&=0
        LIB_DeleteBrushes
    END FUNCTION
    
    ' *************************************************************
    '                    Application Dialogs (#3)
    ' *************************************************************
    GLOBAL OriginalFrameWinProc AS DWORD
    '
    FUNCTION FrameSubclassProc(BYVAL hWnd&, BYVAL Msg&, BYVAL wParam&, BYVAL lParam&) AS LONG
         SELECT CASE Msg&
              CASE %WM_COMMAND, %WM_NOTIFY, %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT, %WM_CTLCOLORSTATIC, %WM_CTLCOLORSCROLLBAR, %WM_CTLCOLORLISTBOX, %WM_PARENTNOTIFY
                   ' forward messages to parent dialog so DDT can handle it
                   FUNCTION=SendMessage(GetParent(hWnd&), Msg&, wParam&, lParam&)
                   EXIT FUNCTION
              CASE %WM_DESTROY
                   SetWindowLong hWnd&, %GWL_WNDPROC, OriginalFrameWinProc
              CASE ELSE
         END SELECT
         FUNCTION=CallWindowProc(OriginalFrameWinProc, hWnd&, Msg&, wParam&, lParam&)
    END FUNCTION
    FUNCTION MakeFrameContainer(BYVAL hDlg&, BYVAL ID&) AS LONG
         LOCAL hCtrl&
         CONTROL HANDLE hDlg&, ID& TO hCtrl&
         OriginalFrameWinProc=SetWindowLong(hCtrl&, %GWL_WNDPROC, CODEPTR(FrameSubclassProc))
         FUNCTION=hCtrl&
    END FUNCTION
    SUB SetNewParent(BYVAL hDlg&, BYVAL ID&, BYVAL ParentID&)
         LOCAL hCtrl&, hNewParent&
         CONTROL HANDLE hDlg&, ID& TO hCtrl&
         CONTROL HANDLE hDlg&, ParentID& TO hNewParent&
         SetParent hCtrl&, hNewParent&
    END SUB
    SUB ShowDialog_Form1(BYVAL hParent&)
        LOCAL Style&, ExStyle&, hFrame&
        LOCAL N&, CT&        '  Variables used for Reading Data in Arrays for Listbox and Combobox
        '   hParent& = 0 if no parent Dialog
        Style& = %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER
        ExStyle& = 0
        DIALOG NEW hParent&, "Your Dialog", 0, 0,  309,  246, Style&, ExStyle& TO hForm1&
        CONTROL ADD FRAME, hForm1&,  %FORM1_FRAME1,  "Frame  1", 11, 17, 232, 148, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_GROUPBOX, _
            %WS_EX_TRANSPARENT OR %WS_EX_CONTROLPARENT
        hFrame& = MakeFrameContainer(hForm1&,%FORM1_FRAME1)
        ' must create controls on dialog or they won't be right sizeor position
        ' DDT doesn't use dialog units when the parent of CONTROL ADD is not a dialog
        CONTROL ADD LABEL, hForm1&,  %FORM1_LABEL1,  "Frame Clips Label ->", 147, 121, 117, 25, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER OR %WS_BORDER
        CONTROL ADD "Button", hForm1&,  %FORM1_BUTTON1,  "Button  1", 27, 39, 56, 25, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP CALL CBF_FORM1_BUTTON1
        CONTROL ADD "Button", hForm1&,  %FORM1_BUTTON2,  "Button  2", 27, 74, 56, 22, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP CALL CBF_FORM1_BUTTON2
            ' must use SetParent to put the controls on the frame
        SetNewParent hForm1&,%FORM1_LABEL1,%FORM1_FRAME1
        SetNewParent hForm1&,%FORM1_BUTTON1,%FORM1_FRAME1
        SetNewParent hForm1&,%FORM1_BUTTON2,%FORM1_FRAME1
        DIALOG SHOW MODELESS hForm1& , CALL Form1_DLGPROC
    END SUB
    ' *************************************************************
    '                             Dialog Callback Procedure
    '                             for Form Form1
    '                             uses Global Handle - hForm1&
    ' *************************************************************
    CALLBACK FUNCTION Form1_DLGPROC
        SELECT CASE CBMSG
            CASE %WM_HSCROLL
            CASE %WM_VSCROLL
            CASE %WM_CLOSE
            ' -----------------------------------------------
            CASE %WM_CTLCOLORMSGBOX , %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT,_
                 %WM_CTLCOLORSTATIC, %WM_CTLCOLORSCROLLBAR, %WM_CTLCOLORLISTBOX
                ' Control colors
                SELECT CASE GetDlgCtrlID(CBLPARAM)
                    CASE  %FORM1_LABEL1
                        SetTextColor CBWPARAM, App_Color&( 0)
                        SetBkColor   CBWPARAM, App_Color&( 17)
                        FUNCTION=App_Brush&( 17)
                    CASE ELSE
                        FUNCTION=0
                END SELECT
            CASE %WM_COMMAND
                ' Process Messages to Controls that have no Callback Function
                ' and Process Messages to Menu Items
                SELECT CASE CBCTL
                    CASE ELSE
                END SELECT
            CASE ELSE
        END SELECT
    END FUNCTION
    
    ' *******************************************************************
    ' *                         Library Code   *
    ' ********************************************************************
    SUB LIB_InitColors()
        DATA         0,  8388608,    32768,  8421376,      196,  8388736,    16512, 12895428
        DATA   8421504, 16711680,    65280, 16776960,      255, 16711935,    65535, 16777215
        DATA  10790052, 16752768, 10551200, 16777120, 10526975, 16752895, 10551295, 13948116
        DATA  11842740, 16768188, 14483420, 16777180, 14474495, 16768255, 14483455, 15000804
        LOCAL T&, RGBVal&
        REDIM App_Brush&(0 TO 31)
        REDIM App_Color&(0 TO 31)
        FOR T&=0 TO 31
            RGBVal&=VAL(READ$(T&+1))
            App_Brush&(T&)=CreateSolidBrush(RGBVal&)
            App_Color&(T&)=RGBVal&
        NEXT T&
    END SUB
    ' -------------------------------------------------------------
    SUB LIB_DeleteBrushes()
        LOCAL T&
        FOR T&=0 TO 31
            DeleteObject App_Brush&(T&)
        NEXT T&
    END SUB
    ' -------------------------------------------------------------
    ' *************************************************************
    '   Application Callback Functions (or Subs) for Controls (#4)
    ' *************************************************************
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FORM1_BUTTON1
        IF CBCTLMSG=%BN_CLICKED THEN
              MSGBOX "Button 1 Clicked"
        END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FORM1_BUTTON2
        IF CBCTLMSG=%BN_CLICKED THEN
              MSGBOX "Button 2 Clicked"
        END IF
    END FUNCTION
    ' ------------------------------------------------
    
    ' *************************************************************
    '           Other Common Procedures and Functions
    ' *************************************************************

    The work around is to not use control callbacks:

    Code:
    ' ***************************************************************
    '   This code can be used Royalty Free and Freely Distributed !
    ' ***************************************************************
    #COMPILE EXE
    #REGISTER NONE
    #DIM ALL          '  This is helpful to prevent errors in coding
    
    #INCLUDE "win32api.inc"   ' Must come first before other include files !
    ' *************************************************************
    '                  Constants and Declares (#1)
    ' *************************************************************
    DECLARE SUB LIB_InitColors()
    DECLARE SUB LIB_DeleteBrushes()
     
    %FORM1_FRAME1             = 100
    %FORM1_LABEL1             = 105
    %FORM1_BUTTON1            = 110
    %FORM1_BUTTON2            = 115
    ' --------------------------------------------------
    DECLARE SUB ShowDialog_Form1(BYVAL hParent&)
    DECLARE CALLBACK FUNCTION Form1_DLGPROC
    ' --------------------------------------------------
    ' ------------------------------------------------
    DECLARE SUB CBF_FORM1_BUTTON1(BYVAL NCode&)
    DECLARE SUB CBF_FORM1_BUTTON2(BYVAL NCode&)
     
    
    ' *************************************************************
    '               Application Globals Variables (#2)
    ' *************************************************************
    GLOBAL App_Brush&()
    GLOBAL App_Color&()
    GLOBAL hForm1&    ' Dialog handle
     
     
    ' *************************************************************
    '                    Application Entrance
    ' *************************************************************
    FUNCTION PBMAIN
        LOCAL Count&
        LIB_InitColors
        ShowDialog_Form1 0
        DO
            DIALOG DOEVENTS TO Count&
        LOOP UNTIL Count&=0
        LIB_DeleteBrushes
    END FUNCTION
    
    ' *************************************************************
    '                    Application Dialogs (#3)
    ' *************************************************************
    GLOBAL OriginalFrameWinProc AS DWORD
    '
    FUNCTION FrameSubclassProc(BYVAL hWnd&, BYVAL Msg&, BYVAL wParam&, BYVAL lParam&) AS LONG
         SELECT CASE Msg&
              CASE %WM_COMMAND, %WM_NOTIFY, %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT, %WM_CTLCOLORSTATIC, %WM_CTLCOLORSCROLLBAR, %WM_CTLCOLORLISTBOX, %WM_PARENTNOTIFY
                   ' forward messages to parent dialog so DDT can handle it
                   FUNCTION=SendMessage(GetParent(hWnd&), Msg&, wParam&, lParam&)
                   EXIT FUNCTION
              CASE %WM_DESTROY
                   SetWindowLong hWnd&, %GWL_WNDPROC, OriginalFrameWinProc
              CASE ELSE
         END SELECT
         FUNCTION=CallWindowProc(OriginalFrameWinProc, hWnd&, Msg&, wParam&, lParam&)
    END FUNCTION
    FUNCTION MakeFrameContainer(BYVAL hDlg&, BYVAL ID&) AS LONG
         LOCAL hCtrl&
         CONTROL HANDLE hDlg&, ID& TO hCtrl&
         OriginalFrameWinProc=SetWindowLong(hCtrl&, %GWL_WNDPROC, CODEPTR(FrameSubclassProc))
         FUNCTION=hCtrl&
    END FUNCTION
    SUB SetNewParent(BYVAL hDlg&, BYVAL ID&, BYVAL ParentID&)
         LOCAL hCtrl&, hNewParent&
         CONTROL HANDLE hDlg&, ID& TO hCtrl&
         CONTROL HANDLE hDlg&, ParentID& TO hNewParent&
         SetParent hCtrl&, hNewParent&
    END SUB
    SUB ShowDialog_Form1(BYVAL hParent&)
        LOCAL Style&, ExStyle&, hFrame&
        LOCAL N&, CT&        '  Variables used for Reading Data in Arrays for Listbox and Combobox
        '   hParent& = 0 if no parent Dialog
        Style& = %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER
        ExStyle& = 0
        DIALOG NEW hParent&, "Your Dialog", 0, 0,  309,  246, Style&, ExStyle& TO hForm1&
        CONTROL ADD FRAME, hForm1&,  %FORM1_FRAME1,  "Frame  1", 11, 17, 232, 148, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_GROUPBOX, _
            %WS_EX_TRANSPARENT OR %WS_EX_CONTROLPARENT
        hFrame& = MakeFrameContainer(hForm1&,%FORM1_FRAME1)
        ' must create controls on dialog or they won't be right sizeor position
        ' DDT doesn't use dialog units when the parent of CONTROL ADD is not a dialog
        CONTROL ADD LABEL, hForm1&,  %FORM1_LABEL1,  "Frame Clips Label ->", 147, 121, 117, 25, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER OR %WS_BORDER
        CONTROL ADD "Button", hForm1&,  %FORM1_BUTTON1,  "Button  1", 27, 39, 56, 25, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP
        CONTROL ADD "Button", hForm1&,  %FORM1_BUTTON2,  "Button  2", 27, 74, 56, 22, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP
            ' must use SetParent to put the controls on the frame
        SetNewParent hForm1&,%FORM1_LABEL1,%FORM1_FRAME1
        SetNewParent hForm1&,%FORM1_BUTTON1,%FORM1_FRAME1
        SetNewParent hForm1&,%FORM1_BUTTON2,%FORM1_FRAME1
        DIALOG SHOW MODELESS hForm1& , CALL Form1_DLGPROC
    END SUB
    ' *************************************************************
    '                             Dialog Callback Procedure
    '                             for Form Form1
    '                             uses Global Handle - hForm1&
    ' *************************************************************
    CALLBACK FUNCTION Form1_DLGPROC
        SELECT CASE CBMSG
            CASE %WM_HSCROLL
            CASE %WM_VSCROLL
            CASE %WM_CLOSE
            ' -----------------------------------------------
            CASE %WM_CTLCOLORMSGBOX , %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT,_
                 %WM_CTLCOLORSTATIC, %WM_CTLCOLORSCROLLBAR, %WM_CTLCOLORLISTBOX
                ' Control colors
                SELECT CASE GetDlgCtrlID(CBLPARAM)
                    CASE  %FORM1_LABEL1
                        SetTextColor CBWPARAM, App_Color&( 0)
                        SetBkColor   CBWPARAM, App_Color&( 17)
                        FUNCTION=App_Brush&( 17)
                    CASE ELSE
                        FUNCTION=0
                END SELECT
            CASE %WM_COMMAND
                ' Process Messages to Controls that have no Callback Function
                ' and Process Messages to Menu Items
                SELECT CASE CBCTL
                    CASE %FORM1_BUTTON1
                        CBF_FORM1_BUTTON1 HIWRD(CBWPARAM)
                    CASE %FORM1_BUTTON2
                        CBF_FORM1_BUTTON2 HIWRD(CBWPARAM)
                    CASE ELSE
                END SELECT
            CASE ELSE
        END SELECT
    END FUNCTION
    
    ' *******************************************************************
    ' *                         Library Code   *
    ' ********************************************************************
    SUB LIB_InitColors()
        DATA         0,  8388608,    32768,  8421376,      196,  8388736,    16512, 12895428
        DATA   8421504, 16711680,    65280, 16776960,      255, 16711935,    65535, 16777215
        DATA  10790052, 16752768, 10551200, 16777120, 10526975, 16752895, 10551295, 13948116
        DATA  11842740, 16768188, 14483420, 16777180, 14474495, 16768255, 14483455, 15000804
        LOCAL T&, RGBVal&
        REDIM App_Brush&(0 TO 31)
        REDIM App_Color&(0 TO 31)
        FOR T&=0 TO 31
            RGBVal&=VAL(READ$(T&+1))
            App_Brush&(T&)=CreateSolidBrush(RGBVal&)
            App_Color&(T&)=RGBVal&
        NEXT T&
    END SUB
    ' -------------------------------------------------------------
    SUB LIB_DeleteBrushes()
        LOCAL T&
        FOR T&=0 TO 31
            DeleteObject App_Brush&(T&)
        NEXT T&
    END SUB
    ' -------------------------------------------------------------
    ' *************************************************************
    '   Application Callback Functions (or Subs) for Controls (#4)
    ' *************************************************************
    ' ------------------------------------------------
    SUB CBF_FORM1_BUTTON1(BYVAL NCode&)
        IF NCode&=%BN_CLICKED THEN
              MSGBOX "Button 1 Clicked"
        END IF
    END SUB
    ' ------------------------------------------------
    ' ------------------------------------------------
    SUB CBF_FORM1_BUTTON2(BYVAL NCode&)
        IF NCode&=%BN_CLICKED THEN
              MSGBOX "Button 2 Clicked"
        END IF
    END SUB
    ' ------------------------------------------------
    
    ' *************************************************************
    '           Other Common Procedures and Functions
    ' *************************************************************

    Leave a comment:


  • Mike Doty
    replied
    Thank you!
    I only want it for cosmetic reasons so the container isn't really necessary.
    Just hated the fact I couldn't get it to work. Yes, I thought it would work like VB when done.

    Leave a comment:


  • Chris Boss
    replied
    Mike,

    What you intend is something done in Visual Basic, rather than using the standard controls in Windows using the API.

    Visual Basic is really a hybrid programming language, since the controls are not really the native controls in Windows. The Frame control is of the class "ThunderFrame" in VB.

    In VB, likely they are SuperClassing the native Windows controls, which means they work like them, but can have added features.

    The Frame control (actually Button class) is not natively a container control, like the VB Frame control.

    To be a container (contain other controls), the control has to be able to handle notification messages from its child controls (like dialogs do from their controls).

    Now if you want to be able to use a Frame as a container, you will have to either subclass it or superclass it and then forward the child control notification messages to the parent dialog. Also for the contain control to be able to handle the dialog message loop and be able to handle tabbing to controls, you should use the extended window style %WS_EX_CONTROLPARENT.

    Now I don't think PB Forms will support assigning controls to a Frame control as its parent either (correct me if I am wrong) so you won't be able to drag them together.

    Leave a comment:


  • Mike Doty
    replied
    I've tried this since PBForms first came out and still can't do it.
    I drag the group to within the frame
    I mark the first text box with %WS_GROUP
    The next item after the tab order is marked with another %WS_GROUP? I tried this, no effect.
    I used the tab order function in tools to find the next in tab order and

    I give up. I can put a frame around the controls when the project is done.

    Leave a comment:


  • Dave Biggs
    replied
    Maybe this is the info you are looking for?

    PBForms Help. (PBWinxx\Bin\PBForms.hlp).

    Section. Designing Dialogs / Moving controls.
    (e.g. Ctrl-Click each control to be moved then click-drag one of the highlighted controls to move them all).

    Section. Styles reference / Option control styles.
    (e.g. Add %WS_GROUP to first Option button in a group then add %WS_GROUP to the next tab-order item after the last control in the group).

    Just putting a frame around a number of items on a dalog doesn't make them a 'group' (as may be the case in VB?).
    Section. Styles reference / Frame control syles.

    Leave a comment:


  • Mike Doty
    replied
    How do you add controls to a frame control using PBFORMS so they act as a group?
    It is in the docs somewhere.

    Leave a comment:


  • Michael Mattias
    replied
    By "frame" you mean a Group Box? (code not shown)

    You can make the controls children of the group box. However, that will affect your message handling; you'll have to reset the parent of those controls (see SetParent() API function) to the owning window or subclass the groupbox to receive your notifications.

    Or, you can just move them individually when you move the group box.

    Leave a comment:


  • Mike Doty
    started a topic Frame add controls to a group

    Frame add controls to a group

    How do you add controls to a frame?
    Can't get them to move as a group.
    Where in the docs is this?
Working...
X