当前位置:松语文学 > 其他类型 >VC++_6.0程序设计从入门到精通最新章节 > VC++_6.0程序设计从入门到精通TXT下载
错误举报

第 72 章

  Edit 控件1 IDC_CONNECTION_STRING

  Edit 控件2 IDC_EXECUTE_STRING

  按钮控件1 IDC_SOURCE 数据源

  按钮控件2 IDC_CONNECT 连接

  按钮控件3 IDC_EXECUTE cāo作

  按钮控件4 IDC_DISCONNECT 断开

  按钮控件5 IDC_QUIT 退出

  枫叶文学网www.fywxw.com

  第12 章 数据库开发

  ·359·

  4.编写代码

  在正式开始编写代码之前,需要进一步明确此程序要实现的功能。用户单击“数据源”

  按钮,则可以利用COM 组件DataSourceLocator 动态设置数据源,同时在Edit 控件1 中将连

  接串显示出来。设定数据源后,用户单击“连接”按钮,程序连接到数据源,同时在List Box

  控件中将数据库中所有表名都显示出来。然后用户可以在Edit 控件2 中输入SQL 语句,单

  击“cāo作”按钮对数据库进行cāo作。当cāo作完毕后,单击“断开”按钮断开与数据源的连接。

  最后单击“退出”按钮退出程序界面。同时为了方便用户,程序增加了两个功能。当用户在

  List Box 控件中单击某个表名时,在DataGrid 控件中会相应的显示出此表的所有记录;当用

  户在DataGrid 控件中表的某列单击时,此列按照升序进行排列,再次单击此列,则降序排列。

  注意:为了让程序更加简洁,本节在介绍cāo作数据库时,没有利用12.6.4 小节介绍的对数据库记

  录进行cāo作的方法,而是直接用SQL 语句cāo作。读者也可以根据12.6.4 小节所讲内容自己

  编写cāo作记录的代码。

  (1)初始化变量

  首先在文件“CAdoTestView.h ” 的开头加入语句#include "datagrid.h" , 然后为类

  CAdoTestView 添加如表12-25 所示的成员变量,它们都是public 成员变量。

  表12-25 类CAdoTestView 成员变量表

  成员变量 功能

  _ConnectionPtr m_Connection 连接数据源

  _RecordsetPtr m_Recordset 打开记录集

  CListBox m_ListBox 与控件List Box 关联

  CDataGrid m_DataGrid 与控件DataGrid 关联

  CString m_strConnection 连接串,与Edit 控件1 关联

  CString m_strSQL 对数据库cāo作的SQL 语句,与Edit 控件2 关联

  CString m_strTableNcom 表名

  BOOL isDesc 是否降序排列

  然后在CAdoTestView 类的构造函数中先进行一些初始化工作,代码如下:

  CAdoTestView::CAdoTestView()

  : CFormView(CAdoTestView::IDD)

  {

  //{{AFX_DATA_INIT(CAdoTestView)

  // NOTE: the ClassWizard will addcommber initialization here

  //}}AFX_DATA_INIT

  // TODO: add construction code here

  m_strConnection = _T("");

  m_strSQL = _T("");

  m_strTableNcom = _T("");

  isDesc = FALSE;

  }

  最后要将各控件和它们对应的变量关联起来,代码如下:

  void CAdoTestView::DoDataExchange(CDataExchange* pDX)

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·360·

  {

  CFormView::DoDataExchange(pDX);

  //{{AFX_DATA_MAP(CAdoTestView)

  // NOTE: the ClassWizard will add DDX and DDV calls here

  //}}AFX_DATA_MAP

  DDX_Control(pDX, IDC_LISTBOX, m_strListBox);

  DDX_Control(pDX, IDC_DATAGRID, m_strDataGrid);

  DDX_Text(pDX, IDC_CONNECTION_STRING, m_strConnection);

  DDX_Text(pDX, IDC_EXECUTE_STRING, m_strSQL);

  }

  (2)编写各消息响应函数

  前面已经说过,在编写ADO 的程序时,要用try 和catch,否则ADO 调用错误有可能使

  程序崩溃,一定要随时记得捕捉_com_error 例外以及其他错误。因此首先编写捕获例外时的

  处理函数。为类CAdoTestView 添加public 成员函数void GenerateError(HRESULT hr, PWSTR

  pwszDescription),代码如下:

  void CAdoTestView::GenerateError(HRESULT hr, PWSTR pwszDescription)

  {

  CString m_strError;

  m_strError.Format("Run-tcom error ’%d (%x)’", hr, hr);

  m_strError += "\n\r";

  m_strError += pwszDescription;

  AfxMessageBox(m_strError);

  }

  接下来为各个按钮添加响应函数。首先为用来设定数据源的按钮添加响应函数:打开

  “ClassWizard”对话框,在“Class ncom”下拉菜单中选择CAdoTestView,在Object IDs 下

  拉列表中选择IDC_SOURCE,在“Messages”下拉列表中选择BN_CLICKED,单击“Add

  Function”,采用默认的函数名,然后依次单击“OK”和“Edit Code”按钮,定位到函数

  CAdoTestView::OnSource(),代码如下:

  void CAdoTestView::OnSource()

  {

  // TODO: Add your control notification handler code here

  // TODO: Add your control notification handler code here

  HRESULT hr;

  IDataSourceLocatorPtr m_dlPrompt = NULL;

  _ConnectionPtr m_Conn = NULL;

  //初始化COM

  ::CoInitialize(NULL);

  枫叶文学网www.fywxw.com

  第12 章 数据库开发

  ·361·

  //创建IDataSourceLocatorPtr 的实例

  hr = m_dlPrompt.CreateInstance(__uuidof(DataLinks));

  //弹出数据连接的对话框

  m_Conn = m_dlPrompt->PromptNew();

  if (m_Conn!=NULL)

  {

  //将连接字符串复制到m_strConnect 中

  m_strConnection.Format("%s", (char*)m_Conn->ConnectionString);

  //将变量中的值保存到控件中

  UpdateData(FALSE);

  }

  }

  编写好设置数据源的代码,接下来该为“连接”按钮编写响应函数了。在编写此函数之

  前,先要编写数据库表名的函数。因为当连接成功时,在List Box 控件中会显示出数据库中

  所有表的名称。为类CAdoTestView 添加一个函数void getTables(),它是public 的,用来显

  示表名。代码如下:

  void CAdoTestView::getTables()

  {

  _bstr_t tablesNcoms;

  CString kooky;

  //先将List Box 清空

  m_ListBox.ResetContent();

  //将控件中的值保存到变量中

  UpdateData( TRUE);

  try

  {

  //创建实例

  m_Recordset.CreateInstance(__uuidof(Recordset));

  //以只读方式打开结果集,得到表名信息

  m_Recordset = m_Connection->OpenSchema (adSchemaTables,vtMissing,vtMissing);

  //如果结果集没有结束

  while (!m_Recordset->adoEOF)

  {

  //得到表项的名字

  tablesNcoms = m_Recordset->GetCollect("TABLE_NAME");

  kooky = (char*) tablesNcoms;

  //如果是表项,则加到ListBox 中

  if (kooky.Left(4) != "MSys")

  m_ListBox.AddString( kooky );

  //移到下一个表项

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·362·

  m_Recordset->MoveNext();

  }

  }

  //捕获例外_com_error

  catch (_com_error &e)

  {

  GenerateError(e.Error(), e.Description());

  }

  //捕捉其他例外

  catch(...) {}

  //将变量中的值保存到控件中

  UpdateData( FALSE );

  //最后将结果集置为空

  m_Recordset = NULL;

  }

  现在为“连接”按钮编写响应函数。具体步骤与为“数据源”按钮添加响应函数的一致,

  只是Object IDs 下拉列表中选择Connect 按钮的ID:IDC_CONNECT,代码如下:

  void CAdoTestView::OnConnect()

  {

  // TODO: Add your control notification handler code here

  //更新变量值

  UpdateData(TRUE);

  try

  {

  //创建实例

  m_Connection.CreateInstance(__uuidof(Connection));

  //根据连接字符串开启数据连接

  m_Connection->Open( _bstr_t( m_strConnection.GetBuffer(0) ), "", "", -1);

  }

  //捕获例外_com_error

  catch (_com_error &e)

  {

  GenerateError(e.Error(), e.Description());

  }

  //捕捉其他例外

  catch(...) {}

  //将变量中的值保存到控件中

  UpdateData( FALSE );

  //显示表项名

  getTables();

  枫叶文学网www.fywxw.com

  第12 章 数据库开发

  ·363·

  }

  按照顺序,为“cāo作”按钮编写响应函数。代码如下:

  void CAdoTestView::OnExecute()

  {

  // TODO: Add your control notification handler code here

  try

  {

  //创建实例

  m_Recordset.CreateInstance(__uuidof(Recordset));

  //将控件中的值保存到变量中,主要是保存SQL 语句

  UpdateData(TRUE);

  //设定光标服务

  m_Connection->CursorLocation = adUseClient;

  //根据连接字符串开启数据连接,得到结果集

  m_Recordset->Open(m_strSQL.GetBuffer(0), m_Connection.GetInterfacePtr(), adOpenDynamic,

  adLockOptimistic, adCmdText);

  }

  //捕获例外_com_error

  catch (_com_error &e)

  {

  GenerateError(e.Error(), e.Description());

  }

  //捕获其他例外

  catch (...) {}

  //将结果集中的内容在datagrid 中显示出来

  m_DataGrid.SetRefDataSource((LPUNKNOWN)m_Recordset);

  //刷新DataGrid

  m_DataGrid.Refresh();

  //将变量中的值保存到控件中

  UpdateData(FALSE);

  //将结果集置空

  m_Recordset = NULL;

  }

  在这段代码中,完成了执行SQL 语句。这是因为记录集转化成LPUNKNOWN 类型,然

  后当做参数传给DataGrid 控件的方法SetRefDataSource 即可。

  至此,程序已经可以完成对数据库的cāo作了,但是为了让程序更加完善,当cāo作结束时,

  应该关闭记录集和连接,然后退出。最后还需要为“断开”和“退出”按钮编写响应函数。

  “断开”按钮的响应函数如下:

  void CAdoTestView::OnDisconnect()

  {

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·364·

  // TODO: Add your control notification handler code here

  try

  {

  //关闭连接

  m_Connection->Close();

  }

  //捕获_com_error 例外

  catch (_com_error &e)

  {

  GenerateError(e.Error(), e.Description());

  }

  //捕获其他例外

  catch(...) {}

  //清空List Box 控件

  m_ListBox.ResetContent();

  //将DataGrid 控件置空

  m_DataGrid.SetRefDataSource(NULL);

  //将DataGrid 控件设置成默认状态

  m_DataGrid.ClearFields();

  //刷新DataGrid

  m_DataGrid.Refresh();

  //将SQL 语句清空

  //这里不清空连接语句,是为了断开连接以后如果重新连接不需要重新设定数据源

  m_strSQL = "";

  //将变量值保存到控件中

  UpdateData(FALSE);

  }

  为“退出”按钮编写如下响应函数:

  void CAdoTestView::OnQuit()

  {

  // TODO: Add your control notification handler code here

  try

  {

  //关闭记录集

  if (m_Recordset != NULL)

  m_Recordset->Close();

  //关闭连接

  if (m_Connection !=NULL)

  m_Connection->Close();

  }

  枫叶文学网www.fywxw.com

  第12 章 数据库开发

  ·365·

  //捕获例外

  catch(...){}

  //退出

  PostMessage(WM_QUIT);

  }

  至此,基本功能已经全部完成。为了让用户cāo作起来更加方便,下面介绍为添加的

  松语文学免费小说阅读_www.16sy.com