4 Static split window
4.1 Custom MFC view class
Customize two classes: CSelectView and CDispalyView (its base class must be a view class).
CSelectView inherits from CTreeView, and CDispalyView inherits from CFormView.
4.2 Split the window through the CSplitterWnd class
1) In the CMainFrame class, declare an object of type CSplitterWnd:
private: CSplitterWnd m_spliter; // Split window class object
2) Rewrite the OnCreateClient function of the frame class CMainFrame
Change the return value of the OnCreateClient() function to Return TRUE:
The static splitting implementation code is as follows:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {<!-- --> // TODO: Add specialized code here and/or call the base class // Static split window, 1 row and 2 columns, CSplitterWnd::CreateStatic m_spliter.CreateStatic(this, 1, 2); //Create view: CSplitterWnd::CreateView //0, 0: Place it at row 0 and column 0 //RUNTIME_CLASS(CSelectView): Requires header file #include "SelectView.h", CSelectView is declared in SelectView.h // CSize(250, 500): Specify the view width and height //pContext: The last formal parameter of OnCreateClient() m_spliter.CreateView(0, 0, RUNTIME_CLASS(CSelectView), CSize(200, 500), pContext); //0, 1: Place it at row 0 and column 1 //CDispalyView, requires header file #include "DispalyView.h" m_spliter.CreateView(0, 1, RUNTIME_CLASS(CDispalyView), CSize(600, 500), pContext); //return CFrameWnd::OnCreateClient(lpcs, pContext); return TRUE; }
The program running effect diagram is as follows:
##5 Implementation of tree view function
5.1 Add function node
1) Load icon resources
The icon resource ID is changed to: IDI_ICON_RE
2) Declare the corresponding variables in the CSelectView class:
CTreeCtrl *m_treeCtrl; //Tree control CImageList m_imageList; //Icon list
3) Rewrite the OnInitUpdate function of CSelectView
void CSelectView::OnInitialUpdate() {<!-- --> CTreeView::OnInitialUpdate(); // TODO: Add specialized code here and/or call the base class }
4) In the OnInitUpdate function of CSelectView, complete the initialization function
void CSelectView::OnInitialUpdate() {<!-- --> CTreeView::OnInitialUpdate(); // TODO: Add specialized code here and/or call the base class //Loading of icon resources CWinApp::LoadIcon //IDI_ICON_RE is the icon resource ID HICON icon = AfxGetApp()->LoadIconW(IDI_ICON_RE); //Creation of image list CImageList::Create //30, 30: Specify the width and height of the icon //ILC_COLOR32: Icon format //1, 1: Write as many icons as there are m_imageList.Create(30, 30, ILC_COLOR32, 1, 1); //Add icon to image list CImageList::Add m_imageList.Add(icon); //Get the tree control in the data view CTreeView::GetTreeCtrl m_treeCtrl = & amp;GetTreeCtrl(); //Count control set image list CTreeCtrl::SetImageList m_treeCtrl->SetImageList( & amp;m_imageList, TVSIL_NORMAL); //Tree control setting node CTreeCtrl::InsertItem m_treeCtrl->InsertItem(TEXT("Personal Information"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("Sales Management"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("Inventory Information"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("Inventory Add"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("Inventory Delete"), 0, 0, NULL); }
The program running effect diagram is as follows:
5.2 Function node corresponding message processing
void CSelectView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult) {<!-- --> LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // TODO: Add control notification handler code here *pResult = 0; }
In the above function, obtain the selected content of the current node:
void CSelectView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult) {<!-- --> LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // TODO: Add control notification handler code here *pResult = 0; //Get the selected item of the current node CTreeCtrl::GetSelectedItem HTREEITEM item = m_treeCtrl->GetSelectedItem(); //Get the text content of the selected item CTreeCtrl::GetItemText CString str = m_treeCtrl->GetItemText(item); //MessageBox(str); if (str == TEXT("Personal information")) {<!-- --> } else if (str == TEXT("Sales Management")) {<!-- --> } else if (str == TEXT("Inventory information")) {<!-- --> } else if (str == TEXT("Inventory increase")) {<!-- --> } else if (str == TEXT("Inventory Delete")) {<!-- --> } }
6 Personal information management window
6.1 UI design
1) Add a dialog box resource (change the ID to DIALOG_USER) and add the required controls:
In the window properties, change Border to None and Style to Child:
2) Select the dialog box -> right-click -> Add class -> Class name: CUserDlg, select CFormView as the base class
3) According to the requirements, the control associates the required variables
The identity editing area is associated with CString m_user, and the username editing box is associated with CString m_name.
The new password edit box is associated with CString m_newPwd, and the sure password edit box is associated with CString m_surePwd.
6.2 Function Implementation
1) In the dialog class, rewrite the OnInitDialog function to initialize it.
void CUserDlg::OnInitialUpdate() {<!-- --> CFormView::OnInitialUpdate(); // TODO: Add specialized code here and/or call the base class }
void CUserDlg::OnInitialUpdate() {<!-- --> CFormView::OnInitialUpdate(); // TODO: Add specialized code here and/or call the base class CInfoFile file; //Header file required #include "InfoFile.h" CString name, pwd; file.ReadLogin(name, pwd); //Read the username and password of the file //Initialize personal information m_user = TEXT("Salesperson"); //Identity m_name = name; //user name UpdateData(FALSE); //Update data to the control }
2) Confirm that the change password button function is implemented
void CUserDlg::OnBnClickedButton1() {<!-- --> // TODO: Add control notification handler code here UpdateData(TRUE);//Update the content of the control to the corresponding variable if (m_newPwd.IsEmpty() || m_surePwd.IsEmpty()) {<!-- --> MessageBox(TEXT("Enter password cannot be empty")); return; } if (m_newPwd != m_surePwd) {<!-- --> MessageBox(TEXT("Enter password and confirm password are not equal")); return; } CInfoFile file; //Header file required #include "InfoFile.h" CString name, pwd; file.ReadLogin(name, pwd); //Read the username and password of the file if (m_surePwd == pwd) {<!-- --> MessageBox(TEXT("The entered password is equal to the old password")); return; } //Convert the CString type of username and password to char * char *tmpName, *tmpPwd; \t//username CStringA tmp1; tmp1 = name; tmpName = tmp1.GetBuffer(); \t//password CStringA tmp2; tmp2 = m_surePwd; tmpPwd = tmp2.GetBuffer(); file.WritePwd(tmpName, tmpPwd); //Change password MessageBox(TEXT("Password changed successfully")); //Clear the content of the input box m_surePwd.Empty(); m_newPwd.Empty(); UpdateData(FALSE); //Update data to the control }
3) Implementation of cancel button function
void CUserDlg::OnBnClickedButton3() {<!-- --> // TODO: Add control notification handler code here //Clear the content of the input box m_surePwd.Empty(); m_newPwd.Empty(); UpdateData(FALSE); //Update data to the control }
7 interface mounting
7.1 Customized message sending
1) In the CMainFrame frame class, add a custom message macro
//WM_USER is a starting value for user-defined messages //WM_USER + 100 is to distinguish system messages and user messages to avoid conflicts #define NM_A (WM_USER + 100) #define NM_B (WM_USER + 101) #define NM_C (WM_USER + 102) #define NM_D (WM_USER + 103) #define NM_E (WM_USER + 104)
2) Add a custom message processing function in the CMainFrame framework class:
//Custom message processing function afx_msg LRESULT OnMyChange(WPARAM wParam, LPARAM lParam);
3) The corresponding .cpp defines its function
LRESULT CMainFrame::OnMyChange(WPARAM wParam, LPARAM lParam) {<!-- --> }
4) Add a custom message entry between the CMainFrame framework class BEGIN_MESSAGE_MAP and END_MESSAGE_MAP and bind it to the custom message processing function.
//ON_MESSAGE responds to a custom message //Generate NM_X message and automatically call OnMyChange function ON_MESSAGE(NM_A, OnMyChange) ON_MESSAGE(NM_B, OnMyChange) ON_MESSAGE(NM_C, OnMyChange) ON_MESSAGE(NM_D, OnMyChange) ON_MESSAGE(NM_E, OnMyChange)
5) Send custom signals
In the OnTvnSelchanged function of CSelectView, send a custom signal:
if (str == TEXT("Personal information")) {<!-- --> //Need to include the framework class header file #include "MainFrm.h" //CWnd::PostMessage puts a message into the window's message queue //AfxGetMainWnd(): Pointer to the frame window object //AfxGetMainWnd()->GetSafeHwnd(): Get the handle of the returned window, CWnd::GetSafeHwnd //NM_A: Send custom message //(WPARAM)NM_A: Specifies additional message information //(LPARAM)0: Additional message information is specified. This parameter has no meaning here. ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_A, (WPARAM)NM_A, (LPARAM)0); } else if (str == TEXT("Sales Management")) {<!-- --> ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_B, (WPARAM)NM_B, (LPARAM)0); } else if (str == TEXT("Inventory Information")) {<!-- --> ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_C, (WPARAM)NM_C, (LPARAM)0); } else if (str == TEXT("Inventory added")) {<!-- --> ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_D, (WPARAM)NM_D, (LPARAM)0); } else if (str == TEXT("Inventory Delete")) {<!-- --> ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_E, (WPARAM)NM_E, (LPARAM)0); }
7.2 Customized information processing
Process the corresponding message in the OnMyChange function of the CMainFrame framework class
LRESULT CMainFrame::OnMyChange(WPARAM wParam, LPARAM lParam) {<!-- --> switch(wParam) {<!-- --> case NM_A: MessageBox(_T("NM_A")); break; case NM_B: MessageBox(_T("NM_B")); break; case NM_C: MessageBox(_T("NM_C")); break; case NM_D: MessageBox(_T("NM_D")); break; case NM_E: MessageBox(_T("NM_E")); break; default: MessageBox(_T("error")); } return 0; }
7.3 Interface mounting
If it is the NM_A signal, the CUserDlg window is mounted, and the subsequent interfaces are mounted in the same way.
CCreateContext Context; switch(wParam) {<!-- --> case NM_A: {<!-- --> //CUserDlg class needs to include the header file #include "UserDlg.h" Context.m_pNewViewClass = RUNTIME_CLASS(CUserDlg); Context.m_pCurrentFrame = this; Context.m_pLastView = (CFormView *)m_spliter.GetPane(0, 1); m_spliter.DeleteView(0, 1); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CUserDlg), CSize(600,500), & amp;Context); CUserDlg *pNewView = (CUserDlg *)m_spliter.GetPane(0, 1); m_spliter.RecalcLayout(); pNewView->OnInitialUpdate(); m_spliter.SetActivePane(0, 1); } break; case NM_B: //…………
The program runs as follows: