注意:需要创建一个txt,并把后缀改为udl,右键属性,连接你创建的数据库,测试连接后,改回txt,获取其中字符串。
创建MFC项目->基于对话框
这里创建的项目名称为Test
在 stdafx.h 添加以下代码:
#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF" , "adoEOF") rename("BOF", "adoBOF")
注意要在一行内,分多行需在行末加 " \ "
在 Test.h 中的 public 添加以下代码:
_ConnectionPtr m_pCon;
BOOL ConnectDataBase(CString strLinkWord);
在 Test.cpp 中的 InitInstance() 函数添加以下代码:
CString strLinkWord = L"Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=StudentManagement;Data Source=DESKTOP-EDQ3AKC";
if (!ConnectDataBase(strLinkWord))
{
return FALSE;
}
AfxMessageBox(L"Succeedly!");
strLinkWord中的字符串即为你从udl中获取的字符串
并如图中添加dlg.m_pCon = m_pCon;
来传递指针
注意需在TestDlg.h 中先定义指针,不然会提示不存在m_pCon
我们之前声明了ConnectDataBase()函数,现在来定义它,在Test.cpp任意位置添加以下代码:
BOOL CTestApp::ConnectDataBase(CString strLinkWord)
{
// TODO: 在此处添加实现代码.
::CoInitialize(NULL);
if (!SUCCEEDED(m_pCon.CreateInstance(__uuidof(Connection))))
{
m_pCon = NULL;
TRACE("Failed!");
}
ASSERT(m_pCon != NULL);
try
{
return SUCCEEDED(m_pCon->Open(_bstr_t(strLinkWord), _bstr_t(L""), _bstr_t(L""), adModeUnknown));
}
catch (_com_error & e)
{
CString str;
str.Format(L"%s\n", e.ErrorMessage());
AfxMessageBox(str);
return FALSE;
}
}
注意CTestApp改为你自己创建项目的名字
在 TestDlg.h 中的 public 添加以下代码:
_ConnectionPtr m_pCon;
_RecordsetPtr m_pRec;
_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
BOOL GetCollect(LPCTSTR Name,_variant_t& OutCol);
CString m_sno;//学号
CString m_pw;//密码
如果指针m_pCon在之前那步定义了,这里就不用重复定义
先在 TestDlg.cpp 中定义声明的两个函数:
_RecordsetPtr CTestDlg::DBRecordSetGet(LPCTSTR Sql)
{
// TODO: 在此处添加实现代码.
m_pRec.CreateInstance("ADODB.Recordset");
m_pRec = m_pCon->Execute((_bstr_t)Sql, NULL, adCmdText);
return m_pRec;
//return _RecordsetPtr();
}
BOOL CTestDlg::GetCollect(LPCTSTR Name, _variant_t& OutCol)
{
// TODO: 在此处添加实现代码
_variant_t vt;
vt = m_pRec->GetCollect(Name);
if (vt.vt != VT_NULL) {
OutCol = vt;
return TRUE;
}
else
return FALSE;
}
在对话框中添加2个 Edit Control
双击确定按钮,创建Button函数,添加以下代码:
GetDlgItemText(IDC_EDIT1, m_sno);
GetDlgItemText(IDC_EDIT2, m_pw);
CString sql;
sql.Format(L"exec Login '%s','%s'", m_sno, m_pw);//存储过程
m_pRec = DBRecordSetGet(sql);
_variant_t var;
GetCollect(L"cnt", var);//cnt 与你创建的存储过程里的名称对应
int temp = var.intVal;
if (temp == 1)
{
Info dlg;
dlg.m_pCon = m_pCon;
dlg.m_sno = m_sno;
dlg.DoModal();
}
else
MessageBox(L"Error!");
这里用到了 学生信息对话框,所以需先在 资源视图 插入 新对话框,并右键对话框,添加类:Info.h
Info.h 中一样要先定义指针和学号,不过你可以先忽略红色警告,在后面步骤中再添加
在 TestDlg.cpp 中引入#include"Info.h"
将学生信息对话框做如下布局:
Edit Control 修改一下属性,可以改成无边框背景,列表为 List Control
上面代码中用到了存储过程,我们得先去SSMS创建存储过程:
create procedure Login
@sno char(5),@pw varchar(20)
as
select COUNT(*) as cnt from S
where 学号=@sno and 密码=@pw
在 Info.h 的 public 中添加:
CString m_sno;
_ConnectionPtr m_pCon;
_RecordsetPtr m_pRec;
_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
BOOL GetCollect(LPCTSTR Name, _variant_t& OutCol);
注意所有对话框都用到了上面声明的2个函数,都需要在相应cpp中定义:
_RecordsetPtr CTestDlg::DBRecordSetGet(LPCTSTR Sql)
{
// TODO: 在此处添加实现代码.
m_pRec.CreateInstance("ADODB.Recordset");
m_pRec = m_pCon->Execute((_bstr_t)Sql, NULL, adCmdText);
return m_pRec;
//return _RecordsetPtr();
}
BOOL CTestDlg::GetCollect(LPCTSTR Name, _variant_t& OutCol)
{
// TODO: 在此处添加实现代码
_variant_t vt;
vt = m_pRec->GetCollect(Name);
if (vt.vt != VT_NULL) {
OutCol = vt;
return TRUE;
}
else
return FALSE;
}
之后就不再赘述。
在信息对话框右键->类向导->虚函数 添加OnInitDialog()
并在其中添加:
CString sql;
sql.Format(L"exec Stud '%s'", m_sno);
m_pRec = DBRecordSetGet(sql);
_variant_t var;
CString str;
str.Format(L"学号:%s", m_sno);
SetDlgItemText(IDC_EDIT1, str);
GetCollect(L"姓名", var);
CString temp = var.bstrVal;
str.Format(L"姓名:%s", temp);
SetDlgItemText(IDC_EDIT2, str);
GetCollect(L"所在系", var);
CString a = var.bstrVal;
str.Format(L"所在系:%s", a);
SetDlgItemText(IDC_EDIT3, str);
GetCollect(L"性别", var);
CString b = var.bstrVal;
str.Format(L"性别:%s", b);
SetDlgItemText(IDC_EDIT4, str);
GetCollect(L"年龄", var);
int c = var.intVal;
str.Format(L"年龄:%d", c);
SetDlgItemText(IDC_EDIT5, str);
给List Control添加变量,右键列表,变量名:m_list
并在Info.cpp 的 OnInitDialog() (就是刚刚创建的)
中添加:
m_list.ModifyStyle(LVS_ICON | LVS_SMALLICON | LVS_LIST, LVS_REPORT);
m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
m_list.InsertColumn(0, L"课程号"); m_list.InsertColumn(1, L"课程名");
m_list.InsertColumn(2, L"学时数"); m_list.InsertColumn(3, L"任课老师");
m_list.InsertColumn(4, L"成绩");
RECT rect;
m_list.GetWindowRect(&rect); int wid = (rect.right - rect.left) / 7;//wid 格宽度
m_list.SetColumnWidth(0, wid); m_list.SetColumnWidth(1, 2 * wid);
m_list.SetColumnWidth(2, wid); m_list.SetColumnWidth(3, wid);
m_list.SetColumnWidth(4, 2 * wid);
LoadData();
这里的 LoadData() 为数据加载函数,需自己创建
在 Info.h 的 public 中声明:void LoadData();
并在 Info.cpp 中添加:
void Info::LoadData()
{
// TODO: 在此处添加实现代码.
CString sql;
sql.Format(L"exec Scla '%s'", m_sno);
m_pRec = DBRecordSetGet(sql);
if (m_pRec == NULL)
return;
m_list.DeleteAllItems();
int j = 0;
while (!m_pRec->adoEOF)
{
m_list.InsertItem(j, L"");
_variant_t var;
m_list.SetItemText(j, 0, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程号"));
m_list.SetItemText(j, 1, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程名"));
m_list.SetItemText(j, 2, (LPTSTR)(_bstr_t)m_pRec->GetCollect("学时数"));
m_list.SetItemText(j, 3, (LPTSTR)(_bstr_t)m_pRec->GetCollect("任课老师"));
var = m_pRec->GetCollect("成绩");
if (var.vt != VT_NULL)
{
m_list.SetItemText(j, 4, (LPTSTR)(_bstr_t)var);
}
else
m_list.SetItemText(j, 4, TEXT(""));
m_pRec->MoveNext();
j++;
}
}
上面用到了存储过程Scla,同样得去SSMS创建:
create procedure Scla
@sno char(5)
as
select C.课程号,C.课程名,C.任课老师,C.学时数,SC.成绩
from SC,C
where C.课程号=SC.课程号 and 学号=@sno
在信息对话框添加新Button,名字改为修改密码,双击创建Button函数。
并在 资源视图 新建 修改密码对话框,添加类:Pw.h
在 Pw.h 的 public 中添加:
CString m_sno;
CString m_pw;
_ConnectionPtr m_pCon;
_RecordsetPtr m_pRec;
_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
BOOL GetCollect(LPCTSTR Name, _variant_t& OutCol);
*记得在cpp中添加那2个函数定义!
我们先回到 Info.cpp 中引入#include"Pw.h"
在 OnBnClickedButton1() 函数中,添加:
Pw dlg;
dlg.m_pCon = m_pCon;
dlg.m_sno = m_sno;
dlg.DoModal();
再回到修改密码对话框,添加 Edit Control,
双击确定按钮创建 OnBnClickedOk() ,在其中添加:
GetDlgItemText(IDC_EDIT1, m_pw);
CString sql;
sql.Format(L"exec Cpw '%s','%s'", m_sno, m_pw);
m_pRec = DBRecordSetGet(sql);
MessageBox(L"修改成功!");
上面用到存储过程:
create procedure Cpw
@sno char(5),@pw varchar(20)
as
update S
set 密码=@pw
where S.学号=@sno
在Info对话框新建按钮,双击进入Info.cpp
引入:#include"Sc.h"
并在 OnBnClickedButton2() 添加:
S dlg;
dlg.m_pCon = m_pCon;
dlg.m_sno = m_sno;
if (dlg.DoModal() == IDOK)
LoadData();
新建 选课 对话框,添加类:Sc.h
在对话框添加List Control
给List Control添加变量,右键列表,变量名:m_list
双击列表创建:OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
双击确定创建:OnBnClickedOk()
在对话框右键->类向导->虚函数 添加OnInitDialog()
在 Sc.h 的 public 中添加:
CString m_sno;
CString sel;
_ConnectionPtr m_pCon;
_RecordsetPtr m_pRec;
_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
BOOL GetCollect(LPCTSTR Name, _variant_t& OutCol);
void LoadData();
*记得在cpp中添加那2个函数定义!
添加LoadData :
void Sc::LoadData()
{
// TODO: 在此处添加实现代码.
CString sql;
sql.Format(L"exec UnScla '%s'", m_sno);
m_pRec = DBRecordSetGet(sql);
if (m_pRec == NULL)
return;
m_list.DeleteAllItems();
int j = 0;
while (!m_pRec->adoEOF)
{
m_list.InsertItem(j, L"");
_variant_t var;
m_list.SetItemText(j, 0, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程号"));
m_list.SetItemText(j, 1, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程名"));
m_list.SetItemText(j, 2, (LPTSTR)(_bstr_t)m_pRec->GetCollect("学时数"));
m_list.SetItemText(j, 3, (LPTSTR)(_bstr_t)m_pRec->GetCollect("任课老师"));
m_pRec->MoveNext();
j++;
}
}
在Sc.cpp 的 OnInitDialog() 中添加:
m_list.ModifyStyle(LVS_ICON | LVS_SMALLICON | LVS_LIST, LVS_REPORT);
m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
m_list.InsertColumn(0, L"课程号"); m_list.InsertColumn(1, L"课程名");
m_list.InsertColumn(2, L"学时数"); m_list.InsertColumn(3, L"任课老师");
RECT rect;
m_list.GetWindowRect(&rect); int wid = (rect.right - rect.left) / 7;//wid 格宽度
m_list.SetColumnWidth(0, wid); m_list.SetColumnWidth(1, 2 * wid);
m_list.SetColumnWidth(2, wid); m_list.SetColumnWidth(3, wid);
LoadData();
在Sc.cpp 的 OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult) 中添加:
int i = m_list.GetSelectionMark();
sel = m_list.GetItemText(i, 0);
在Sc.cpp 的 OnBnClickedOk() 中添加:
CString sql;
sql.Format(L"exec Ins '%s','%s'", m_sno, sel);
m_pRec = DBRecordSetGet(sql);
if (m_pRec == NULL)
return;
else
MessageBox(L"Succeed");
以上代码用到的存储过程:
create procedure UnScla
@sno char(5)
as
select 课程号,课程名,任课老师,学时数
from C
where 课程号 not in (select 课程号 from SC where 学号=@sno)
create procedure Ins
@sno char(5),@cno char(5)
as
insert into SC(学号,课程号)
values(@sno,@cno)
特别鸣谢: @czn @zyf