Implementation method of MSFLEXGRID embedd, ComboBox in VC
Key Words: MSFLEXGRID inline control
In the 9CBS network, some people will often see the implementation methods of various Grid control embedds, ComboBox, and in the development of the pretty stage, it also encounters this difficulties, and finds it on the Internet, most of them ListView and dbgrid, and less than the implementation of MSFLExGrid With the support of the majority of netizens, I finally found a way to implement MSFlexGrid embedd, ComboBox, I want this article to have considerable help for applying MSFLExGrid to applying development.
Summary Some netizens and the reasons why they originally implemented the MSFlexGrid embedded controls, mostly caused by two aspects:
1. Coordinate system conversion problem, the coordinate system and general controls used by MSFlexGrid are different, so they need to be converted during operation.
2, the control is created on the problem, if you create the control directly in the main window, then there will be, the program is running, the mouse is a grid, the control is off, so when you create a control Edit, ComboBoX, FlexGrid is a parent window.
Below, I use an example program to simply explain, and our sample program also implements the Tab button to step to the next grid in the FlexGrid [The grid mentioned below refers to the small cells in MSFLExGrid]. Features.
Program run interface:
First, call our initialization function in the initialization of the dialog:
Void cprog5dlg :: initcontrols ()
{
// Create each inline control
M_EDit.create (WS_CHILD, CRECT (0, 0), & M_FlexGrid, IDC_EDIT);
M_cmb.create (ws_child | cbs_dropdownlist, crect (0, 0, 0), & m_flexgrid, IDC_CMB);
// Set the same font as the main window
m_edit.setfont (getFont ());
m_cmb.setfont (getFont ());
// Pack Grid and ComboBox with data
Long LROW;
Long lrowcount = m_flexgrid.getrows ();
Long Lcol;
Long LCOLCOUNT = m_flexgrid.getcols ();
For (LROW = 1; LROW { m_flexgrid.setrow (LROW); For (LCOL = 1; LCOL { m_flexgrid.setcol (LCOL); CString strText; Strtext.Format ("% LD-% LD", LROW, LCOL); // Pack Grid with data m_flexgrid.settext (strText); // Pack ComboBox with data m_cmb.addstring (strText); } } } Where m_edit, m_cmbmb is our statement of class data: Private: Cedit m_edit; CCOMBOBOX M_CMB; Their creation must use .create method and use msflexgrid as a parent window, otherwise, when running, you do MSFLEXGRID, your Edit or ComboBox is gone [this is because MSFlexGrid is the same as your Edit or ComboBox Dialog is a parent window, you have some msflexgrid, on the Z coordinates, it covers your embedded control], because after the creation, the fonts they use may be inconsistent with your main window style, so I have to set it up. Font. Next is the most important function in the program: Void CProg5dlg :: GridEdit (Word Nkeyascialode, CWND * P_Wnd) { IF (p_wnd == null) {// Get the contents of the current edited grid is m_edit or m_cmbmb p_Wnd = getThiscellmaskControl (); } Assert (p_wnd! = Null); / / Support coordinate transformation CDC * PDC = M_FlexGrid.getdc (); INT NLOGX = PDC-> getDeviceCaps (Logpixelsx); INT NLOGY = PDC-> getDeviceCaps (Logpixelsy); ReleaseDC (PDC); Cstring sz; // When there is a text input, if the current control is edit, then the cursor is at the end. IF (nkeyascialode> = 0 && nkeyasciicode <') { IF (p_wnd-> iskindof (runtime_class (cedit))) { (CEDIT *) P_WND) -> setsel (-1, -1); } } Else { CString Input = "" P_Wnd-> getWindowText (SZ); IF (Nkeyascialode> 0x100) {/ Used to support Chinese characters Input.Setat (0, Nkeyascialode >> 8); Input.Setat (1, Nkeyascial & 0xFF); } Else {// Non-Chinese INPUT = (char) nkeyascialode; } SZ = INPUT; P_Wnd-> SetwindowText (SZ); } IF (p_wnd-> iskindof (runtime_class (ccomboBox))) { P_Wnd-> MoveWindow (m_flexgrid.getcellleft () * nlogx) / 1440 - 3, (m_flexgrid.getcelltop () * nlogy) / 1440 - 3, (m_flexgrid.getcellwidth () * nlogx) / 1440, (m_flexgrid.getcellheight () * nlogy) / 1440 100, false); } Else IF (p_wnd-> iskindof (runtime_class (ced))) { P_Wnd-> MoveWindow (m_flexgrid.getcellleft () * nlogx) / 1440 - 3, (m_flexgrid.getcelltop () * nlogy) / 1440 - 3, (m_flexgrid.getcellwidth () * nlogx) / 1440, (m_flexgrid.getcellheight () * NLOGY) / 1440, FALSE); } Else { AskERT (0); // Show our control P_Wnd-> ShowWindow (SW_SHOW); p_Wnd-> setfocus (); P_Wnd-> getWindowText (SZ); IF (p_wnd-> iskindof (runtime_class (cedit))) { ((CEDIT *) P_WND) -> setsel (sz.getlength (), sz.getlength (), false); } M_FlexGrid.RedrawWindow (); } [Description: This function is not original] The function of this function is mainly to support the editor of MSFlexGrid and display your inline control. Of course, if it is an edit, then we have the last cursor within the Edit in the end of the Edit. This function has two parameters: Word nkeyascialode: If the event of editing FlexGrid is a button, then this parameter is of course related to the button information, in addition to the function, through it can implement support Chinese, such as: You put the focus to an embedded EDIT In the grid [just let the grid of FlexGrid get the focus, do not let the embedded Edit display], enter Chinese directly, then find that the grid will automatically enter the editing state, and the Chinese Chinese characters you entered are located in the string At last: The second parameter: CWnd * p_wnd You can specify the inline control you want, and you can use & m_edit or & m_cmbmb00 when passing. Of course, you may not specify it and use our original rules [this rule refers to which of the MSFLEXGRID which is fixed to which inline control is used. What is this implementation? See the function in the GridEdit IF (p_wnd == null) { p_Wnd = getThiscellmaskControl (); } Is it? CWnd * cprog5dlg :: getThiscellmaskControl () { Switch (m_flexgrid.getcol ()) { // First column, the third column uses ComboBox as an inline control Case 1: Case 3: Return & M_CMB; Break; / Other use Edit DEFAULT: Return & m_edit; } } We can set some basic rules through this function. So whose GridEdit function is called? The answer is of course triggered by an event that wants to implement the editing grid. Here I set up a button event when you double-click and your grid with the mesh: // Mouse double-click excitation Void CProg5dlg :: OndblclickMsflexGrid () { // The first line and the first column are fixed, I don't want to edit them. IF (M_FlexGrid.getcol () == 0 || m_flexgrid.getrow () == 0) Return; GridEdit (0, NULL); } // Button event excitation Void CProg5dlg :: onkeypressmsflexGrid (Short Far * Keyascii) { // Todo: Add Your Control Notification Handler Code Here IF (M_FlexGrid.getcol () == 0 || m_flexgrid.getrow () == 0) Return; GridEdit (* keyascii, null); } Before you causing this function, we best set the contents of ComboBox's current selection and Edit to the sheet to edit: void cprog5dlg :: OneNtercellmsflexGrid () { // Todo: Add Your Control Notification Handler Code Here INT nthisrow = m_flexgrid.getrow (); IF (nthismrow == 0) { Return; } Cstring sz; SZ = m_flexgrid.getText (); CWnd * pwnd = getThiscellmaskControl (); IF (PWND-> iskindof (runtime_class (ccomboBox))) { (CCOMBOBOX *) PWND) -> SelectString (-1, sz); } Else IF (PWND-> iskindof (runtime_class (ced))) { PWND-> SetwindowText (SZ); } Else { Assert (0); } } Do you think this way? Of course! When we move the focus to other grids [just remove the focus], we need to drop the embedded control Hide that has already been displayed, and pass its content to the grid, which is the purpose of our editor. Void CProg5dlg :: OnleAvecellmsflexGrid () { // Todo: Add Your Control Notification Handler Code Here INT nthisrow = m_flexgrid.getrow (); IF (nthismrow == 0) { Return; } Cstring sz; CWND * p_thiswnd = getThiscellmaskControl (); Assert (p_thiswnd! = Null); IF (p_thiswnd-> iswindowvisible ()) { p_thiswnd-> getWindowText (SZ); m_flexgrid.settext (sz); p_thiswnd-> showwindow; } } It is basically almost the same. The following is a brief introduction to the problem of jump in the grid of MSFLEXGRID with TAB. I saw this application, I immediately thought of using the PretranslateMessage function, this function is really easy to use, usually in the window of the focus, I use it. Before implementing it, let's define a function that jumps to the grid: Void CProg5dlg :: gotonextCell () { IF (M_FlexGrid.getcol () == m_flexgrid.getcols () - 1) { IF (M_FlexGrid.Getrow ()! = m_flexgrid.getrows () - 1) { M_FlexGrid.setrow (m_flexgrid.getrow () 1); M_FlexGrid.Setcol (1); } Else { Return; } } Else { m_flexgrid.setcol (m_flexgrid.getcol () 1); } } In our PretranslateMessage, it will call it to be jumped to the next grid: Bool CProg5dlg :: PretranslateMessage (MSG * PMSG) { // Todo: add your specialized code here and / or call the base classcwnd * pwnd = CWnd :: fromHandle (PMSG-> hw); CWND * PCON = GetThiscellmaskControl (); IF (PMSG-> Message! = WM_KEYDOWN) Return CDIALOG :: PretranslateMessage (PMSG); Switch (PMSG-> WPARAM) { Case VK_TAB: IF (PCON-> getsafehwnd () == PMSG-> hWnd) {// If you press TAB, in the Edit status, you will also jump to the next place GotonextCell (); Return True; } Switch (pWnd-> getdlgctrlid ()) { Case IDC_MSFLEXGRID: GotonextCell (); Return True; } Break; } Return CDIALOG :: PretranslateMessage (PMSG); } Ok, the entire application is finished, I want to use MSFLEXGRID to realize applications, this small Dongdong must play the role of throwing jade. If you want to get its source, please send me an email: Mahongxi@hotmail.com