博客剛開始寫,還不太完善,但願各位看官能夠多提意見,全部代碼都是測試經過能夠跑起來的,若是遇到什麼問題能夠留言。數據庫
首先看一下程序運行的效果:編程
我的信息管理界面:框架
右鍵菜單有增長、修改,點擊就到了我的信息界面:編程語言
接下來看一下是怎麼實現的:函數
(1)信息管理界面用到了一個表格控件list Control,還用到了右鍵菜單測試
***********PersonalInformationTabDlg.h*********** #pragma once #include "afxwin.h" #include "afxcmn.h" class ConnectDB; // 我的信息管理對話框 class PersonalInformationTabDlg : public CDialogEx { DECLARE_DYNAMIC(PersonalInformationTabDlg) public: PersonalInformationTabDlg(CWnd* pParent = NULL); // 標準構造函數 virtual ~PersonalInformationTabDlg(); // 對話框數據 enum { IDD = IDD_PERSONALINFOTABDLG }; protected: HICON m_hIcon; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 //初始化tab afx_msg LRESULT OnInitdialog(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() private: //tab對象 CListCtrl m_tabPersonalInfo; int m_nMaxID; public: //彈出右鍵菜單 afx_msg void OnNMRClickList3(NMHDR *pNMHDR, LRESULT *pResult); //添加 afx_msg void OnMenuClickedAdd(); //修改 afx_msg void OnMenuClickChange(); //刪除 afx_msg void OnMenuClickDelete(); private: bool _seleteDB(); };
***********PersonalInformationTabDlg.cpp*********** #include "stdafx.h" #include "PersonalInformation.h" #include "PersonalInformationTabDlg.h" #include "afxdialogex.h" #include "PersonalInformationDlg.h" #include "ConnectDB.h" // PersonalInformationTabDlg 對話框 IMPLEMENT_DYNAMIC(PersonalInformationTabDlg, CDialogEx) PersonalInformationTabDlg::PersonalInformationTabDlg(CWnd* pParent /*=NULL*/) : CDialogEx(PersonalInformationTabDlg::IDD, pParent) { m_nMaxID = 0; } PersonalInformationTabDlg::~PersonalInformationTabDlg() { } void PersonalInformationTabDlg::DoDataExchange(CDataExchange* pDX) { //添加變量 CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST3, m_tabPersonalInfo); } //添加事件處理程序 BEGIN_MESSAGE_MAP(PersonalInformationTabDlg, CDialogEx) ON_MESSAGE(WM_INITDIALOG, &PersonalInformationTabDlg::OnInitdialog) ON_WM_RBUTTONDOWN() ON_COMMAND(ID_32771, &PersonalInformationTabDlg::OnMenuClickedAdd) ON_NOTIFY(NM_RCLICK, IDC_LIST3, &PersonalInformationTabDlg::OnNMRClickList3) ON_COMMAND(ID_32772, &PersonalInformationTabDlg::OnMenuClickChange) ON_COMMAND(ID_32773, &PersonalInformationTabDlg::OnMenuClickDelete) END_MESSAGE_MAP() // PersonalInformationTabDlg 消息處理程序 afx_msg LRESULT PersonalInformationTabDlg::OnInitdialog(WPARAM wParam, LPARAM lParam) { CDialogEx::OnInitDialog(); // 將「關於...」菜單項添加到系統菜單中。 // IDM_ABOUTBOX 必須在系統命令範圍內。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動 // 執行此操做 SetIcon(m_hIcon, TRUE); // 設置大圖標 SetIcon(m_hIcon, FALSE); // 設置小圖標 CRect rect; // 獲取編程語言列表視圖控件的位置和大小 m_tabPersonalInfo.GetClientRect(&rect); // 爲列表視圖控件添加全行選中和柵格風格 m_tabPersonalInfo.SetExtendedStyle(m_tabPersonalInfo.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); // 爲列表視圖控件添加四列 m_tabPersonalInfo.InsertColumn(0, _T("編號"), LVCFMT_CENTER, rect.Width()/5, 0); m_tabPersonalInfo.InsertColumn(1, _T("姓名"), LVCFMT_CENTER, rect.Width()/5, 1); m_tabPersonalInfo.InsertColumn(2, _T("年齡"), LVCFMT_CENTER, rect.Width()/5, 2); m_tabPersonalInfo.InsertColumn(3, _T("性別"), LVCFMT_CENTER, rect.Width()/5, 3); m_tabPersonalInfo.InsertColumn(4, _T("愛好"), LVCFMT_CENTER, rect.Width()/5, 4); m_tabPersonalInfo.SetColumnWidth(0,40); m_tabPersonalInfo.SetColumnWidth(1,80); m_tabPersonalInfo.SetColumnWidth(2,80); m_tabPersonalInfo.SetColumnWidth(3,80); m_tabPersonalInfo.SetColumnWidth(4,200); _seleteDB(); return 0; } bool PersonalInformationTabDlg::_seleteDB() { bool bSuccessed = false; CDatabase * pDatabase = NULL; // 數據庫 CRecordset * pRecSet = NULL; // 記錄集 bSuccessed = ConnectDB::getInstance()->connectDB(pDatabase, pRecSet); if (!bSuccessed) { return false; MessageBox(_T("創建數據庫鏈接失敗!"), _T("提示框"), MB_OK | MB_ICONHAND); } int nAge = 0; int nID = 0; CString strName, strSex, strAge, strHobby, strID; CDBVariant var; // 字段類型 BOOL b = pRecSet->Open(AFX_DAO_USE_DEFAULT_TYPE, _T("SELECT * FROM PERSONALINFO"), NULL); int nIndex = 0 ; while(!pRecSet->IsEOF()) // 有沒有到表結尾 { pRecSet->GetFieldValue(L"ID", var); nID = var.m_iVal; strID.Format(L"%d", nID); m_tabPersonalInfo.InsertItem(nIndex, strID); pRecSet->GetFieldValue(L"姓名", var); strName = *(var.m_pstring); m_tabPersonalInfo.SetItemText(nIndex, 1, strName); pRecSet->GetFieldValue(L"年齡", var); nAge = var.m_iVal; strAge.Format(L"%d", nAge); m_tabPersonalInfo.SetItemText(nIndex, 2, strAge); pRecSet->GetFieldValue(L"性別", var); strSex = *(var.m_pstring); m_tabPersonalInfo.SetItemText(nIndex, 3, strSex); pRecSet->GetFieldValue(L"愛好", var); strHobby = *(var.m_pstring); m_tabPersonalInfo.SetItemText(nIndex, 4, strHobby); pRecSet->MoveNext(); ++nIndex ; } m_nMaxID = nID; pRecSet->Close(); return bSuccessed; } void PersonalInformationTabDlg::OnMenuClickedAdd() { // 增長 INT_PTR nRes; // 用於保存DoModal函數的返回值 PersonalInforData stuData; stuData.m_stuFlag = -1; stuData.m_stuID = m_nMaxID + 1; CPersonalInformationDlg dlg( stuData); // 定義對話框類CAdditionDlg的對象dlg nRes = dlg.DoModal(); // 彈出對話框dlg if (nRes == IDOK) // 判斷返回值是否爲OK按鈕(其ID爲IDOK) { //肯定 // TODO: 在此放置處理什麼時候用 // 「肯定」來關閉對話框的代碼 } else if (nRes == IDCANCEL) // 判斷返回值是否爲Cancel按鈕(其ID爲IDCANCEL) { //取消 // TODO: 在此放置處理什麼時候用 // 「取消」來關閉對話框的代碼 return; } CString strAge; CString strCurID; stuData = dlg.getStructData(); strCurID.Format (L"%d",m_nMaxID + 1); m_tabPersonalInfo.InsertItem(m_nMaxID, strCurID); m_tabPersonalInfo.SetItemText(m_nMaxID, 1, stuData.m_stuName); m_tabPersonalInfo.SetItemText(m_nMaxID, 3, stuData.m_stuSex); strAge.Format(L"%d", stuData.m_stuAge); m_tabPersonalInfo.SetItemText(m_nMaxID, 2, strAge); m_tabPersonalInfo.SetItemText(m_nMaxID, 4, stuData.m_stuHobby); m_nMaxID ++; } void PersonalInformationTabDlg::OnNMRClickList3(NMHDR *pNMHDR, LRESULT *pResult) { // 右鍵菜單 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); *pResult = 0; POINT point; GetCursorPos(&point); ScreenToClient(&point); if (point.x == -1 && point.y == -1) //判斷是否在窗口外面 { CRect rect; m_tabPersonalInfo.GetClientRect(rect); //獲得窗口客戶區的大小 m_tabPersonalInfo.ClientToScreen(rect); //轉化爲屏幕座標 point = rect.TopLeft();//獲取左上角座標 //point.Offset(5, 5); //座標偏移5,5 } CMenu menu;//聲明菜單對象 menu.LoadMenu(IDR_MENU1);//從應用程序的可執行文件中加載菜單資源 CMenu* pPopup ; pPopup= menu.GetSubMenu(0); //得到第一個彈出菜單的指針,也就是菜單中的第一個彈出菜單 // 將座標值由客戶座標轉換爲屏幕座標 ClientToScreen(&point); ASSERT(pPopup != NULL); //p斷言不爲空 CWnd* pWndPopupOwner = this;//當前類的指針 //下面就是彈出菜單 pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner); } void PersonalInformationTabDlg::OnMenuClickChange() { // 修改 PersonalInforData stuData ; int istat=m_tabPersonalInfo.GetSelectionMark(); stuData.m_stuFlag = 0; stuData.m_stuID = StrToInt(m_tabPersonalInfo.GetItemText(istat,0)); stuData.m_stuName = m_tabPersonalInfo.GetItemText(istat,1); stuData.m_stuAge = StrToInt(m_tabPersonalInfo.GetItemText(istat,2)); stuData.m_stuSex = m_tabPersonalInfo.GetItemText(istat,3); stuData.m_stuHobby = m_tabPersonalInfo.GetItemText(istat,4); INT_PTR nRes; CPersonalInformationDlg dlg( stuData); // 定義對話框類CAdditionDlg的對象dlg nRes = dlg.DoModal(); // 彈出對話框dlg CString strCurID; CString strAge; stuData = dlg.getStructData(); strCurID.Format (L"%d",stuData.m_stuID); m_tabPersonalInfo.SetItemText(stuData.m_stuID - 1, 1, stuData.m_stuName); m_tabPersonalInfo.SetItemText(stuData.m_stuID - 1, 3, stuData.m_stuSex); strAge.Format(L"%d", stuData.m_stuAge); m_tabPersonalInfo.SetItemText(stuData.m_stuID - 1, 2, strAge); m_tabPersonalInfo.SetItemText(stuData.m_stuID - 1, 4, stuData.m_stuHobby); } void PersonalInformationTabDlg::OnMenuClickDelete() { // 刪除 int nSel=m_listCoord.GetSelectionMark(); m_listCoord.DeleteItem(nSel); }
(2)信息界面用到了Static Text ,Edit Control ,Radio Button等this
***********PersonalInformationDlg.h*********** #pragma once #include "afxwin.h" class ConnectDB; struct PersonalInforData { int m_stuFlag; //-1爲增長,0爲修改 CString m_stuName ; int m_stuAge ; CString m_stuSex ; CString m_stuHobby; int m_stuID; }; // 我的信息 對話框 class CPersonalInformationDlg : public CDialogEx { // 構造 public: CPersonalInformationDlg( PersonalInforData stuData, CWnd* pParent = NULL); // 標準構造函數 ~CPersonalInformationDlg(); // 對話框數據 enum { IDD = IDD_PERSONALINFODLG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 實現 protected: HICON m_hIcon; // 生成的消息映射函數 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: afx_msg void OnEnChangeEdit1(); afx_msg void OnBnClickedOk(); private: CEdit m_edtName; //姓名 CEdit m_edtAge; //年齡s CEdit m_edtHobby; //我的愛好 CButton m_btnWoman; //女 CButton m_btnMan; //男 PersonalInforData m_stuData; private: bool _saveDataToDB(CString strName, int nAge, CString strHobby, bool bIsWoman);//保存數據到數據庫 void saveStructData(); public: PersonalInforData getStructData(); };
***********PersonalInformationDlg.cpp*********** #include "stdafx.h" #include "PersonalInformation.h" #include "PersonalInformationDlg.h" #include "afxdialogex.h" #include "ConnectDB.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用於應用程序「關於」菜單項的 CAboutDlg 對話框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 對話框數據 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 實現 protected: DECLARE_MESSAGE_MAP() public: afx_msg void add(); afx_msg void OnMenuClickedAdd(); }; CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CMFC_PersonalInformationDlg 對話框 CPersonalInformationDlg::CPersonalInformationDlg(PersonalInforData stuData, CWnd * pParent /*=NULL*/) : CDialogEx(CPersonalInformationDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_stuData = stuData; } CPersonalInformationDlg::~CPersonalInformationDlg() { } void CPersonalInformationDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT1, m_edtName); DDX_Control(pDX, IDC_EDIT2, m_edtAge); DDX_Control(pDX, IDC_EDIT3, m_edtHobby); DDX_Control(pDX, IDC_RADIO1, m_btnWoman); DDX_Control(pDX, IDC_RADIO2, m_btnMan); } BEGIN_MESSAGE_MAP(CPersonalInformationDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDOK, &CPersonalInformationDlg::OnBnClickedOk) END_MESSAGE_MAP() // CMFC_PersonalInformationDlg 消息處理程序 BOOL CPersonalInformationDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 將「關於...」菜單項添加到系統菜單中。 // IDM_ABOUTBOX 必須在系統命令範圍內。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動 // 執行此操做 SetIcon(m_hIcon, TRUE); // 設置大圖標 SetIcon(m_hIcon, FALSE); // 設置小圖標 // TODO: 在此添加額外的初始化代碼 if (-1 != m_stuData.m_stuFlag) { m_edtName.ReplaceSel(m_stuData.m_stuName); m_edtHobby.ReplaceSel(m_stuData.m_stuHobby); CString strAge ; strAge.Format(_T("%d"),m_stuData.m_stuAge); ; m_edtAge.ReplaceSel(strAge); if (m_stuData.m_stuSex == "女") { CheckDlgButton(IDC_RADIO1, 1); } else { CheckDlgButton(IDC_RADIO2, 1); } //m_btnWoman.ReplaceSel(stuData.m_stuName); } return TRUE; // 除非將焦點設置到控件,不然返回 TRUE } void CPersonalInformationDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 若是向對話框添加最小化按鈕,則須要下面的代碼 // 來繪製該圖標。對於使用文檔/視圖模型的 MFC 應用程序, // 這將由框架自動完成。 void CPersonalInformationDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用於繪製的設備上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使圖標在工做區矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 繪製圖標 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //當用戶拖動最小化窗口時系統調用此函數取得光標 //顯示。 HCURSOR CPersonalInformationDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CPersonalInformationDlg::OnBnClickedOk() { INT_PTR nRes; CString strName; GetDlgItemText(IDC_EDIT1,strName); if (strName == "" ) { // 顯示消息對話框 nRes = MessageBox(_T("名字不能爲空,請您將信息填寫完整"), _T("提示框"), MB_OK | MB_ICONHAND ); return; } CString strHobby; GetDlgItemText(IDC_EDIT3,strHobby); if (strHobby == "") { // 顯示消息對話框 nRes = MessageBox(_T("愛好不能爲空,請您將信息填寫完整"), _T("提示框"), MB_OK | MB_ICONHAND ); return; } bool bIsWoman = false; if (!(m_btnMan.GetCheck() || m_btnWoman.GetCheck())) { // 顯示消息對話框 nRes = MessageBox(_T("性別不能爲空,請您將信息填寫完整"), _T("提示框"), MB_OK | MB_ICONHAND ); return; } if (m_btnWoman.GetCheck()) { bIsWoman = true; } CString strAge; GetDlgItemText(IDC_EDIT2,strAge); if (strAge == "") { // 顯示消息對話框 nRes = MessageBox(_T("年齡不能爲空,請您將信息填寫完整"), _T("提示框"), MB_OK | MB_ICONHAND ); return; } int nAge = StrToInt(strAge); if (nAge < 0 || nAge > 120 ) { // 顯示消息對話框 nRes = MessageBox(_T("年齡輸入不合法,請您從新輸入"), _T("提示框"), MB_OK | MB_ICONHAND ); return; } saveStructData(); _saveDataToDB(strName, nAge, strHobby, bIsWoman); // TODO: 在此添加控件通知處理程序代碼 CDialogEx::OnOK(); } bool CPersonalInformationDlg::_saveDataToDB(CString strName, int nAge, CString strHobby, bool bIsWoman) { bool bSuccessed = false; CDatabase * pDatabase = NULL; // 數據庫 CRecordset * pRecSet = NULL; // 記錄集 bSuccessed = ConnectDB::getInstance()->connectDB(pDatabase, pRecSet); if (!bSuccessed) { return false; MessageBox(_T("創建數據庫鏈接失敗!"), _T("提示框"), MB_OK | MB_ICONHAND); } CString strSex = bIsWoman ? L"女" : L"男"; CString strSql = L""; if (-1 ==m_stuData.m_stuFlag) { //增長 strSql.Format(L"INSERT INTO PERSONALINFO(姓名, 性別, 年齡, 愛好,ID) VALUES('%s', '%s', %d, '%s',%d)", strName, strSex, nAge, strHobby,m_stuData.m_stuID); pDatabase->ExecuteSQL(strSql); } else { //修改 strSql.Format(L"UPDATE PERSONALINFO SET 姓名 = '%s', 性別 = '%s', 年齡 = %d, 愛好 = '%s' WHERE ID = %d", strName, strSex, nAge, strHobby, m_stuData.m_stuID); pDatabase->ExecuteSQL(strSql); } return true; } void CPersonalInformationDlg::saveStructData() { CString strName; CString strAge; CString strHobby; GetDlgItemText(IDC_EDIT1,strName); GetDlgItemText(IDC_EDIT2,strAge); GetDlgItemText(IDC_EDIT3,strHobby); m_stuData.m_stuName = strName; m_stuData.m_stuAge = StrToInt(strAge); m_stuData.m_stuHobby = strHobby; m_stuData.m_stuSex = m_btnWoman.GetCheck() ? L"女" : L"男"; } PersonalInforData CPersonalInformationDlg::getStructData() { return m_stuData; }
(3)數據庫鏈接,我用了一個單例指針
***********ConnectDB.h*********** #pragma once class ConnectDB { public: static ConnectDB * getInstance(); static void release(); bool connectDB(CDatabase *& pDatabase, CRecordset *& pRecSet); private: ConnectDB(); ~ConnectDB(); private: static ConnectDB * m_pInstance; CDatabase * m_pDatabase; // 數據庫 CRecordset * m_pRecSet; // 記錄集 };
***********ConnectDB.cpp*********** #include "stdafx.h" #include "ConnectDB.h" ConnectDB * ConnectDB::m_pInstance = NULL; ConnectDB::ConnectDB() { m_pDatabase = NULL; m_pRecSet = NULL; } ConnectDB::~ConnectDB(void) { //關閉記錄集及庫 m_pRecSet->Close(); m_pDatabase->Close(); if (m_pRecSet != NULL) { delete m_pRecSet; m_pRecSet = NULL; } if (m_pDatabase != NULL) { delete m_pDatabase; m_pDatabase = NULL; } } ConnectDB * ConnectDB::getInstance() { if (m_pInstance == NULL) { m_pInstance = new ConnectDB; } return m_pInstance; } void ConnectDB::release() { if (m_pInstance != NULL) { delete m_pInstance; m_pInstance = NULL; } } bool ConnectDB::connectDB(CDatabase *& pDatabase, CRecordset *& pRecSet) { BOOL bSuccessed = FALSE; if (m_pDatabase == NULL) { m_pDatabase = new CDatabase(); bSuccessed = m_pDatabase->Open(L"ODBC;DRIVER={MICROSOFT ACCESS DRIVER (*.mdb)};DSN='';DBQ=..\\Debug\\DemoDatabase.mdb"); if (!bSuccessed) { return false; } } if (m_pRecSet == NULL) { m_pRecSet = new CRecordset(m_pDatabase); bSuccessed = m_pRecSet->Open(AFX_DAO_USE_DEFAULT_TYPE, _T("SELECT * FROM PERSONALINFO"), NULL); m_pRecSet->Close(); if (!bSuccessed) { return false; } } pDatabase = m_pDatabase; pRecSet = m_pRecSet; return true; }