今天帮人调试程序,遇到了MFC ODBC与Access数据库相关的问题,记录下。

之前从未真正使用过ODBC与Access数据库,下面是一点理解:ODBC和JDBC一样,是一层统一的封装,由各个数据库厂商提供统一的接口。你可以使用ODBC的统一接口,因为它具有通用性,稍加修改就能移植到不同数据库。当然,你也可以使用数据库厂商提供的单独的库。

与Access数据库连接,本质是与其数据库文件打交道,格式为.mdb。可以通过COM或者MFC本身的ODBC支持来实现连接。

COM实现连接:http://6520874.blog.163.com/blog/static/7258271920113845626128/

MFC项目向导中有对ODBC的支持,首先要在控制面板--->管理工具中配置数据源(ODBC)。

配置时有三种DSN(Data Source Name,数据源名称),需要根据具体情况及其提示进行配置,添加Microsoft Access Driver相关的数据库.mdb文件。

MFC项目向导会自动生成相关的CxxxSet类对ODBC进行支持。

在这里有趣的是,VC6.0的对话框编辑器中提供了相应的ActiveX控件ADODC和DATAGRID对ODBC进行了视图支持,但VS2005中确没有。具体的解决方案是:http://zhidao.baidu.com/question/210849183.html

在调试的过程中,因为项目的具体要求,还遇到了一点问题。该项目的主窗口即m_pMainWnd是含有以上两个控件的View,不是Dlg。现在需要先有登录对话框进行登录后才能出现主窗口。

在InitInstance中进行修改如下:
// The one and only window has been initialized, so show and update it.
//m_pMainWnd->ShowWindow(SW_SHOW);
//m_pMainWnd->UpdateWindow();
CLoginDlg dlg;
dlg.DoModal();
return TRUE;

然后在登录对话框的登录成功处有如下代码:
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW);
AfxGetApp()->m_pMainWnd->UpdateWindow();
CDialog::OnOK();

结果发现主窗口依然出现,并且CLoginDlg的构造函数中AfxOleInit处出现断言错误。注释掉后,断言错误消失。

于是注释掉InitInstance中如下代码:
//// Parse command line for standard shell commands, DDE, file open
//CCommandLineInfo cmdInfo;
//ParseCommandLine(cmdInfo);

//// Dispatch commands specified on the command line
//if (!ProcessShellCommand(cmdInfo))
// return FALSE;

结果发现会在ShowWindow(SW_SHOW)处出现断言错误,具体出现在winocc.cpp ShowWindow中的ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));处。

经过调试发现m_pMainWnd为NULL。也就是说在ProcessShellCommand后m_pMainWnd才会有正确的赋值。参考:http://apps.hi.baidu.com/share/detail/15714628

最终解决方案:相关函数的调用延迟到CLoginDlg的登录处理函数中,如下:
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
AfxGetApp()->ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line
if (!AfxGetApp()->ProcessShellCommand(cmdInfo))
return ;

// The one and only window has been initialized, so show and update it.
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW);
AfxGetApp()->m_pMainWnd->UpdateWindow();
CDialog::OnOK();