In our mfc programming, we need to use the list box to display the parameter settings of each layer or object, and also hope to edit its parameters. I used to search online, using CComboListCtrl, which requires three cpp and h files, which is not easy to use.
I saw an article recently. https://blog.csdn.net/qingyang8513/article/details/50986455 This is very simple to use listctrl and an Edit control directly. So I also tested it and recorded it here.
The effect is as follows: click on the contents of a list box to edit, but I can't edit the picture when I edit it.
My operating environment is vc2010, and I will start the process below.
Key contents:
1) List Control NM_DCLICK message response event;
2) Kill Focus message response of Edit Control;
3) Dynamic display and hiding of Edit Control;
4) List Control obtains the number of specified rows and columns, gets the contents of specified rows and columns, and modifies assignments.
Operation:
1. Create MFC application based on dialog box and delete the original static text.
2. Add a List Control control and an Edit Control control, and associate the control variables m_ListTem and m_EditTest separately (List Control controls are adjusted appropriately, Edit Control size is not adjusted);
3. The initialization dialog function OnInitDialog implements the initialization of List Control control and Edit Control control, InitList(), UpdateList();
The code is as follows:
BOOL CListCtrlTestDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here InitList(); UpdateList(); return TRUE; // return TRUE unless you set the focus to a control } void CListCtrlTestDlg::InitList(void) { Clayer layer={"zhang",1.3,15.6,88}; m_layer.push_back(layer); Clayer layer1={"Li",22.3,25.6,288}; m_layer.push_back(layer1); Clayer layer2={"Wang",32.33,35.6,388}; m_layer.push_back(layer2); m_EditTest.ShowWindow(SW_HIDE); CRect rect; m_ListTem.GetClientRect(&rect); int iLength = rect.Width(); m_ListTem.SetExtendedStyle(m_ListTem.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); m_ListTem.InsertColumn(0, _T("number"), LVCFMT_CENTER, 40); m_ListTem.InsertColumn(1, _T("Name"), LVCFMT_CENTER, 80); m_ListTem.InsertColumn(2, _T("x"), LVCFMT_CENTER, (iLength - 120)/3); m_ListTem.InsertColumn(3, _T("y"), LVCFMT_CENTER, (iLength - 120)/3); m_ListTem.InsertColumn(4, _T("Rotation angle"), LVCFMT_CENTER, (iLength - 120)/3); } void CListCtrlTestDlg::UpdateList(void) { CString index,x,y,z,name,count,rotate,blocks; while(m_ListTem.GetItemCount()>0) m_ListTem.DeleteItem(0); for(int i=0;i<m_layer.size();i++) { index.Format("%d",i); Clayer& layer=m_layer[i]; name=layer.name; x.Format("%.2f",layer.x); y.Format("%.2f",layer.y); count.Format("%d",layer.count); m_ListTem.InsertItem(i,index); m_ListTem.SetItemText(i,1,name); m_ListTem.SetItemText(i,2,x); m_ListTem.SetItemText(i,3,y); m_ListTem.SetItemText(i,4,count); } }
In the h file, the layer parameter structure is defined, and the layer parameter vector m_layer is defined.
typedef struct {CString name;float x;float y;int count;} Clayer;
std::vector<Clayer> m_layer;
With the above, the above code is correct. This is where the initial display is completed. You should get the initial effect, but you can't edit it.
4. Add int variables m_Row and m_Col to the header file of the dialog box to save the selected row and column numbers when double-clicking, and initialize them to -1 (unchecked state);
5. Add the NM_DBLCLK message response to the List Control control and add the following code:
void CListCtrlTestDlg::OnDblclkList2(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); // TODO: Add your control notification handler code here CRect rc; CString strTemp; NM_LISTVIEW *pNMListView = (NM_LISTVIEW *)pNMHDR; m_Row = pNMListView->iItem; m_Col = pNMListView->iSubItem; if (pNMListView->iItem == -1) //Choose the blanks return; if (m_Col != 0) // Select subitems { m_ListTem.GetSubItemRect(m_Row, m_Col, LVIR_LABEL, rc); m_EditTest.SetParent(&m_ListTem); m_EditTest.MoveWindow(rc); m_EditTest.SetWindowText(m_ListTem.GetItemText(m_Row, m_Col)); m_EditTest.ShowWindow(SW_SHOW); m_EditTest.SetFocus();//Setting Edit Focus m_EditTest.ShowCaret();//Display cursor m_EditTest.SetSel(0, -1);//All election } *pResult = 0; }
6. Add EN_KILLFOCUS message response to the Edit Control control and add the following code:
void CListCtrlTestDlg::OnKillfocusEdit1() { // TODO: Add your control notification handler code here CString str; m_EditTest.GetWindowText(str); m_ListTem.SetItemText(m_Row, m_Col, str); m_EditTest.ShowWindow(SW_HIDE); }
Now we can compile, run and test the program, which should be the result of our start.