Announcement
Collapse
No announcement yet.
Frame add controls to a group
Collapse
X
-
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, ...
-
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:
-
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:
-
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:
-
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:
-
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:
-
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:
-
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:
-
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:
-
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:
-
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?Tags: None
Leave a comment: