| 网站首页 | 技术文章 | 下载频道 | 博客 | 编程论坛 |
 
| 技术教程首页 | 开发语言 | WEB开发 | .NET技术 | 数据库 | 操作系统 | 网页制作 |
 
 
您现在的位置: 编程中国 >> 技术教程 >> 开发语言 >> VC++ >> VC技术资料 >> 正文
  ►  VC++联接数据库SQL2000应用实例及登陆退出(较全)
VC++联接数据库SQL2000应用实例及登陆退出(较全)
作者:赵博闻    阅读人次:……    文章来源:本站原创    发布时间:2007/10/30    网友评论()条
 

原帖及讨论:http://bbs.bccn.net/thread-181679-1-1.html

*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国  http://www.bccn.net
*/ 作者: 赵博闻        
*/ 时间: 2007-10-29  编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------


我自己做了个用SQL2000联接的例子,请大家帮我看看,有什么不足还望指教。如能得到您的点滴指点
都将万分感谢。

这个例子现在只能操作一张表,要想操作整个库也不难,就是改SQL语句,然后配好数据库,建议使用存储过程

正文:

简易数据库系统

第一部分:用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;  
    }
    // 判断所选项是否位于行首
    if (m_nIndex == 0) {
        MessageBox("已经位于第一行了!","请注意",MB_ICONINFORMATION);
        return;  
    }

    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);
    
    m_List.DeleteItem(m_nIndex);
    m_List.InsertItem(m_nIndex,strMusicName);
    m_List.SetItemText(m_nIndex,1,strSomeOne);
    m_List.SetItemText(m_nIndex,2,strSomeThing);
    m_nIndex--;

    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);

    // 使得m_nIndex-1位置处项目高亮显示并获得焦点
    UINT flag = LVIS_SELECTED|LVIS_FOCUSED;
    m_List.SetItemState(m_nIndex, flag, flag);
}

void CADOAccessDlg::OnBtnDown()
{
    // TODO: Add your control notification handler code here
    //向下移动
    m_List.SetFocus();
    if (m_nIndex == -1) {
        MessageBox("请选择一行再上移!","请注意",MB_ICONINFORMATION);
        return;  
    }
    // 判断所选项是否位于行首
    if (m_nIndex == m_List.GetItemCount()-1) {
        MessageBox("已经位于最后一行了!","请注意",MB_ICONINFORMATION);
        return;  
    }
    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);
    
    m_List.DeleteItem(m_nIndex);
    m_List.InsertItem(m_nIndex,strMusicName);
    m_List.SetItemText(m_nIndex,1,strSomeOne);
    m_List.SetItemText(m_nIndex,2,strSomeThing);
    m_nIndex++;
    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);
    //显示高亮得到焦点
    UINT falg = LVIS_SELECTED|LVIS_FOCUSED;
    m_List.SetItemState(m_nIndex,falg,falg);
}
第五部分:登录
    
实质:1取得信息,验证,并存于相应变量。2在ini文件中存入这些变量。3调用命令函数查询数据库看是否通过。
给出核心代码,其余请参看源代码
void LogINDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
    CDialog::OnShowWindow(bShow, nStatus);
    
    // TODO: Add your message handler code here
    CFileStatus Status;//文件身份
    CString str;//“关闭”按钮文字
    static CRect RtSmall;
    if (CFile::GetStatus(".\\MyDB.ini",Status))
    {
        this->OnBtnCloseORMore();

        m_SQLDomainName = m_Inif.GetSQLServerIPORName();
        m_strSQLUserName = m_Inif.GetSQLServerUserName();
        m_strSQLPassword = m_Inif.GetSQLServerPassWord();
        if (m_strUserName == "") {
            m_Save = false;// m_Save是CheckBox的变量
        }
        else
        {
            m_Save = true;
        }
        CString ifFind;
        ifFind = m_SQLDomainName;
        if (!ifFind.IsEmpty()) {
            m_Save =true;
        }
        UpdateData(false);
    }
}
1登录
void LogINDlg::OnBtnOK()
{
    // TODO: Add your control notification handler code here
    if (!IsEmpty())
    {
        m_Inif.SetSQLServerIP(m_SQLDomainName);
        m_Inif.SetSQLServerUserName(m_strSQLUserName);
        m_Inif.SetSQLServerPassword(m_strSQLPassword);
        if (m_Save) {
            m_Inif.SetUserName(m_strUserName);
            m_Inif.SetPassWord(m_strPassWord);
        }
        else
        {
            m_Inif.SetUserName("");
            m_Inif.SetPassWord("");
        }
        //连接数据库
        CString strSQL;
        strSQL.Format("Provider=SQLOLEDB;server=%s;uid=%s;pwd=%s;database=MidoText",
            m_SQLDomainName,m_strSQLUserName,m_strSQLPassword);
        try
        {
            theApp.m_pConnection->Open((_bstr_t)strSQL,"","",NULL);
            
        }
        catch (_com_error e)
        {
            AfxMessageBox("连接SQL Server失败!");
            return;
        }
        UpdateData(true);
        CString strSelect;
        strSelect.Format("Select * From UserINIF Where UserName='%s' And \
            PassWord='%s' And UserKind=1",m_strUserName,m_strPassWord);
        m_pRecordset.CreateInstance(__uuidof(Recordset));
        try
        {
            m_pRecordset->Open((_bstr_t)strSelect,theApp.m_pConnection.GetInterfacePtr(),
                adOpenDynamic,
                adLockOptimistic,
                adCmdText);
        }
        catch (_com_error e)
        {
            AfxMessageBox(e.ErrorMessage());
            return;
        }
        _variant_t var;
        CString strUserName;
        if (!m_pRecordset->adoEOF)
        {
            theApp.LoginFlag = true;
            theApp.UserName = strUserName;
            m_pRecordset->Close();
            CDialog::OnOK();
        }
        else
        {
            m_pRecordset->Close();
            theApp.m_pConnection->Close();
            AfxMessageBox("登陆失败!");
        }    
    }
}

2详细…
void LogINDlg::OnBtnCloseORMore()
{
    // TODO: Add your control notification handler code here
    //改变文字
    CString str;
    if (GetDlgItemText(IDC_BtnCloseORMore,str),str=="关闭...") {
        SetDlgItemText(IDC_BtnCloseORMore,"详细...");
    }
    else
    {
        SetDlgItemText(IDC_BtnCloseORMore,"关闭...");
    }
    //开辟对话框区域
    static CRect RtLarger;
    static CRect RtSmall;
    if (RtLarger.IsRectEmpty())
    {
        //可变区域
        CRect temp;
        GetWindowRect(&RtLarger);
        GetDlgItem(IDC_STATIC_Span)->GetWindowRect(&temp);//设定分界线以下为可变区域
        //设置可变区域大小
        RtSmall.left = RtLarger.left;
        RtSmall.right = RtLarger.right;
        RtSmall.top = RtLarger.top;
        RtSmall.bottom = temp.bottom;
    }
    //按钮上显示“关闭。。。”时不显示附加区域
    if (str=="关闭...") {
        SetWindowPos(NULL,0,0,RtSmall.Width(),RtSmall.Height(),
            SWP_NOMOVE | SWP_NOZORDER);//不改变当前的大小和位置
    }
    else
    {
        SetWindowPos(NULL,0,0,RtLarger.Width(),RtLarger.Height(),
            SWP_NOMOVE | SWP_NOZORDER);
    }
}
第六部分 退出

软件要退出时应该有个退出界面,让用户确认是否真的要退出
效果图

步骤:
1在主干文件中定义退出变量,就是和工程同名的那个文件我的是ObjectPlayer。Cpp
Public:
BOOL ExitFlag;//退出标志符
2建立基于退出对话框的相关类,因为要用到程序对象App,所以在程序开始处引用对象extern CObjectPlayerApp theApp;
填写相应方法
void ExitDlg::OnOK()
{
    // TODO: Add extra validation here
    theApp.ExitFlag = TRUE;
    CDialog::OnOK();
}

void ExitDlg::OnCancel()
{
    // TODO: Add extra cleanup here
    theApp.ExitFlag = false;
    CDialog::OnCancel();
}
3在需要调用该对话框的文件中(.cpp)引入#include "ExitDlg.h"
extern CObjectPlayerApp theApp;
调用WM_Close消息
void CObjectPlayerDlg::OnClose()
{
    // TODO: Add your message handler code here and/or call default
    ExitDlg dlgExit;
    dlgExit.DoModal();//调用对话框
    if (theApp.ExitFlag) //判断标志位
    {
        CDialog::OnClose();
    }
}

 

 
文章录入:编辑01    责任编辑:编辑01 
  • 上一篇文章:

  • 下一篇文章:

  •  
    相关文章
    原创地带
    24小时热门帖子