📄 visual c++多线程dao处理 .txt
字号:
Visual C++多线程DAO处理
在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())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -