Multi-tool programming secret skills

zhaozj2021-02-16  56

statement:

The toolbar is a relatively traditional topic. If you think this article is more old, please don't read it, so as not to pay for your precious energy and time.

Multi-tool programming secret skills

Li Anne

October 1, 2001

Keywords: toolbar true color button button tag

For an app, the user interface is always one of the critical issues, but it not only determines the convenience of the user, but also increases the user's reliance on the software. Let's take a look at your own experience in how to write a problem with a number of tools with multiple toolbars using VC 6.0. First, implementing multiple toolbars typically in each newly built project, AppWizard has created a default toolbar, and its resource identifier ID is IDR_MAINFRAME, and a ctoolbar type is added to the main window class (such as CMAInframe). Variable m_wndtoolbar. The actual creation of the toolbar is performed in the oncreate () member function of the main window class. When we implement multi-toolbar, we should follow these principles, focusing on the multi-toolbar in the main window class, making unified implementation and management, which is more convenient. With the CToolbar and CDialogbar classes provided by the MFC, the steps are easier. The main points are as follows: (1) Creating a toolbar resource template If you want to add a toolbar implemented by CToolbar, in the Resource Editor: 1. Create a new toolbar resource, assign a resource identifier ID (for example, idR_mytoolbar); 2, add and edit the various tool buttons on the toolbar. The Characteristics of the CToolBar toolbar include multiple buttons, but if you want to include other controls on the toolbar, such as editing boxes, a combined list box, etc., you should use CDialogBar to implement, steps are as follows: 1, click "Project / Add To Project / Components and Controls ... "menu items; 2. In the" Components and Controls Gallery "dialog box, double-click Visual C Components; 3, select" Dialog Bar "in the list, then single Take the "Insert" button; 4, finally click "Close" to close the dialog. This way AppWizard automatically generates the code required for this toolbar within the CMAINFRAME class and establishes a resource template for it, and its resource ID is CG_IDD_MYDILOGBAR. Note that the Dialog Bar's resources are a dialog template instead of a toolbar template. According to the above steps, add a resource for each toolbar to add and assign a resource identification ID. As for how to add a button on the toolbar, and how to build a response function for each button, here is not described here. (2) Deriven the new toolbar, the toolbar can be implemented directly using the CToolbar or CDIALOGBAR class in the MFC. But to implement some specific operations, you must derive your own toolbar. There is a little tip when derived, as follows: When the new class is derived from the ClassWizard or ClassView, CToolbar and CDialogBar are not found in the base class list box. At this point, CToolBarctrl or CDIALOG can be temporarily selected as the base class, and then change the base class to ctoolbar or cdialogbar.

Taken only to the specific steps of the CMYDialogbar class by cdialogbar: 1. Right-click on the first item in ClassView; 2. Click "New Class ..." in the shortcut menu that appears, and "appears" In the New Class dialog, enter the name "CMYDIGBAR" of the newly generated class; 4, select the base class as cDialog, and specify the ID of the Dialog Bar created in Section (1), such as CG_IDD_MYDIALOGBAR. 5. Open myDialogbar.h file, modify the base class of CMYDIALOGBAR to CDialogbar; 6, open myDialogbar.cpp files, replace all CDIALOG to CDialogbar. Note that the constructor of CDIALOGBAR does not have a parameter, so the parameter in ": cdialogbar (CMYDIALOGBAR :: IDD, PPARENT) is changed, and": cdialogbar () ". A CMYTOOLBAR class can be derived from CToolbar according to a similar approach. Then, add in the CMainFrame class of these two classes of objects, such as: CMyToolbar m_myToolBar; CMyDialogbar m_wndMyDialogBar; // This variable is generated by AppWizard formerly At this point, your work is // simply replacing it's base class with CMyDialogbar order. Allow all code in the program to access the toolbar, it is best to set these two variables to public. Of course, please don't forget that the header files of the above two classes are included in the #include instruction. (C) to create a toolbar control to open the file MainFrm.cpp, () member function add the following code within the OnCreate CMainFrame class: // Toolbar2: if (m_myToolBar.CreateEx (this, TBSTYLE_FLAT, WS_CHILD | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY! ! | CBRS_SIZE_DYNAMIC | CBRS_TOP, CRect (0, 0, 0, 0), ID_VIEW_MYTOOLBAR) || m_myToolBar.LoadToolBar (IDR_MYTOOLBAR)) {TRACE0 ( "Failed to create toolbar / n"); return -1; // fail to create } m_mytoolbar.enabledocking (cbrs_align_any); Enabledocking (CBRS_ALIGN_ANAY); DockControlbar (& M_MYTOOLBAR);

AppWizard has created a code for creating a CMYDIALOGBAR control, which is not necessary. Here should be a few questions: 1. The control identifier ID of the toolbar should be noted that the control identifier ID of the toolbar is usually different from its resource identifier ID. AppWizard assigns the control identifier ID assigned by the program's first default toolbar, and we must also assign a control identifier ID to each newly added toolbar. For example, the steps to assign control IDs as follows: (1), open the resource.h file, add the following line: #define id_view_mytoolbar 137 (2), create a M_MytoolBar toolbar control in the oncreate () function of the CMAINFRAME class, Pass ID parameter ID_VIEW_MYTOOLBAR to ctoolbar's createEx () function, without using CreateEx () default parameters (see the code above). It is not necessary to assign an ID for the M_WndmyDialogbar because AppWizard has assigned control identifiers CG_ID_View_filterbar for M_WndmyDialogbar. The CreateEx () function prototype is as follows: BOOL CreateEx (CWnd * pParentWnd, DWORD dwCtrlStyle = TBSTYLE_FLAT, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect rcBorders = CRect (0, 0, 0, 0), UINT nID = AFX_IDW_TOOLBAR); the This can see the value of ID_view_toolbar is equal to AFX_IDW_TOOLBAR. 2. When the program starts, the toolbar is hidden. Some toolbars may not want it to display when the program is started. At this time, simply remove the WS_Visible parameters (see the code). But for the M_WndmyDialogbar toolbar, this method is not Spirit, and can be added to the cmainframe's oncreate () function: m_wndmydialogbar.showwindow (sw_hide); // this approach is effective for all Toolbars. (4), add message mapping entries In addition to the default Outside the toolbar, we should add two message mappings to each newly added toolbar: 1. Open the mainfrm.cpp file, add the M_MytoolBar toolbar to the M_Mytoolbar toolbar in the message mapping table of the CMAINFRAME class: ON_COMMAND_EX (ID_View_mytoolbar , OnBarCheck) ON_UPDATE_COMMAND_UI (ID_VIEW_MYTOOLBAR, OnUpdateControlBarMenu) AppWizard following line has been added to m_wndMyDialogBar: ON_COMMAND_EX (CG_ID_VIEW_MYDIALOGBAR, OnBarCheck) ON_UPDATE_COMMAND_UI (CG_ID_VIEW_MYDIALOGBAR, OnUpdateControlBarMenu) thereof for producing a display and hide the toolbar handling code. But you don't need to add these two entries for the default toolbar.

(5), add a menu item to resourceView, then open the appropriate menu resource, 1, add the menu item "My Toolbar" in the menu, and specify the id_view_mytoolbar; 2, add menu items in the menu "My Dialog Toolbar, and specify ID to CG_ID_View_FilterBar. There is no need to establish a handset for these two menu items because the message mapping entries added in Section (IM) have generated processing code. Click these two menu items to display or hide the corresponding toolbar. At this point, we have three toolbars in our programs, and their types are: ctoolbar, cmytoolbar, and CMYDILOGBAR. After compiling, the three toolbars have been working properly. Second, write similar toolbar shortcut menu issues that when the user right-click the menu bar in the main window, the toolbar submenu is displayed. Naturally, use the onContextMenu (CWND * PWND, CPOINT) function, but debugging discovery, right-click the menu bar simply cannot enter the function, that is, this function does not respond to right-click menu bar. Therefore, the ONNCRBUTTONUP (Uint NhitTest, CPoint Point) function can be used, and the effect is very good. For example, Suppose the menu resource of the toolbar menu is established, its resource ID is IDR_MENU_TOOLBAR, contains the menu item "Default Toolbar", "My Toolbar" and "My Dialog Toolbar"; the objects of the three toolbars are variables in CMainFrame class: CToolBar m_wndToolBar; CMyToolbar m_myToolBar; CMyDialogbar m_wndMyDialogBar; (a), the first to achieve response follows the right-click toolbar: 1, in the offside OnContextMenu CMainFrame class () function, a response message WM_CONTEXTMENU; 2 The following code is added inside this function: hWnd h0 = m_wndtoolbar.getParent () -> m_hwnd; hwnd h1 = m_mytoolbar.getParent () -> m_hwnd; hwnd h2 = m_wndmydialogbar.getParent () -> m_hwnd;

IF (h0 == pwnd-> m_hwnd || h1 == pWnd-> m_hwnd || h2 == pwnd-> m_hwnd) {cmenu mymenu; mymenu.loadmenu; cmenu * Submenu = MyMenu.getsubmenu (0);

Submenu-> TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON, POINT.X, POINT.Y, THIS);

Here, you should pay attention to the first parameter of the onContextMenu () function is neither a primary frame window, nor the toolbar window itself, but a pointer to the parent window of the toolbar (it may be a Dock window). Also, don't respond to WM_ContextMenu messages within the toolbar, such as the ONCONTEXTMUENU () function in the CMYDIALOGBAR class. Otherwise, right-click the toolbar to enter the ONCONTEXTMENU () function of the CMAINFRAME class. Through the experiment, it is interesting that the plurality of toolbars are in neighborhood, and their parent windows are the same (ie, the handle is equal). However, it should still be judged (such as above) to prevent users from pulling them, and their parent windows are different. The above method is better, but if the toolbar is dragging the toolbar to the middle of the floating state, the right mouse button is not reacted, please refer to Section (III) below. (2), but to implement the response to right-click menu bar, you need to do it as follows: 1. Open the mainfrm.h file, add a function in the CMAINFRAME class: AFX_MSG Void OnncrButtonup (uint nhittest, cpoint point); 2 in CMainFrame message mapping table is added: ON_WM_NCRBUTTONUP () 3, in OnNcRButtonUp () function to add the following code: if (nHitTest == HTMENU) {CMenu mymenu; mymenu.LoadMenu (IDR_MENU_TOOLBAR); CMenu * submenu = mymenu.GetSubMenu (0); Submenu-> TRACKPOPUPMENU (TPM_LEFTALIGN | TPM_LEFTBUTTON, POINT.X, POINT.Y, THIS);

(3) Solution to the toolbar float, the response right click in the tool bar and the ONCONTEXTMENU () function is also responding to the WM_ContextMenu message, and then display the shortcut menu in OnContextMenu (), in Submenu-> TRACKPOPUPMENU ( Do not pass the THIS pointer, but the pointer of the main window CMAINFRAME, otherwise the tag can be displayed on the check mark. For example, the following code is added to the onContextMenu () function of each tool class: cmenu mymenu; mymenu.loadmenu (idR_Menu_toolbar); cmenu * Submenu = mymenu.getsubmenu (0);

Submenu-> TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON, POINT.X, POINT.Y, AFXGETMAINWND ());

Doing so every toolbar must use your own class (including the default toolbar), derive from CToolbar or CDialogbar. Therefore, the declaration of the tool bar variable is modified as follows: CMYTOOLBAR M_WNDTOOLBAR; CMYTOOLBAR M_MYTOOLBAR; CMYDIGBAR M_WNDMYDIALOGBAR;

But at this time, CMAINFRAME's onContextMenu () still needs. Because observed when debugging, although at this time, right-click the toolbar button area, it will not enter the onContextMenu () of CMAINFRAME; but CToolBar and its derived class do not float, right-click the toolbar area other than the button, only Enter CMAINFRAME on onContextMenu (), and this PWND points to the parent window of the toolbar, so it is not possible to enter his own onContextMenu (). At this point, right-click the "Toolbar" submenu problem is completely solved. Third, the display button text is created by the CToolbar or CToolbar derived class, and the label text can be displayed below or on the right below. Therefore, a menu item "Display Text" can be created so that the user switches between the display and hidden tag text. To implement the above functions, first call CToolbar's setButtonText () member function in the CMAINFRAME's oncreate () function, and then call its setsizes () member function. And also call the setsizes () function adjustment button size in response to the message processing function of the "Display Text" menu item to display or block the text below the button. Below, it is assumed that the size of each button graph is 24x23, the specific implementation steps are as follows: 1. Open the mainfrm.cpp file, in the end of the return 0 within the oncreate () function; the statement is inserted as follows: char * stext1 [] = {" Tiger "," Parrot "," "Flowers", "Fruit"}; char * stext2 [] = {"Li Jiaxin", "Zhu Ying", "" Little Dragon "," COCO "}; INT i = 0; i <5; i) {m_wndtoolbar.setButtonTontext (i, step1 [i]); m_mytoolbar.setButtonText (i, stext2 [i]);} m_wndtoolbar.setsizes (CSIZE (31, 29), CSIZE (24, 23)); M_MytoolBar.setsizes (CSIZE (31, 29), CSIZE (24, 23)); Now the text is inclusible, the button size is 31x29 (which must be slightly larger than the graphic).

2, to establish within CMainFrame class "show text" response function menu item: void CMainFrame :: OnViewText (); void CMainFrame :: OnUpdateViewText (CCmdUI * pCmdUI); 3, the following code within OnUpdateViewText (CCmdUI * pCmdUI) function : pCmdUI-> SetCheck (m_bTextVisible); 4, in OnViewText () function to add the following code: m_bTextVisible = m_bTextVisible; if (m_bTextVisible) {// Display text:! m_wndToolBar.SetSizes (CSize (32,43), CSize (24 , 25); M_MytoolBar.setsizes (CSIZE (43, 43), CSIZE (24, 25));} else {// make text invisible: m_wndtoolbar.setsizes (CSIZE (31, 29), CSIZE (24, 23) ); m_myToolBar.SetSizes (CSize (31,29), CSize (24,23));} // Resize the toolbar: if (m_wndToolBar.IsWindowVisible () && m_wndToolBar.IsFloating ()) {PostMessage (WM_COMMAND, ID_VIEW_TOOLBAR); PostMessage (WM_COMMAND, ID_VIEW_TOOLBAR);} if (m_myToolBar.IsWindowVisible () && m_myToolBar.IsFloating ()) {PostMessage (WM_COMMAND, ID_VIEW_MYTOOLBAR); PostMessage (WM_COMMAND, ID_VIEW_MYTOOLBAR); (! m_wndToolBar.IsFloating ())} if {PostMessage ( WM_COMMAND, ID_VIEW_TOOLBAR); PostM_Command, ID_View_toolbar; Return;}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} If (! M_mytoolbar.isfloating ()) {PostMessage (WM_COMMAND, ID_VIEW_MYTOOLBAR); PostM_Command, ID_View_mytoolbar; Return;}

5. Add a type BOOL M_BTextVisible in the CMAINFRAME class, and initialize it to false. It is contemplated that the following: 1. When setbuttontext (), the button's serial number (index) must include the separators (|) on the toolbar, and its text is indicated by an empty string "" (see the code above) . 2. Display the size of the button, determined by the programmer test. However, a principle is that the width and height of the button must be at least 7 and 6.3, and after the point of the button graphics, the setsizes (), although the height of the button changes, the height of the toolbar does not immediately immediately Change. The toolbar is changed only when the user clicks on the menu item or change the main window size, and very headache. After repeated exploration, I use the following method, don't have to change the main window size (see the code above): Postmessage; PostMessage (WM_COMMAND, ID_VIEW_MYTOOLBAR); let the toolbar hide first hide then to display status, or First display the restore to hidden state, causing the toolbar window to refresh. This will only cause toolbar shake to avoid the main window jitter caused by changing the main window size. Even if there are multiple toolbars, you only need to choose one of the above processing, all the toolbars will be refreshed at the same time. There is a role in all tool bars that darkened (ie, no floating) (even without adjacent). But thus handling, the floating toolbar is invalid, and vice versa, if the tool strip is floating, it is ineffective. Therefore, a safe way is to process all visible floating tools, and then select a non-floating toolbar (visible or not, it is not a relationship) to process (see the sample code above). The actual window effect is shown in Figure 3. Fourth, the button to display 256 colors Usually the tool button of the application is 16 colors, but it can actually use 256 color (8-bit color), or even the color of 24 bits. The size is not necessarily 16x15, or it can be any extensive size. The implementation method is to load 24-bit color or 256 color bitmap (a total of three bitmaps) using the CIMAGELIST class, then call the members of the CToolbar class setImageList (), setDisabledImagelist () and sethotimagelist (). (1), making bitmaps need to prepare three bitmaps for each button on the toolbar, indicating three states: normal, bright (hot), disabled, where the two can also omitly omit . The brightness is the state when the mouse pointer points to the button, and the gray is when the button is disabled. Now suppose we want to implement the button graphic size of 24x23. And assume that toolbar template resources have been created for the toolbar. Making a bitmap can be used with any graphic processing tool, such as Photoshop, etc. First, you can make a bitmap indicating normal state:

1. A 24x23 graphic is made for each button; 2, arrange the fabrication of the created button graphics, adjacent to a piece, form a bitmap (as shown in Figures 1 and 2);

3. Save the bitmap in the format of 24-bit color as a BMP file, such as Toolbarimg0.bmp and Toolbarimg.BMP files. It should be noted when making it, the button graphics are arranged in the bitmap, and must be exactly the same as the button order in the toolbar resource template, one or one. The resource template here is still needed, because so we don't have to write the specific code of the constructor, and is done by the main framework. The next step is to make a bitmap of brightness and gray grayness: 1, the bitmap of the normal state of the above, texture processing (such as using a photo editor), then saved as another BMP file in 256 colors, For example, ToolBardisableDIMG0.BMP and ToolbardisableDimg.bmp files, as a bitmap for disabled states, there is no need to save 24-bit format; Save the format as another BMP file, such as ToolBarhotimg0.bmp and ToolBarhotimg.bmp files as bitmaps of highlighting. 3, the six bitmaps, all import to the project, allocate their resource IDs to: IDB_IMG0IDB_DISABLED_IMG0IDB_IMG0IDB_DISABLED_IMG0IDB_HOT_IMG0IDB_IMGIDB_DISABLED_IMGIDB_HOT_IMG Note: For 24-bit graph, a warning dialog box will appear when IMPORT can do it. (B) adding an implementation code, add the following six variables in CMainFrame class (can be set protected): CImageList m_img1; CImageList m_img2; CImageList m_disabledimg1; CImageList m_disabledimg2; CImageList m_hotimg1; CImageList m_hotimg2; 2, OnCreate CMainFrame class in the () RETURN 0 at the end of the function; insert the following code before: // load imagelists for Toolbar1: cbitmap Bm; bm.loadbitmap (IDB_IMG0); m_img1.create (24, 23, ILC_COLOR24, 4, 0); m_img1.add ( & BM, RGB (0, 0)); bm.deleteObject (); bm.loadbitmap (idb_disabled_img0); m_disabledimg1.create (24, 23, ilc_color8, 4, 0); m_disabledimg1.add (& BM, RGB (0, 0, 0)); bm.deleteObject (); bm.loadbitmap (idb_hot_img0); m_hotimg1.create (24, 23, ilc_color8, 4, 0); m_hotimg1.add (& BM, RGB (0, 0)); // Set imagelists for toolbar1: CToolBarCtrl & ctl1 = m_wndToolBar.GetToolBarCtrl (); ctl1.SetImageList (& m_img1); ctl1.SetDisabledImageList (& m_disabledimg1); ctl1.SetHotImageList (& m_hotimg1);

// load imagelists for Toolbar2: bm.deleteObject (); bm.loadbitmap; m_img2.create (24, 23, ilc_color24, 4, 0); m_img2.add (& BM, RGB (0, 0, 0)) Bm.deleteObject (); bm.loadbitmap (idb_disabled_img); m_disabledimg2.create (24, 23, ilc_color8, 4, 0); m_disabledimg2.add (& BM, RGB (0, 0)); bm.deleteObject () BM.LoadBitmap; m_hotimg2.create (24, 23, ILC_COLOR8, 4, 0); m_hotimg2.add (& BM, RGB (0, 0)); // set imagelists for Toolbar2: ctoolbarctrl & ctl2 = m_mytoolbar .Gettoolbarctrl (); ctl2.setimagelist (& m_img2); CTL2.SETDISABEDIMAGELIST (& m_disabledimg2); CTL2.SETHOTIMAGELIST (& M_HOTIMG2); The key technology used here is to call the CREATE () function of the CIMAGELIST class, the second parameter Specifies to ilc_color24 or ilc_color8, we can load 24-bit or 8 bitmaps (see Figure 3 of the actual window effect). This method is equally applicable when displaying the icons in TreeView and ListView.

5. Summary This article introduces the programming method of multi-tool strips, which has high practical value for improving the ease of use of procedures and the level of commercialization. The author uses these technologies in the software design and development, all of which are well received by users. The sample code is debugged in VC 6.0 and Win 98. There are still some imperfect places in the text. I hope that friends will propose adversions and suggestions, and hope that this article can play the effect of bricking jade.

Hereinafter, the focus of this article is summarized (this paragraph can be omitted): 1. If the toolbar is not displayed when the program is started, simply use the toolbar when calling create (), does not specify the WS_Visible style I.e. Or simply call ShowWindow (SW_HIDE). 2. When you create multiple toolbars, you should do in the oncreate () function of the main window. 3. In addition to the first default toolbar of AppWizard automatically created, ID_VIEW_TOOLBAR, other toolbars are set to other IDs in addition to it. 4. In addition to the default toolbar, it should also add the following two message mapping entries to the mainfrm.cpp file (assuming the ID_toolbar) to the mAINFRM.CPP file (assuming the ID_toolbar) to respond menu items: ON_COMMAND_EX (ID_MYTOOLBAR, ONBARCHECK ) On_update_command_ui (id_mytoolbar, onupdateControlbarmenu)

转载请注明原文地址:https://www.9cbs.com/read-25802.html

New Post(0)