第8课 标签和工作表格

简  介– 标签和表格

标签和表格对于GUI应用程序来说是极其重要的部件,本教程的目的是演示如何将这些特性纳入到Ultimate Grid应用程序中。此例采用了对话框界面。这个应用程序将有三个选项卡对应的三个表格。所有这三个表格将被连接到相同的数据源,分别从各自对应的数据库表中读取数据。关于数据源,你可以在合适的位置创建一个.mdb文件。请记住务必在启动函数时传递一个正确路径的参数。下面这个函数调用演示了这个过程:

m_dao.Open("movie","Employees");

完成后的程序将表现为下面这个图。


图4.14 - Ultimate Grid 演示标签页和表格


第1步– 启动一个新的MFC对话框项目

启动一个新的MFC对话框项目。将这个项目命名为Tabs。记住要添加所有的UG*.cpp文件和UG*.h文件,还有ugdao.hugdao.cpp这两个文件。

在对话框界面上添加两个按钮控件和一个静态控件。

静态控件命名为IDC_GRID。请参考下图:

图4.15 - The IDD_TABS_DIALOG 


控件命名列表如下:

主静态控件

IDC_GRID

SQL编辑框

IDC_SQL_INFO

SQL命令按钮

IDC_SQL

Close命令按钮

IDC_CANCEL

 

第2步– 创建一个新的CtabsDlg类成员变量

我们必须添加一个MYCug对象到CtabDlg类。首先是把'mycug.h'这一句添加到CtabDlg的头文件中,然后实例化一个新的网格对象。代码如下:

/**************************************************************************************/
//******* 新添加的头文件
#include "Mycug.h"
class CTabsDlg : public CDialog
{
  public:
  // **** 新添加的网格对象
  MyCug m_grid;

第3步 – 在对话框界面上建立网格

此时用来容纳网格的主界面上的静态控件是必要的。其命名为IDC_GRID。

添加下面代码到CTabsDlg::OnInitDialog()中。

/*********************************************************************************/
BOOL CTabsDlg::OnInitDialog(){
  CDialog::OnInitDialog();
  //****** 在对话框界面上构建网格
  m_grid.AttachGrid(this, IDC_GRID);
}

第4步– 创建一个新的MyCug类成员变量

CUGDAODataSource数据源类负责填充网格的数据。必须在MyCug中创建三个CUGDAODataSource类的成员变量。

"ugdao.h"必须被包含到MyCug.h文件中,之后再创建三个CUGDAODataSource对象,每个对象负责填充一个单独的表。

添加下列代码到MyCug头文件中:

/***********************************************************************************/
#include "ugctrl.h"
//****** 新添加的头文件
#include "ugdao.h"
class MyCug:public CUGCtrl
{
  public:
  //****** 新创建的三个对象
  CUGDAODataSource m_dao, m_dao2, m_dao3;

第5步– 在STDAFX头文件里添加Afxdao头文件

如果你这一步没完成以前,你的程序将不会被正确的编译执行。你必须添加'afxdao.h'到STDAFX头文件中。

参考下面的程序片段:

/*************************************************************************************/
define VC_EXTRALEAN
#include <afxwin.h>
#include <afxdao.h> //新添加的头文件
#include <afxext.h> // MFCextensions
#include <afxdisp.h> // MFC OLEautomation classes

第6步– 在OnSetup消息函数内编码

添加所有下列代码到MyCug::OnSetup()消息函数:

/**************************************************************************************/
void MyCug::OnSetup(){
  //******* 添加三个表格
  SetNumberSheets(3);
  //******* 添加三个标签
  AddTab("Employees", 0); 
  AddTab("Movies", 1); 
  AddTab("Customers", 2);
  //***** 设置标签宽度
  SetTabWidth(200);
  //***** 设置第一个表格
  SetSheetNumber(0); 
  SetUniformRowHeight(TRUE);
  //****** 设置第一个数据源
  m_dao.Open("movie","Employees"); 
  int index = AddDataSource(&m_dao); 
  if (index < 0)
    MessageBox("No Data Source was allocated");
  else{
    SetDefDataSource(index); 
    SetGridUsingDataSource(index); 
    AdjustComponentSizes(); 
    int num_cols = GetNumberCols(); 
    BestFit(0,num_cols-1,0,1);
  }
  //***** 设置第二个表格
  SetSheetNumber(1); 
  SetUniformRowHeight(TRUE);
  //****** 设置第二个数据源
  m_dao2.Open("movie","movies"); 
  int index2 = AddDataSource(&m_dao2);
  if (index2 < 0) 
    MessageBox("No Data Source was allocated");
  else{
    SetDefDataSource(index2); 
    SetGridUsingDataSource(index2); 
    AdjustComponentSizes(); 
    int num_cols = GetNumberCols();
    BestFit(0,num_cols-1,0,1);
  }
  //****** 调用第一个表格
  SetSheetNumber(0);
}

代码说明

这个消息函数的开始首先创建三个工作表(网格),然后定义三个标签页。这些标签编号是基于0的。第一个标签命名为'Employees',第二个标签命名为'movies',第三个标签命名为'Customers'。调用SetTabWidth()设置标签宽度为200个像素点。

所有的表格(网格)编号都是基于0的。第一个表格(网格)被定义为“表0”。CUGDAODataSource类型的对象m_dao对“表0”填充数据。是调用下面这个函数完成的:

m_dao.Open("movie","Employees");

数据源为"movie"是一个普通的.mdb文件。由于这个文件是放在项目的路径下,所以在代码里没有写目录路径。m_dao.Open的第二个参数是值数据源中的数据库表的名称。

下一行代码用来获得一个数据源的索引值:

int index = AddDataSource(&m_dao);

这个AddDataSource函数需要m_dao对象的地址作为参数。现在index变量包含了m_dao对象的索引值。此索引值被附加到一个链表,当然这都在程序内部完成,因此您不必担心这个问题。

另外给“表0”填充数据的代码如下:

SetDefDataSource(index);

SetGridUsingDataSource(index);

AdjustComponentSizes();

int num_cols = GetNumberCols();

BestFit(0,num_cols-1,0,1)

Index变量被作为SetDefDataSource()和SetGridUsingDataSource()的参数。这两个函数用数据库Employees表中的数据对“表0”进行填充。

BestFit函数能够确保列宽度恰当的显示所有的数据。

其余的代码定义了“表1”和“表2”。这些表格(网格)被定义后,调用SetSheetNumber(0) 函数使当前表为“表0”。


第7步– 在MyCug::OnHitBottom()内编码

你必须添加一些代码到此消息函数中,否则的话程序只能显示一条记录,因此你要通知网格还有记录需要添加,直到所有的记录都添加完毕。

添加下列代码到OnHitBottom()函数:

/**************************************************************************************/
void MyCug::OnHitBottom(longnumrows,long rowspast,long rowsfound){
  //****** 设置行数
  SetNumberRows(numrows+rowsfound, FALSE);
}

注意:确保SetNumberRows()函数的第二个参数为FALSE ,否则网格将无限循环刷新。


第8步– 在OnTabSelected()内编码

调用SetSheetNumber()函数能让用户在选择标签时显示对应的工作表(网格),这个ID为标签编号。因此如果是选择标签2那么就显示“表2”。

MyCug::OnTabSelected(int ID)
{
  SetSheetNumber(ID) ;
}

一旦网格被调用,它会加载第一个工作表(表0)。用户可以选择其中的三个标签。当用户选择了另外的标签,会显示新的工作表。这些不同的工作表连接到相同数据源的不同数据库表。下图显示了Movies标签被选择即标签1,其结果是m_dao2对象从movie数据库表中读取数据填充“表1”。


图4.16 – Ultimate Grid标签与工作表


第9步– 创建CTabsDlg::OnSQL()函数

这一步的目的是为了完成这个应用程序,这样当用户输入一个有效的SQL查询,相应的数据将填充网格。因此如果我们是工作表0那就从“雇员”表中读取。

使用类向导为IDC_SQL命令按钮创建消息响应函数。默认情况下,此消息函数名应该为CTabsDlg::OnSql()。

添加下列代码到这个函数中:

/************************************************************************************/
void CTabsDlg::OnSql(){
  //****** 创建所有变量
  CString my_sql, path ;
  //******* 获取当前工作表号
  Int sheetNumber = m_grid.GetSheetNumber();
  //****** 从用户处获取SQL信息
  GetDlgItemText(IDC_SQL_INFO, my_sql);
  if (my_sql > 1){
    //******* 第一个工作表被调用?? 
    if (sheetNumber == 0){
      path = "movie";
      //*******设置行数和列数为0
      m_grid.SetNumberRows(0); 
      m_grid.SetNumberCols(0);
      //*** 关闭数据源
      m_grid.m_dao.Close();
      //****** 设置当前工作表为表0 
      m_grid.SetSheetNumber(0);
      //****** 调用SQL查询
      if( m_grid.m_dao.OpenSQL(path, my_sql) == UG_SUCCESS){
        //******获取数据源索引值
        int index = m_grid.AddDataSource(&(m_grid.m_dao));
        m_grid.SetDefDataSource(index); 
        m_grid.SetGridUsingDataSource(index);
        int num_col = m_grid.m_dao.GetNumCols();
        m_grid.BestFit(0,num_col-1,0,1) ;
      }
    }
    //****** 是第二个工作表被调用?? 
    if (sheetNumber == 1){
      path = "movie";
      //*******设置行数和列数为0
      m_grid.SetNumberRows(0); 
      m_grid.SetNumberCols(0);
      //*** 关闭数据源
      m_grid.m_dao2.Close();
      //****** 设置当前工作表为表1
      m_grid.SetSheetNumber(1);
      //****** 调用SQL查询
      if( m_grid.m_dao2.OpenSQL(path, my_sql) == UG_SUCCESS){
        //******获取数据源索引值
        int index2 = m_grid.AddDataSource(&(m_grid.m_dao2));
        m_grid.SetDefDataSource(index2); 
        m_grid.SetGridUsingDataSource(index2);
        int num_col = m_grid.m_dao.GetNumCols();
        m_grid.BestFit(0,num_col-1,0,1) ;
      }
    }
  }
  else
    MessageBox("There is no SQL information", "GRIDERROR", MB_ICONSTOP);
//*****代码结束!!
}

代码说明

这个代码片段与位于MyCug::OnSetup消息中(第六步)的代码之间的主要区别在于此消息函数利用CUGDAODataSource::OpenSQL()给工作表填充数据。这个函数需要两个参数,分别是:数据源名称和用户输入的SQL查询语句。这个消息函数也通过CUGCtrl::GetSheetNumber()函数获得当前工作表值。这个函数的返回值填充整型变量sheetNumber。

下图显示了从“表0”获得的SQL查询结果。


图4.17 - Ultimate Grid标签和工作表


实验用MDB数据库文件
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值