第一部分:用ADO连接SQL Server 2000 1 在STDafx.h中加入动态连接库msado15.dll,并重命名EOF为adoEOF,加在该文件后面(蓝色#endif后面,要是编译时有错误说明位置不对) #import "D:/Program Files/Common Files/System/ado/msado15.dll"/ no_namespace rename("EOF","adoEOF") 2 在App类中定义连接字符串。我的是CADOApp,文件是ADO.h _ConnectionPtr m_pConnection; 3 在数据操作类InitInstance()中初始化COM类库 //这就是初始化COM库 //应用程序主类的InitInstance成员函数里初始化OLE/COM库环境 if (!AfxOleInit()) { AfxMessageBox("OLE/COM初始化失败"); return FALSE; } theApp.m_pConnection.CreateInstance(__uuidof(Connection)); 要在其它操作前面初始化,我的是dlg,原来在它后面初始化的结果走不到那一步,所以m_pConnection总是为NULL/0x000000000 4 再要操作的地方初始化结果集和连接字符串,我的是在一个按钮里 void CADOAccessDlg::OnBtnExec() { m_pRecordset.CreateInstance(__uuidof(Recordset)); CString strLink;//连接字符串 try { strLink.Format("Provider=SQLOLEDB;server=ZHAOPENG;UID=sa;PWD=sa;database=MD200"); theApp.m_pConnection->Open((_bstr_t)strLink,"","",NULL); } catch(_com_error e) { AfxMessageBox("连接SQL Server失败!"); return; } //UpdateData(true); theApp.m_pConnection->Close(); } 如果要在文件中使用theApp,不要忘记在文件头部(不是头文件)加上extern CADOAccessApp theApp 以上就是连接数据库的简单方法。 第二部分:向ListCtrl中添加数据库中表的数据 1先写两个方法用于添加表头,和内容,ListCtrl要用Report格式 //初始化列表框 void CADOAccessDlg::InitReport() { m_List.InsertColumn(0,_T("音乐名称"),LVCFMT_LEFT,120,-1); m_List.InsertColumn(1,_T("作者/歌手"),LVCFMT_LEFT,90,-1); m_List.InsertColumn(2,_T("备注"),LVCFMT_LEFT,110,-1); m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT |LVS_EX_GRIDLINES); } //显示列表框里的内容,从MidoSond表中 void CADOAccessDlg::UpdataReport() { m_List.DeleteAllItems(); //查询 m_pRecordset.CreateInstance(__uuidof(Recordset)); CString strLink; try { strLink.Format("Provider=SQLOLEDB;server=ZHAOPENG;UID=sa;PWD=sa;database=MidoText"); theApp.m_pConnection->Open((_bstr_t)strLink,"","",NULL); } catch(_com_error e) { AfxMessageBox("连接SQL Server失败!"); return; } UpdateData(true); try { m_pRecordset->Open("select * from TextSond",theApp.m_pConnection.GetInterfacePtr(), adOpenDynamic,//动态 adLockOptimistic,//乐观封锁法 adCmdText);//文本查询 } catch (_com_error e) { CString strErr="Select语句执行失败!"; AfxMessageBox(e.ErrorMessage()+strErr); } _variant_t vat; CString MusicName,ZhuoZhe,SomethingAbout; CString strDomainName; while (!m_pRecordset->adoEOF) {//获取一个字段 vat = m_pRecordset->GetCollect("音乐名称"); if (vat.vt != VT_NULL) { MusicName = (LPCSTR)_bstr_t(vat); MusicName.TrimLeft();//清除左边的空格 } vat = m_pRecordset->GetCollect("作者/歌手"); if (vat.vt != VT_NULL) { ZhuoZhe = (LPCSTR)_bstr_t(vat); ZhuoZhe.TrimLeft(); } vat = m_pRecordset->GetCollect("备注"); if (vat.vt != VT_NULL) { SomethingAbout = (LPCSTR)_bstr_t(vat); SomethingAbout.TrimLeft(); } int pos,id=1; pos = m_List.InsertItem(id,strDomainName); m_List.SetItemText(pos,0,MusicName); m_List.SetItemText(pos,1,ZhuoZhe); m_List.SetItemText(pos,2,SomethingAbout); m_pRecordset->MoveNext(); } m_pRecordset->Close(); theApp.m_pConnection->Close(); } 2在ShowWindow事件中调用,因为该事件先于其它任何事件所以在这一个就建立了数据库连接(连接写在第二个方法里) void CADOAccessDlg::OnShowWindow(BOOL bShow, UINT nStatus) { CDialog::OnShowWindow(bShow, nStatus); // TODO: Add your message handler code here this->InitReport(); this->UpdataReport(); } 第三部分:添加,修改,删除 这三项功能看似简单实则重要,使操作数据库系统的核心操作,可以扩展出许多其他功能。 分析:三项功能的本质在于1检索输入设备中输入的数据合法性,将其保存到相应的变量中。2调用命令函数,对连接的数据库进行操作。3将操作结果返回到输出设备上。 我们就按照这样的思想编成,以添加功能为例说明其它给出代码 //1检索输入设备中输入的数据合法性,将其保存到相应的变量中 void CADOAccessDlg::OnBtnAdd() { //判断是否有字符输入 if (ISEmpty()) { return; } //不可以出现前两项一样的输入(正则表达式) if (ISHaveString()==false) { return; } //得到所输入的字符 BOOL IsUpdata = FALSE; DataTable = "TextSond";//数据表名字 //这里我原来想作动态建库的所遗留了变量 CString strWeather; CString strMusicName,strMen,strSomething; ((CEdit*)GetDlgItem(IDC_EdtMusicName))->GetWindowText(strMusicName); ((CEdit*)GetDlgItem(IDC_EdtZZName))->GetWindowText(strMen); ((CEdit*)GetDlgItem(IDC_EdtSomething))->GetWindowText(strSomething); //对所输入字符的合法性进行验证 if (strMusicName.GetLength()>50) { MessageBox("音乐名称不能超过50个字节!","请您注意",MB_ICONINFORMATION); return; } if (strMen.GetLength()>30) { MessageBox("作者或歌手不能超过50个字节!","请您注意",MB_ICONINFORMATION); return; } if (strSomething.GetLength()>40) { MessageBox("备注不能超过50个字节!","请您注意",MB_ICONINFORMATION); return; } //判断要添加的行是否存在,存在就更新,不存在,就追加 for (int i=0;i<m_List.GetItemCount();i++) { if (strWeather == m_List.GetItemText(i,0)) { IsUpdata = TRUE; break; } } if (IsUpdata) { CString strUpdata; strUpdata.Format("Updata '%s' set 音乐名称='%s',作者或歌手='%s',备注='%s'", DataTable,strMusicName,strMen,strSomething); _variant_t RecordAffected; theApp.m_pConnection->Execute(_bstr_t(strUpdata),&RecordAffected, adCmdText); } else { UpdateData(); m_pRecordset.CreateInstance(__uuidof(Recordset)); try { //查找所有行 CString sql; sql.Format("select * from %s", DataTable); BSTR bstrSQL = sql.AllocSysString(); m_pRecordset->Open(_bstr_t(bstrSQL), theApp.m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); } catch (_com_error e) { AfxMessageBox(e.ErrorMessage()); } //添加 m_pRecordset->AddNew(); m_pRecordset->PutCollect("音乐名称",_variant_t(strMusicName)); m_pRecordset->PutCollect("作者或歌手",_variant_t(strMen)); m_pRecordset->PutCollect("备注",_variant_t(strSomething)); m_pRecordset->Update(); m_pRecordset->Close(); } this->UpdataReport(); } BOOL CADOAccessDlg::ISEmpty() { UpdateData(TRUE); if (m_EdtMName == "") { MessageBox("请输入音乐名称!","提示",MB_ICONINFORMATION); return true; } if (m_Men == "") { MessageBox("请输入作者或歌手!","提示",MB_ICONINFORMATION); return true; } // if (m_SomeThing = "") { // MessageBox("请输入音乐名称!","提示",MB_ICONINFORMATION); // return; // } return false; } //判断编辑框里是否有字符,有择削去 BOOL CADOAccessDlg::ISHaveString() { CString strMusicName,strMen,strSomething; CString strOldName,strOldMen; ((CEdit*)GetDlgItem(IDC_EdtMusicName))->GetWindowText(strMusicName); ((CEdit*)GetDlgItem(IDC_EdtZZName))->GetWindowText(strMen); for (int i=0;i<m_List.GetItemCount();i++) { strOldName = m_List.GetItemText(i,0); strOldMen = m_List.GetItemText(i,1); if ((strMusicName==strOldName)&(strMen==strOldMen)) { AfxMessageBox("请不要重复添加记录!"); return false;//已经有了这样的字段 } } return true; } 修改 void CADOAccessDlg::OnBtnUpdate() { // TODO: Add your control notification handler code here //点击修改时将会更新数据表中的内容 if (ISEmpty()) { return; } //得到所输入的字符 BOOL IsUpdata = FALSE; CString strMusicName,strSomeOne,strSomeThing; ((CEdit*)GetDlgItem(IDC_EdtMusicName))->GetWindowText(strMusicName); ((CEdit*)GetDlgItem(IDC_EdtZZName))->GetWindowText(strSomeOne); ((CEdit*)GetDlgItem(IDC_EdtSomething))->GetWindowText(strSomeThing); //对所输入字符的合法性进行验证 if (strMusicName.GetLength()>50) { MessageBox("音乐名称不能超过50个字节!","请您注意",MB_ICONINFORMATION); return; } if (strSomeOne.GetLength()>30) { MessageBox("作者或歌手不能超过50个字节!","请您注意",MB_ICONINFORMATION); return; } if (strSomeThing.GetLength()>40) { MessageBox("备注不能超过50个字节!","请您注意",MB_ICONINFORMATION); return; } //判断是否选中了要修改的行 CString strOldName,strOldMen; strOldName = m_List.GetItemText(m_nIndex,0); strOldMen = m_List.GetItemText(m_nIndex,1); CWnd* boFocus; boFocus = m_List.GetFocus(); if (boFocus != NULL) //有焦点,先是高亮,更新 { UINT flag = LVIS_SELECTED|LVIS_FOCUSED; m_List.SetItemState(m_nIndex, flag, flag); CString strIndexName; strIndexName = m_List.GetItemText(m_nIndex,0); DataTable="TextSond"; CString strSQLUpdata; _variant_t RecordAffected; strSQLUpdata.Format("Update %s Set 音乐名称='%s',作者或歌手='%s',备注='%s' Where 音乐名称='%s' AND 作者或歌手='%s'", DataTable,strMusicName,strSomeOne,strSomeThing,strOldName,strOldMen); BSTR bstrSQL = strSQLUpdata.AllocSysString(); theApp.m_pConnection->Execute(_bstr_t(bstrSQL),&RecordAffected,adCmdText); //重新显示列表框 UpdataReport(); } else { MessageBox("请选则要修改的行!","请您注意",MB_ICONINFORMATION); return; } } 删除 void CADOAccessDlg::OnBtnDelete() { // TODO: Add your control notification handler code here CString strDelete; CString DataTable; CString MName; DataTable = "TextSond"; MName = m_List.GetItemText(m_nIndex,0); strDelete.Format("Delete %s Where 音乐名称='%s'", DataTable,MName); _variant_t RecordsAffected; theApp.m_pConnection->Execute(_bstr_t(strDelete),&RecordsAffected,adCmdText); this->UpdataReport(); } 第四部分:上下移动按钮 功能:当点击上下移动按钮时列表框中的被选中的一行会显示高亮,同时该亮度条会上移或下移一行,同时编辑框中的字段会随移动有相应变化。 如图:上移,一行 在相应的方法中添加代码 void CADOAccessDlg::OnClickListView(NMHDR* pNMHDR, LRESULT* pResult) {//在上下移动前需要制定一个起始位置 // TODO: Add your control notification handler code here POSITION pos = m_List.GetFirstSelectedItemPosition(); m_nIndex = m_List.GetNextSelectedItem(pos); // 得到项目索引 CString strMusicName,strSomeOne,strSomeThing; strMusicName = m_List.GetItemText(m_nIndex,0); strSomeOne = m_List.GetItemText(m_nIndex,1); strSomeThing = m_List.GetItemText(m_nIndex,2); ((CEdit*)GetDlgItem(IDC_EdtMusicName))->SetWindowText(strMusicName); ((CEdit*)GetDlgItem(IDC_EdtZZName))->SetWindowText(strSomeOne); ((CEdit*)GetDlgItem(IDC_EdtSomething))->SetWindowText(strSomeThing); if (m_nIndex != -1) { // m_List.SetFocus(); } *pResult = 0; } void CADOAccessDlg::OnBtnUp() { // TODO: Add your control notification handler code here //向上移动 m_List.SetFocus(); if (m_nIndex == -1) { MessageBox("请选择一行再上移!","请注意",MB_ICONINFORMATION); return; }