为何使用CFileDialog 会造成数据库打开失败

时间:2022-04-07 23:02:41
我用ODBC操作Excel文件,因为要需要用户输入Excel文件路径,所以使用了CFileDialog,,但是在后面打开数据库时候就失败了,产生异常直接转跳到
CATCH中,

void CCompareRegisters::OnButtonBrowse() //界面上的一个按扭用来输入文件的路径
{
#if 0//我采用这种方式就OK,但是这种方式不能限制文件的后缀名,在选择文件的时候很烦琐,不方便
    CString m_strPath;
    TCHAR   lpDIR[MAX_PATH];   
        LPITEMIDLIST   il;   
BROWSEINFO   bi;   
bi.hwndOwner =m_hWnd;   
bi.pidlRoot=NULL;   
bi.pszDisplayName=lpDIR;   
bi.lpszTitle=_T("please select directory");   
bi.ulFlags=BIF_BROWSEINCLUDEFILES  ;   
bi.lpfn=NULL;   
bi.lParam=0;   
bi.iImage=0;   
il=SHBrowseForFolder(&bi);   

int k=MAX_PATH;
        if(SHGetPathFromIDList(il,lpDIR) == TRUE)  
{    
m_strPath = lpDIR;
GetDlgItem(IDC_EDIT_REG_FILEPATH)->SetWindowText(m_strPath);
}  
#else //采用CFileDialog及失败
    
    CString m_strPath;
    CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"(*.xls)|*.xls",NULL);
    if(dlg.DoModal() == IDOK)
{   
m_strPath = dlg.GetPathName();   

    ((CEdit *)GetDlgItem(IDC_EDIT_REG_FILEPATH))->SetWindowText(m_strPath);
#endif
}

//pFileName指想操作文件路径,并读出excel文件通过参数pDataBuffer传回.
BOOL CCompareRegisters::ReadExcelFileContent(char *pFileName, char *pDataBuffer)
{
    BOOL Flag = FALSE;
    CDatabase database;
    CString sSql;
    CString sItem1, sItem2 , sItem3;
    CString sDriver;
    CString sDsn;
    CString sFile,sPath;

                                    
    //get main program driver for excel,save in sPath
    GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
    sPath.ReleaseBuffer();
    int nPos;
    nPos = sPath.ReverseFind ('\\');
    sPath = sPath.Left (nPos);

    sFile = pFileName; //to be read file name 

    // check excel driver installed status "Microsoft Excel Driver (*.xls)" 
    sDriver = GetExcelDriver();//取的系统驱动名,函数原形没有帖出来
    if (sDriver.IsEmpty())
    {
        // can't find out Excel driver
        AfxMessageBox("Excel driver has not been installed yet!");
        return FALSE;
    }
    
     // create string be used to saved characters
     sDsn.Format("ODBC;DRIVER={%s};DSN=;DBQ=%s", sDriver, sFile);

     TRY
     {
        // open excel file
        database.Open(NULL, false, false, sDsn);//使用了上面的CFileDialog 这里每次都失败,直接跳到CATCH中
        
        CRecordset recset(&database);
        
        // setting Query condition, 
        sSql = "SELECT AddressName,Value,Description "       
                "FROM Table1 " ;                
                //"ORDER BY AddressName ";
    
        // perform Query condition
        recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);

        // get the result
        strcpy(pDataBuffer,"");
        while (!recset.IsEOF())
        {
            
            //read Excel data
            recset.GetFieldValue("AddressName", sItem1);
            recset.GetFieldValue("Value", sItem2);
            recset.GetFieldValue("Description", sItem3);

            for(int i=GetStrLen(sItem1); i<25; i++)
            {
                sItem1 += " ";
            }
            strcat(pDataBuffer,sItem1);
strcat(pDataBuffer,"\n");
                        

            strcat(pDataBuffer,sItem2);
strcat(pDataBuffer,"\n");

            strcat(pDataBuffer,sItem3);
            strcat(pDataBuffer,"\n");

            //move to next line
            recset.MoveNext();
        }

        // close database
        database.Close();
                                 
    }
    CATCH(CDBException, e)
    {
        // if error,give error info ...
        AfxMessageBox("DataBase Error: " + e->m_strError);
    }
    END_CATCH;

    return TRUE;
}

8 个解决方案

#1


是否使用了GetCurrentDirectory函数,有可能是CFileDialog改变了当前路径

#2


异常内容提示是什么??

#3


跟踪一下,sDsn 是否是正确的路径!
database.Open(NULL, false, false, sDsn);//

#4


CFileDialog改变了当前路径,导致数据库访问失败,这在数据库操作中很常见。
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY ¦ OFN_OVERWRITEPROMPT,"(*.xls) ¦*.xls",NULL);
可以改为:
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY ¦ OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR,"(*.xls) ¦*.xls",NULL);
增加 OFN_NOCHANGEDIR标识。

另外的方法:
TCHAR szDir[MAX_PATH];
::GetCurrentDirectory(MAX_PATH, szDir);
//接下来是与路径有关的操作(可能改变当前路径的操作)
.....
最后恢复当前路径:
if(!::SetCurrentDirectory(szDir))
{
MessageBox("ÖØÐÂÉèÖõ±Ç°Ä¿Â¼Ê§°Ü!");
}

#5


我跟踪路径是正确的,不过非常奇怪 ,我刚刚把这个工程在家里编译运行,居然是OK的,,但是我在公司运行的时候,我不用CFileDialog,直接在程序中赋绝对路径,若不去调用CFileDialog就没有问题,只要调用CFileDialog,即使赋上绝对路径还是打开失败,,,貌似不像CFileDialog改变了文件了路径吧?

#6


我跟踪路径是正确的,不过非常奇怪 ,我刚刚把这个工程在家里编译运行,居然是OK的,,但是我在公司运行的时候,我不用CFileDialog,直接在程序中赋绝对路径,若不去调用CFileDialog就没有问题,只要调用CFileDialog,即使赋上绝对路径还是打开失败,,,貌似不像CFileDialog改变了文件了路径吧?

#7


是不是默认路径的问题? 你在程序中调用GetCurrentDirectory(MAX_PATH,szFileName);并打印出szFileName的结果看看是什么??

#8


我也不知道为什么了?因为最近几天忙别的事情去了,昨天晚上在家的电脑上试验,OK,,现在在公司也是OK的了,,

谢谢大家了 ,,之后遇到该问题了,,先按照大家的方法去查一下,,,

#1


是否使用了GetCurrentDirectory函数,有可能是CFileDialog改变了当前路径

#2


异常内容提示是什么??

#3


跟踪一下,sDsn 是否是正确的路径!
database.Open(NULL, false, false, sDsn);//

#4


CFileDialog改变了当前路径,导致数据库访问失败,这在数据库操作中很常见。
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY ¦ OFN_OVERWRITEPROMPT,"(*.xls) ¦*.xls",NULL);
可以改为:
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY ¦ OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR,"(*.xls) ¦*.xls",NULL);
增加 OFN_NOCHANGEDIR标识。

另外的方法:
TCHAR szDir[MAX_PATH];
::GetCurrentDirectory(MAX_PATH, szDir);
//接下来是与路径有关的操作(可能改变当前路径的操作)
.....
最后恢复当前路径:
if(!::SetCurrentDirectory(szDir))
{
MessageBox("ÖØÐÂÉèÖõ±Ç°Ä¿Â¼Ê§°Ü!");
}

#5


我跟踪路径是正确的,不过非常奇怪 ,我刚刚把这个工程在家里编译运行,居然是OK的,,但是我在公司运行的时候,我不用CFileDialog,直接在程序中赋绝对路径,若不去调用CFileDialog就没有问题,只要调用CFileDialog,即使赋上绝对路径还是打开失败,,,貌似不像CFileDialog改变了文件了路径吧?

#6


我跟踪路径是正确的,不过非常奇怪 ,我刚刚把这个工程在家里编译运行,居然是OK的,,但是我在公司运行的时候,我不用CFileDialog,直接在程序中赋绝对路径,若不去调用CFileDialog就没有问题,只要调用CFileDialog,即使赋上绝对路径还是打开失败,,,貌似不像CFileDialog改变了文件了路径吧?

#7


是不是默认路径的问题? 你在程序中调用GetCurrentDirectory(MAX_PATH,szFileName);并打印出szFileName的结果看看是什么??

#8


我也不知道为什么了?因为最近几天忙别的事情去了,昨天晚上在家的电脑上试验,OK,,现在在公司也是OK的了,,

谢谢大家了 ,,之后遇到该问题了,,先按照大家的方法去查一下,,,