//****************************************************************************
/*
作者: 孙益华
开码功能:
call("类","方法")
call(对象,"方法")
扫描数据库
*/
#pragma warning(disable : 4786)
#include <windows.h>
#include <pbext.h>
#include <richedit.h>
#include <commctrl.h>
#include <math.h>
#include <string>
extern "C"
{
#include <oratypes.h>
#include <ociapr.h>
/* demo constants and structs */
#include <ocidem.h>
}
#pragma comment(lib,"oci.lib")
using std::string;
PBXEXPORT LPCTSTR PBXCALL PBX_GetDescription()
{
static const TCHAR desc[] = {
"class n_objcall from nonvisualobject\n"
"subroutine of_call(string class_name,string Method_name,...)\n"//string signature,string arguments[]
"subroutine of_call(powerobject pbo,string method_name,...)\n"//string signature,string arguments[]
"subroutine of_startdblisten(string dbusername,string dbpassword,string sql,ulong hwnd,ulong msg,long cstep1,long cstep2)\n"
"subroutine of_closedblisten()\n"
"end class\n"
};
return desc;
}
DWORD WINAPI DBListenThread(LPVOID lpParam);
typedef struct
{
string username;
string password;
HWND hwnd;
UINT msg;
string sql;
LONG cstep1;
LONG cstep2;
}THREADDATA;
class CNonVisualExt : public IPBX_NonVisualObject
{
IPB_Session* d_session;
pbobject d_pbobj;
HANDLE thread;
THREADDATA data;
public:
CNonVisualExt(IPB_Session* session, pbobject pbobj)
:
d_session(session),
d_pbobj(pbobj),
thread(NULL)
{
}
~CNonVisualExt()
{
}
PBXRESULT Invoke
(
IPB_Session *session,
pbobject obj,
pbmethodID mid,
PBCallInfo *ci
);
void Destroy()
{
if(thread)
{
DWORD exitcode;
GetExitCodeThread(thread,&exitcode);
if(exitcode == STILL_ACTIVE)
{
TerminateThread(thread,0);
}
CloseHandle(thread);
}
delete this;
}
};
PBXRESULT CNonVisualExt::Invoke
(
IPB_Session *session,
pbobject obj,
pbmethodID mid,
PBCallInfo *ci
)
{
switch(mid)
{
case 0:
{
pbgroup group;
pbclass cls;
pbmethodID callmid;
PBCallInfo* callinfo;
pblong dim,n,ll_count;
pbarray in_array;
pbboolean bIsNull = 0;
if(session)
{
group = session-> FindGroup(session->GetString(ci->pArgs->GetAt(0)->GetString()),pbgroup_userobject);
if (group)
{
cls = session->FindClass(group,session->GetString(ci->pArgs->GetAt(0)->GetString()));
if(cls)
{
ll_count = ci->pArgs->GetCount();
callmid = ll_count > 2 ? session->GetMethodID(cls,session->GetString(ci->pArgs->GetAt(1)->GetString()),PBRT_FUNCTION,session->GetString(ci->pArgs->GetAt(2)->GetString())):
session->GetMethodID(cls,session->GetString(ci->pArgs->GetAt(1)->GetString()),PBRT_FUNCTION,"Q");
if(callmid != kUndefinedMethodID)
{
callinfo = new PBCallInfo;
session->InitCallInfo(cls,callmid,callinfo);
if(ll_count > 3 && ci->pArgs->GetAt(3)->IsArray())
{
in_array = ci->pArgs->GetAt(3)->GetArray();
ll_count = session->GetArrayLength(in_array);
for(n=0; n<ll_count; n++)
{
dim = n + 1;
callinfo->pArgs->GetAt((pbint)n)->SetPBString(session->GetStringArrayItem(in_array,&dim,bIsNull));
}
}
session->InvokeClassFunction(cls,callmid,callinfo);
session->FreeCallInfo(callinfo);
}
}
}
}
}
break;
case 1:
{
pbclass cls;
pbobject pbobj;
pbmethodID callmid;
PBCallInfo* callinfo;
pblong dim,n,ll_count;
pbarray in_array;
pbboolean bIsNull = 0;
if(session)
{
pbobj = ci->pArgs->GetAt(0)->GetObjectA();
if(pbobj)
{
cls = session->GetClass(pbobj);
if(cls)
{
ll_count = ci->pArgs->GetCount();
callmid = ll_count > 2 ? session->GetMethodID(cls,session->GetString(ci->pArgs->GetAt(1)->GetString()),PBRT_FUNCTION,session->GetString(ci->pArgs->GetAt(2)->GetString())):
session->GetMethodID(cls,session->GetString(ci->pArgs->GetAt(1)->GetString()),PBRT_FUNCTION,"Q");
if(callmid != kUndefinedMethodID)
{
callinfo = new PBCallInfo;
session->InitCallInfo(cls,callmid,callinfo);
if(ll_count > 3 && ci->pArgs->GetAt(3)->IsArray())
{
in_array = ci->pArgs->GetAt(3)->GetArray();
ll_count = session->GetArrayLength(in_array);
for(n=0; n<ll_count; n++)
{
dim = n + 1;
callinfo->pArgs->GetAt((pbint)n)->SetPBString(session->GetStringArrayItem(in_array,&dim,bIsNull));
}
}
session->InvokeObjectFunction(pbobj,callmid,callinfo);
session->FreeCallInfo(callinfo);
}
}
}
}
}
break;
case 2:
if(thread)
{
DWORD exitcode;
GetExitCodeThread(thread,&exitcode);
if(exitcode == STILL_ACTIVE)
{
TerminateThread(thread,0);
}
CloseHandle(thread);
thread = NULL;
}
data.username =string(session->GetString(ci->pArgs->GetAt(0)->GetString()));
data.password =string(session->GetString(ci->pArgs->GetAt(1)->GetString()));
data.sql =string(session->GetString(ci->pArgs->GetAt(2)->GetString()));
data.hwnd =(HWND)ci->pArgs->GetAt(3)->GetUlong();
data.msg =ci->pArgs->GetAt(4)->GetUlong();
data.cstep1 =ci->pArgs->GetAt(5)->GetLong();
data.cstep2 =ci->pArgs->GetAt(6)->GetLong();
data.cstep1 =data.cstep1 >= 0 ? data.cstep1 :0;
data.cstep2 =data.cstep2 >= 0 ? data.cstep2 :0;
thread=CreateThread(NULL,0,DBListenThread,(LPVOID)&data,0,NULL);
break;
case 3:
if(thread)
{
DWORD exitcode;
GetExitCodeThread(thread,&exitcode);
if(exitcode == STILL_ACTIVE)
{
TerminateThread(thread,0);
}
CloseHandle(thread);
thread = NULL;
}
break;
}
return PBX_OK;
}
PBXEXPORT PBXRESULT PBXCALL PBX_CreateNonVisualObject
(
IPB_Session* pbsession,
pbobject pbobj,
LPCTSTR className,
IPBX_NonVisualObject **obj
)
{
PBXRESULT result = PBX_OK;
string cn(className);
if (cn.compare("n_objcall") == 0)
{
*obj = new CNonVisualExt(pbsession, pbobj);
}
else
{
*obj = NULL;
result = PBX_FAIL;
}
return PBX_OK;
};
VOID FAR dblisten(string username,string password,string sql,HWND hwnd,UINT msg)
{
Lda_Def FAR pLda;
Cda_Def FAR pCda;
ub1 hda[HDA_SIZE];
sword rowcount;
#define DEFER_PARSE 1
#define VERSION_7 2
try
{
memset(hda,0,HDA_SIZE);
if(olog(&pLda,hda,(OraText *)username.c_str(),-1,(OraText *)password.c_str(),-1,NULL,-1,OCI_LM_DEF) == 0)
{
if(oopen(&pCda,&pLda,NULL, -1, -1, NULL, -1) == 0)
{
if(oparse(&pCda,(OraText *)sql.c_str(), -1, DEFER_PARSE, (ub4) VERSION_7) == 0)
{
if (odefin(&pCda, 1, (ub1 *) &rowcount, (sword) sizeof(sword),(sword) INT_TYPE,(sword) -1, (sb2 *) 0, (text *) 0, -1, -1,(ub2 *) 0, (ub2 *) 0)==0)
{
if(oexfet(&pCda, (ub4)1, FALSE, FALSE)==0)
{
if(rowcount > 0)
{
if (::IsWindow(hwnd) && msg >= WM_USER)
::PostMessage(hwnd,msg,0,0);
}
}
}
}
oclose(&pCda);
}
ologof(&pLda);
}
}
catch(...)
{}
}
DWORD WINAPI DBListenThread(LPVOID lpParam)
{
THREADDATA data;
data = *(THREADDATA *)lpParam;
LONG T=0;
threadbegin:
try
{
while(TRUE)
{
Sleep(data.cstep1);
dblisten(data.username,data.password,data.sql,data.hwnd,data.msg);
if(data.cstep2 > 0 && (LONG)timeGetTime() - T > data.cstep2)
{
T = timeGetTime();
if (::IsWindow(data.hwnd) && data.msg >= WM_USER)