Announcement

Collapse
No announcement yet.

Frame add controls to a group

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

  • 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?

  • #2
    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.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


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

      Comment


      • #4
        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.
        Rgds, Dave

        Comment


        • #5
          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.

          Comment


          • #6
            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.
            Chris Boss
            Computer Workshop
            Developer of "EZGUI"
            http://cwsof.com
            http://twitter.com/EZGUIProGuy

            Comment


            • #7
              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.

              Comment


              • #8
                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
                ' *************************************************************
                Chris Boss
                Computer Workshop
                Developer of "EZGUI"
                http://cwsof.com
                http://twitter.com/EZGUIProGuy

                Comment


                • #9
                  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.
                  Rick Angell

                  Comment


                  • #10
                    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.
                    Dale

                    Comment


                    • #11
                      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, ...
                      Furcadia, an interesting online MMORPG in which you can create and program your own content.

                      Comment

                      Working...
                      X