Put the form from the main form
McOL
Almost all official C Builder programs have the slave form in addition to the main window, sometimes the dialog, sometimes no mode window. VCL makes it easy to create and display the slave form. But not all programs are suitable for useless form, some programs need to display different content in one main window. This article discusses how to "resigniate" in the main form, which looks from the main form, and the user does not know that a slave form is being displayed. Figure A shows a main form, and its client area is a slave from the form.
Understand the basic ideas of such programs for such programs are sub-forms that make all slave forms as a primary form, which is very common in other frameworks (such as OWL or MFC), but not in the VCL program common. VCL does not allow simply specifying properties to make a form belong to another form, to do this to pay some small labor. You have to tell the Microsoft Windows Subject to the Subject of the main form, which generally tends to be a window in C Builder programming, and the component is a child object. It is actually seen from Windows, and the forms and components are window. You can specify any window (forms and components) as the child object of another window, as long as you temporarily jump out of the VCL circle. Better "Mouse Clip" A benefit of a homeric list is that you can design a suborman in the design of any other slave form, that is, you create a new form, add it on it. Components and write this form of this form. This makes it easy to design your sub-form and set all the code of all opinion forms in one place. The program design example gives some of the background of some programs. The program is called Parenting, with a main form, the top of the main form, and the bottom of the Tool Bar and Status Bar, except for the main form. In addition, there are two sub-forms, a TTableForm, display animal.dbf data sheet with a raster, an Animal Table is a table of the database samples of the C Builder. Another child form TCHARTFORM displays the animal table with TCHART. (If you purchase C Builder is a standard version without database components) You can select the display form or the graphic form by clicking the Menu item or the tool button, when you make a choice, the active form is destroyed and the form is selected. Display, the subscription is below the toolbar of the main form, and the client area above the status bar is displayed, and the client is always filled with the main form size. Reserved CREATEPARAMS () As mentioned, in order to control the host form to control the slave form, it is necessary to set the main window to the "parent" from the form, which can be done by overloading the CreateParams () method. CREATEPARAMS () calls when VCL creates a window contact with the form, the declaration of createparams () is as follows: Void __fastcall createparams (TCREATEPARAMS & PARAMS); the unique parameter of CreateParams () is a reference to a TcreateParams structure. In the VCL TCreateParams defined as follows: struct TCreateParams {char * Caption; int Style; int ExStyle; int X; int Y; int Width; int Height; HWND WndParent; void * Param; tagWNDCLASSA WindowClass; char WinClassName [64];}; This structure contains all the information required for Windows to create a window (if you have used API for Windows programming, you must realize the map of TcreateParams to the Windows CreateStruct structure). When you overload CreateParams (), first call the baseparams () method of the base class, then modify the individual member variables of the TcreateParams structure.
A heavy-duty off the CreateParams () method looks as follows: void __fastcall TChartForm :: CreateParams (TCreateParams & Params) {TForm :: CreateParams (Params); Params.Style = WS_CHILD | WS_CLIPSIBLINGS; Params.WndParent = MainForm-> Handle; Params.x = 0; params.y = 0; params.width = mainform-> clientRect.right; params.height = mainform-> clientRect.bottom;} The key is to set the TCREATEPARAMS structure STYLE and WNDParent members, Style, Style Set WS_CHILD and WS_CLIPSIBLINGS window, WS_CHILD specifies the sub-window for the window for another window. Depending on the definition, a child window is not a title stick, the title bar when designing, in Windows, creates a window, is removed. WS_CLIPSIBLINGS guarantees that the different sub-windows of the main window do not interfere when forming the form. Obviously, a sub-window must have a parent object that specifies the parent object by specifying the parent window handle to the TcreateParams structure WNDParent member, as indicated by the previous code, the WndParent member is set to the Handle property of the main form. Given that the specified parent object property is relatively straightforward, I don't go deep into this topic. Setting the property of the sub-form In addition to the code in the createparams () method, you have to set the properties of some subforms, and most attributes can keep the default, but the AutoScroll property should be false, of course, the premise is your form. To design a form that does not have to be rolled. Since the size and location of the sub-window is set in createparams (), the position property can be set to Podefault. Caption and Bordericon properties will be ignored, so there is no need to specify. Make sure BorderStyle is set to Bssizeable, and BorderWidth is set to 0, and if this two attribute is set to other values, the child form is not coordinated with the main window. Other components of the form, in addition to the slave form, the main form also contains other components, such as toolbar and status strips, and set the TCREATEPARAMS structure X, Y, Width and Height members to take into account the tool. The strip and status bars, the subsidiary should be coordinated with the top of the toolbar and the bottom of the strip. Therefore, the code to set the member of the TcreateParams structure should be: params.x = 0; params.y = mainform-> Toolbar-> height 1; params.width = mainform-> clientRect.right; params.height = (Mainform- > Statusbar-> TOP-1) -Params.y; Note Y is set to the bottom of the tool bar plus 1, the sub-form width is set as the main form client area width, and the height is calculated according to the top of the subform and the status bar, basically In order to be bound to the main formal client between the bottom of the tool strip and the bottom of the state bar. These are all requirements that enable the slave family "home" in the main form, you may have the features that want to be implemented in the child form, I will leave these characteristics to the back. Setting the main form mainfall also to be set to control the sub-form of its "receipt". First, you need to remove the child form from the automatically created form list and create them again. If you do not remove it from the list, they will be automatically displayed when your application starts.
You also need a variable to track the current active subform, declare the variables in the PUBLIC area of the main form, tform * ActiveChild; ActiveChild is public because the sub-form is to access this variable. I will immediately demonstrate how to use this variable. Now let's write the code that shows the child form, first look at the following line, then I will explain. void __fastcall TMainForm :: Chart1Click (TObject * Sender) {if (ActiveChild) delete ActiveChild; TChartForm * form = new TChartForm (this); ActiveChild = form; form-> Show (); Chart1-> Checked = true; Table1-> Checked = false;} This method is the onclick handler of the host's menu item, guess is right, this is displaying the Tchartform child form. First check if the ActiveChild variable is not 0, and if there is an activation mutual form ActiveChild will not 0. If ActiveChild is not 0, the pointer associated with this variable is deleted to destroy the active subform, otherwise the procedure will be stacked one by one. Then create an instance of a TCHARTFORM class, returning the New operation to the pointer to assign an ActiveChild variable, so ActiveChild always contains a pointer to the current subform. Finally, the SOW () method displays a child form. The last two lines of code ensure that the menu item representative form or graphic display shows a selected mark. In order to complete the discussion of the ActiveChild variable, I have to take you back to the sub-unit unit for a while. Each subform contains a OnClose event handler event follows: void __fastcall TChartForm :: FormClose (TObject * Sender, TCloseAction & Action) {MainForm-> ActiveChild = 0; MainForm-> Chart1-> Checked = false; Action = caFree } Note When the form is destroyed, the ActiveChild of the main form is set to 0 and is placed in unchecked menu item associated with the subsidiary. The Action parameter is set to CAFREE to notify the VCL to release the memory associated with this form. You may be confused with what the FormClose handle contains the last two lines above. The answer is that each subform has a Close button to close the form. If you turn off the form with a Close button, you need to release the memory and Uncheck menu items. The additional feature example has at least one feature that has not been discussed, that is, if the child form is larger than the main form, re-adjust the main form size to accommodate the subform. These statements are placed in the CreateParams () method of the child form. I have shown a simple createParams () example, but did not put it in a statement that adjusts the main form size. List B has a complete createParams () method, and previous demonstrations uniquely include the following statement: if (width> mainform-> clientwidth) Mainform-> clientwidth = width; if (Height> (mainform-> statusbar-> TOP -Mainform-> Toolbar-> Height)) Mainform-> ClientHeight = Height Mainform-> Toolbar-> Height Mainform-> statusbar-> height; these statements Check if the width of the subform is greater than the hostwidth of the main form. Attributes, if yes, the clientwidth of the main form is placed as the width of the subform.
The remaining several lines are the same thing, but it is only targeted that the customer area of the main form is height. The result of these statements is that the main form is always adjusted to a subsidy that can be fully contained. The example program also considers the main form of the main form. If the main window is changed, the subsidiary size must vary to make a client area filled with the main form. The following statement illustrates OnResize event handler of the main form: void __fastcall TMainForm :: FormResize (TObject * Sender) {if (ActiveChild) {ActiveChild-> Width = ClientRect.Right; ActiveChild-> Height = (MainForm-> StatusBar-> TOP-1) -activechild-> top;}} These statements are quite straightforward, without having to explain one by one. Note First, the ActiveChild variable ensures non-0 (ie, pointing to a sub-form), it is clear if there is no activation any child form, nothing in OnResize. The remaining statements are variants of statements in CreateParams (), just simply calculate new sizes of the child form and set the corresponding Width and Height properties. The conclusion list A contains the code of the example of the master's main form. List B shows the source code of the TChartForm unit. The header file did not give the statement of the TTableForm cell because there is no meaningful statement, because similar to the Chatform unit. You can download an example program at www.reisdorph.com. The sub-form "home" provides a clear alternative to the MDI in the main form, which is also an alternative to programs that can only display data to the user in the form of a modeless form, using a child form to allow you to use The form designer designs your from the window and places the code of the operator form in a place.
List A: mainu.cpp # include