Visual C++多线程DAO处理

来源:互联网 发布:财经数据接口 编辑:程序博客网 时间:2024/05/27 10:42
在DAO多线程处理中,有许多局限性,所以我设计了这么一个类,通过GUI线程来使用DAO的强制调用。在类中使用了GUI的消息队列,所有进入到CMultiDAORecordset的调用都被迫使用AfxGetThread()来检查当前的线程。GUI线程指针是放在InitInstance的首端,如果在GUI线程中,引入的调用请求不在运行,那么CMultiDAORecordSet就会发送一个WM_MULTIDAOMESSAGE消息给AfxGetMainWnd()(在Mainfrm.cpp中)。Mainfrm接受到这个消息,线程也就要再运行一次,这个时候,消息已经接受了,基类CDaoRecordset也就得到了调用。所以你的类是从CMultiDAORecordset继承的,而不是CDaoRecordset,如下: 

class CMySet : public CMultiDaoRecordSet

在相应的CPP文件中也应该改一下:

IMPLEMENT_DYNAMIC(CMySet, CMultiDaoRecordSet)

CMySet::CMySet (CDaoDatabase* pdb) : CMultiDaoRecordSet(pdb) 
为了处理接受到的WM_MULTIDAOMESSAGE消息,下面的代码还应该加在MainFrm中:

在MainFrm.h文件中加:
#ifdef MAINFRAME_CPP 
UINT WM_MULTIDAOMESSAGE = RegisterWindowMessage("WM_MULTIDAOMESSAGE"); 
#else 
extern UINT WM_MULTIDAOMESSAGE; 
#endif 

afx_msg LONG OnMultiDaoMessage( UINT uParam, LONG lParam); 
在MainFrm.cpp文件中加:
#define MAINFRAME_CPP 

#include "MutliDaoRecordset.h" 

//added to the message map 

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) 
//{{AFX_MSG_MAP(CMainFrame) 
ON_REGISTERED_MESSAGE(WM_MULTIDAOMESSAGE, OnMultiDaoMessage) 
END_MESSAGE_MAP() 

//this function added 
LONG CMainFrame::OnMultiDaoMessage( UINT uParam, LONG lParam) 

//jtm 
//based on switch, perform operation... 
CMultiDaoRecordSet *pSet = (CMultiDaoRecordSet *)lParam; 
LONG lRet = 0; 

CString cRet = ""; 
COleVariant cVar; 

try 

//jtm-------debug-------------------------------------- 
CString cTraceMessage = cDAOMessageArray[uParam]; 
cTraceMessage += "/n"; 
TRACE(cTraceMessage); 
//jtm-------debug-------------------------------------- 

switch(uParam) 

case MultiDaoOpen: 
pSet->Open(); 
break; 
case MultiDaoClose: 
pSet->Close(); 
break; 
case MultiDaoIsOpen: 
lRet = (LONG)pSet->IsOpen(); 
break; 
case MultiDaoIsBOF: 
lRet = (LONG)pSet->IsBOF(); 
break; 
case MultiDaoIsEOF: 
lRet = (LONG)pSet->IsEOF(); 
break; 
case MultiDaoIsDeleted: 
lRet = (LONG)pSet->IsDeleted(); 
break; 
case MultiDaoIsFieldDirty: 
lRet = (LONG)pSet->IsFieldDirty(pSet->pParam1); 
break; 
case MultiDaoIsFieldNull: 
lRet = (LONG)pSet->IsFieldNull(pSet->pParam1); 
break; 
case MultiDaoIsFieldNullable: 
lRet = (LONG)pSet->IsFieldNullable(pSet->pParam1); 
break; 
case MultiDaoGetName: 
cRet = pSet->GetName(); 
lRet = (LONG)&cRet; 
break; 
case MultiDaoGetType: 
lRet = (LONG)pSet->GetType(); 
break; 
case MultiDaoGetEditMode: 
lRet = (LONG)pSet->GetEditMode(); 
break; 
case MultiDaoGetLastModifiedBookmark: 
cVar = pSet->GetLastModifiedBookmark(); 
lRet = (LONG)&cVar; 
break; 
case MultiDaoGetRecordCount: 
lRet = (LONG)pSet->GetRecordCount(); 
break; 
case MultiDaoMoveNext: 
pSet->MoveNext(); 
break; 
case MultiDaoMovePrev: 
pSet->MovePrev(); 
break; 
case MultiDaoMoveFirst: 
pSet->MoveFirst(); 
break; 
case MultiDaoMoveLast: 
pSet->MoveLast(); 
break; 
case MultiDaoMove: 
pSet->Move(*(LONG *)pSet->pParam1); 
break; 
case MultiDaoFindNext: 
lRet = (LONG)pSet->FindNext(*(LPCTSTR *)pSet->pParam1); 
break; 
case MultiDaoFindPrev: 
lRet = (LONG)pSet->FindPrev(*(LPCTSTR*)pSet->pParam1); 
break; 
case MultiDaoFindFirst: 
lRet = (LONG)pSet->FindFirst(*(LPCTSTR *)pSet->pParam1); 
break; 
case MultiDaoFindLast: 
lRet = (LONG)pSet->FindLast(*(LPCTSTR *)pSet->pParam1); 
break; 
case MultiDaoFind: 
lRet = (LONG)pSet->Find(*(LONG *)pSet->pParam1, *(LPCTSTR*)pSet->pParam2); 
break; 
case MultiDaoGetBookmark: 
cVar = pSet->GetBookmark(); 
lRet = (LONG)&cVar; 
break; 
case MultiDaoSetBookmark: 
pSet->SetBookmark(*(COleVariant*)pSet->pParam1); 
break; 
case MultiDaoAddNew: 
pSet->AddNew(); 
break; 
case MultiDaoEdit: 
pSet->Edit(); 
break; 
case MultiDaoUpdate: 
pSet->Update(); 
break; 
case MultiDaoDelete: 
pSet->Delete(); 
break; 
case MultiDaoCancelUpdate: 
pSet->CancelUpdate(); 
break; 
case MultiDaoRequery: 
pSet->Requery(); 
break; 


catch (CDaoException *e) 

TRACE("Database Multithread Operation Failed%s/n", 
e->m_pErrorInfo->m_strDescription); 

return lRet; 


下面的代码是加在对应的应用程序对象的头文件中的:
public:
CWinThread *pGUIThread;

And this to the constructor in the app .cpp file:


CMyApp::CMyApp()
{
pGUIThread = AfxGetThread();
}
 

  如果没有上面的定义的话,你的应用程序就会出问题。整个DAO公共函数并没有全部实现,但不管怎么样,上面的函数是保护CDaoRecordset的使用的。如果你要加个函数的话,加进去就行了,你也可以用一个对话框来显示错误信息,它们都应该在MultiDaorecordset.h中被定义。为了支持DAO多线程的类,下面的代码也应该加进去:

加在Multidaorecordset.cpp中:
// MultiDaoRecordSet.cpp : implementation file 
// 

#define MULTIDAORECORDSET_CPP 

#include "stdafx.h" 

#include "MyApp.h" 

#include "MultiDaoRecordSet.h" 

#include "mainfrm.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 

///////////////////////////////////////////////////////////////////////////// 
// CMultiDaoRecordSet 

IMPLEMENT_DYNAMIC(CMultiDaoRecordSet, CDaoRecordset) 

CMultiDaoRecordSet::CMultiDaoRecordSet(CDaoDatabase* pdb) 
: CDaoRecordset(pdb) 

//{{AFX_FIELD_INIT(CMultiDaoRecordSet) 
//}}AFX_FIELD_INIT 
m_nDefaultType = dbOpenDynaset; 


//jtm 
//thread safe destructor.... 
CMultiDaoRecordSet::~CMultiDaoRecordSet() 

if (IsOpen()) 
Close(); 

// Clean up database if necessary 
if (m_pDatabase != NULL && (m_nStatus & AFX_DAO_IMPLICIT_DB)) 

m_pDatabase->Close(); 
delete m_pDatabase; 
m_pDatabase = NULL; 



CString CMultiDaoRecordSet::GetDefaultDBName() 

CMyApp *pApp = ((CMYApp *)AfxGetApp()); 
return pApp->GetDatabaseFullPath(); 


///////////////////////////////////////////////////////////////////////////// 
// CMultiDaoRecordSet diagnostics 

//jtm 
//multi thread safe functoins 
void CMultiDaoRecordSet::Open(int nOpenType, LPCTSTR lpszSQL, int nOptions) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::Open(nOpenType, lpszSQL, nOptions); 

else 

pParam1 = (void *)&nOpenType; 
pParam2 = (void *)lpszSQL; 
pParam3 = (void *)&nOptions; 
AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoOpen, (LPARAM)this); 



void CMultiDaoRecordSet::Close() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::Close(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoClose, (LPARAM)this); 



BOOL CMultiDaoRecordSet::IsOpen() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::IsOpen(); 

else 

return (BOOL)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsOpen, (LPARAM)this); 



BOOL CMultiDaoRecordSet::IsBOF() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::IsBOF(); 

else 

return (BOOL)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsBOF, (LPARAM)this); 



BOOL CMultiDaoRecordSet::IsEOF() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::IsEOF(); 

else 

return (BOOL)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsEOF, (LPARAM)this); 



BOOL CMultiDaoRecordSet::IsDeleted() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::IsDeleted(); 

else 

return (BOOL)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsDeleted, (LPARAM)this); 



BOOL CMultiDaoRecordSet::IsFieldDirty(void* pv) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::IsFieldDirty(pv); 

else 

pParam1 = pv; 
return (BOOL)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsFieldDirty, (LPARAM)this); 



BOOL CMultiDaoRecordSet::IsFieldNull(void* pv) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::IsFieldNull(pv); 

else 

pParam1 = pv; 
return (BOOL)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsFieldNull, (LPARAM)this); 



BOOL CMultiDaoRecordSet::IsFieldNullable(void* pv) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::IsFieldNullable(pv); 

else 

pParam1 = pv; 
return (BOOL)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsFieldNullable, (LPARAM)this); 



CString CMultiDaoRecordSet::GetName() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::GetName(); 

else 

return (CString)*(CString *)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetName, (LPARAM)this); 



short CMultiDaoRecordSet::GetType() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::GetType(); 

else 

return (short)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetType, (LPARAM)this); 



short CMultiDaoRecordSet::GetEditMode() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::GetEditMode(); 

else 

return (short)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetEditMode, (LPARAM)this); 



CString CMultiDaoRecordSet::GetSQL() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::GetSQL(); 

else 

return (CString)*(CString *)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetSQL, (LPARAM)this); 



COleVariant CMultiDaoRecordSet::GetLastModifiedBookmark() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::GetLastModifiedBookmark(); 

else 

return (COleVariant)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetLastModifiedBookmark, (LPARAM)this); 



long CMultiDaoRecordSet::GetRecordCount() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::GetRecordCount(); 

else 

return (long)AfxGetMainWnd()-> 
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetRecordCount, (LPARAM)this); 



void CMultiDaoRecordSet::MoveNext() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::MoveNext(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoMoveNext, 
(LPARAM)this); 



void CMultiDaoRecordSet::MovePrev() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::MovePrev(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoMovePrev, 
(LPARAM)this); 



void CMultiDaoRecordSet::MoveFirst() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::MoveFirst(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoMoveFirst, 
(LPARAM)this); 



void CMultiDaoRecordSet::MoveLast() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::MoveLast(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoMoveLast, 
(LPARAM)this); 



void CMultiDaoRecordSet::Move(long lRows) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::Move(lRows); 

else 

pParam1 = (void *)&lRows; 
AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoMove, 
(LPARAM)this); 



BOOL CMultiDaoRecordSet::FindNext(LPCTSTR lpszFilter) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::FindNext(lpszFilter); 

else 

pParam1 = (void *)lpszFilter; 
return (BOOL)AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoFindNext, 
(LPARAM)this); 



BOOL CMultiDaoRecordSet::FindPrev(LPCTSTR lpszFilter) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::FindPrev(lpszFilter); 

else 

pParam1 = (void *)lpszFilter; 
return (BOOL)AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoFindPrev, 
(LPARAM)this); 



BOOL CMultiDaoRecordSet::FindFirst(LPCTSTR lpszFilter) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::FindFirst(lpszFilter); 

else 

pParam1 = (void *)lpszFilter; 
return (BOOL)AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoFindFirst, 
(LPARAM)this); 



BOOL CMultiDaoRecordSet::FindLast(LPCTSTR lpszFilter) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::FindLast(lpszFilter); 

else 

pParam1 = (void *)lpszFilter; 
return (BOOL)AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoFindLast, 
(LPARAM)this); 



BOOL CMultiDaoRecordSet::Find(long lFindType, LPCTSTR lpszFilter) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::Find(lFindType, lpszFilter); 

else 

pParam1 = (void *)&lFindType; 
pParam2 = (void *)lpszFilter; 
return (BOOL)AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoFind, 
(LPARAM)this); 



COleVariant CMultiDaoRecordSet::GetBookmark() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

return CDaoRecordset::GetBookmark(); 

else 

return AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetBookmark, 
(LPARAM)this); 



void CMultiDaoRecordSet::SetBookmark(COleVariant varBookmark) 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::SetBookmark(varBookmark); 

else 

pParam1 = (void *)&varBookmark; 
AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoSetBookmark, 
(LPARAM)this); 



void CMultiDaoRecordSet::AddNew() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::AddNew(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoAddNew, 
(LPARAM)this); 



void CMultiDaoRecordSet::Edit() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::Edit(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoEdit, 
(LPARAM)this); 



void CMultiDaoRecordSet::Update() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::Update(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoUpdate, 
(LPARAM)this); 



void CMultiDaoRecordSet::Delete() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::Delete(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoDelete, 
(LPARAM)this); 



void CMultiDaoRecordSet::CancelUpdate() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::CancelUpdate(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoCancelUpdate, 
(LPARAM)this); 



void CMultiDaoRecordSet::Requery() 

CMYApp *pApp = ((CMYApp *)AfxGetApp()); 
if (pApp->pGUIThread == AfxGetThread()) 

CDaoRecordset::Requery(); 

else 

AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoRequery, 
(LPARAM)this); 



and, Multidaorecordset.h


#if !defined(AFX_MULTIDAORECORDSET_H__BECC8DC3_A967_11D2_BA4C_006097808646__INCLUDED_)
#define AFX_MULTIDAORECORDSET_H__BECC8DC3_A967_11D2_BA4C_006097808646__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// MultiDaoRecordSet.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CMultiDaoRecordSet DAO recordset

enum {
MultiDaoOpen, 
MultiDaoClose, 
MultiDaoIsOpen,
MultiDaoIsBOF,
MultiDaoIsEOF,
MultiDaoIsDeleted,
MultiDaoIsFieldDirty,
MultiDaoIsFieldNull,
MultiDaoIsFieldNullable,
MultiDaoGetName,
MultiDaoGetType,
MultiDaoGetSQL,
MultiDaoGetEditMode,
MultiDaoGetLastModifiedBookmark,
MultiDaoGetRecordCount,
MultiDaoMoveNext,
MultiDaoMovePrev,
MultiDaoMoveFirst,
MultiDaoMoveLast,
MultiDaoMove,
MultiDaoFindNext,
MultiDaoFindPrev,
MultiDaoFindFirst,
MultiDaoFindLast,
MultiDaoFind,
MultiDaoGetBookmark,
MultiDaoSetBookmark,
MultiDaoAddNew,
MultiDaoEdit,
MultiDaoUpdate,
MultiDaoDelete,
MultiDaoCancelUpdate,
MultiDaoRequery,
};

#ifdef MULTIDAORECORDSET_CPP
CString cDAOMessageArray[] = 
{
"MultiDaoOpen", 
"MultiDaoClose", 
"MultiDaoIsOpen",
"MultiDaoIsBOF",
"MultiDaoIsEOF",
"MultiDaoIsDeleted",
"MultiDaoIsFieldDirty",
"MultiDaoIsFieldNull",
"MultiDaoIsFieldNullable",
"MultiDaoGetName",
"MultiDaoGetType",
"MultiDaoGetSQL",
"MultiDaoGetEditMode",
"MultiDaoGetLastModifiedBookmark",
"MultiDaoGetRecordCount",
"MultiDaoMoveNext",
"MultiDaoMovePrev",
"MultiDaoMoveFirst",
"MultiDaoMoveLast",
"MultiDaoMove",
"MultiDaoFindNext",
"MultiDaoFindPrev",
"MultiDaoFindFirst",
"MultiDaoFindLast",
"MultiDaoFind",
"MultiDaoGetBookmark",
"MultiDaoSetBookmark",
"MultiDaoAddNew",
"MultiDaoEdit",
"MultiDaoUpdate",
"MultiDaoDelete",
"MultiDaoCancelUpdate",
"MultiDaoRequery",
};
#else
extern CString cDAOMessageArray[]; 
#endif

class CMultiDaoRecordSet : public CDaoRecordset
{
public:

//jtm
//FORCE user to pass database...
CMultiDaoRecordSet(CDaoDatabase* pDatabase);

~CMultiDaoRecordSet();

DECLARE_DYNAMIC(CMultiDaoRecordSet)

// Field/Param Data
//{{AFX_FIELD(CMultiDaoRecordSet, CDaoRecordset)
//}}AFX_FIELD

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMultiDaoRecordSet)
public:
virtual CString GetDefaultDBName(); // Default database name
//}}AFX_VIRTUAL

// Implementation
//jtm
//redefined public functions
//Note: I am only redefining SOME
//of the public functions this is NOT
//a FULL implementation !!!!!!
public:
//jtm -- only supporting this open.....
virtual void Open(int nOpenType = AFX_DAO_USE_DEFAULT_TYPE,
LPCTSTR lpszSQL = NULL, int nOptions = 0);
virtual void Close();
BOOL IsOpen();
BOOL IsBOF();
BOOL IsEOF();
BOOL IsDeleted();
BOOL IsFieldDirty(void* pv);
BOOL IsFieldNull(void* pv);
BOOL IsFieldNullable(void* pv);
CString GetName();
short GetType();
short GetEditMode();
CString GetSQL();
COleVariant GetLastModifiedBookmark();
long GetRecordCount(); 
void MoveNext();
void MovePrev();
void MoveFirst();
void MoveLast();
virtual void Move(long lRows); 
BOOL FindNext(LPCTSTR lpszFilter);
BOOL FindPrev(LPCTSTR lpszFilter);
BOOL FindFirst(LPCTSTR lpszFilter);
BOOL FindLast(LPCTSTR lpszFilter);
virtual BOOL Find(long lFindType, LPCTSTR lpszFilter);
COleVariant GetBookmark();
void SetBookmark(COleVariant varBookmark); 
virtual void AddNew();
virtual void Edit();
virtual void Update();
virtual void Delete();
virtual void CancelUpdate(); 
virtual void Requery();

void *pParam1;
void *pParam2;
void *pParam3;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the //previous line.

#endif // !defined(AFX_MULTIDAORECORDSET_H__BECC8DC3_A967_11D2_BA4C_006097808646__INCLUDED_)
 


  调试的东西等你搞好你的程序后就可以删了,不过要注意,不要直接调用CDaoRecordset,否则,你的应用程序就会问题。我试了一下,使用这个类的时候,你的计算机的速度会稍微的暂停几秒钟(正在运行你的程序),不过这不会影响到你的计算机的使用的,因为这个类DAO的调用是通过GUI的,如果你使用不当的话(比如临界区问题)就会导致计算机的死锁。 
 
原创粉丝点击