有沒有MIDAS中Callback的範例(BCB)? |
答題得分者是:jieshu
|
alvinmeng70
一般會員 發表:7 回覆:2 積分:1 註冊:2005-03-09 發送簡訊給我 |
|
jieshu
版主 發表:42 回覆:894 積分:745 註冊:2002-04-15 發送簡訊給我 |
引言: 各位高手,小弟需要用C Builder在多層應用上做一個Callback的功能,也就是從Server上調用Client上的Function。但不知道該怎樣寫。目前我只找到Dephi的例子。有沒有人知道該怎樣寫,或是有C Builder的例子呀?可否告知您哪裡不懂, 我幫您解釋. Server做法: 1.在Type Library定義IClient介面, 且定義好要讓Server呼叫的Function. 2.在RDM裡定義一個FCallback: OleVariant;的變數, 然後以此變數來呼叫Client的Function. 3.在Type Library的RemoteDataModule介面上定義好要給Client呼叫的Function, 也可用DataSetPrivoder的DataRequest事件處理, 一定要有一個SetCallback的Function讓Client呼叫. procedure TServer.SetCallback(aCallback: OleVariant); begin FCallback := aCallback; end;Client做法: 1.加入Server Type Library的Unit. 2.定義TClient類別. TClient = class(TAutoIntfObject, IClient) protected 這裡定義和Server Type Library裡IClient相同的Function, 且在implementation下定義好要執行的程式碼. end;3.宣告一個FClient: TClient;的變數. 4.在FormCreate給執行Server的SetCallback Function. procedure TfrmClient.FormCreate(Sender: TObject); var typelib: ITypeLib; begin SocketConnection1.Connected:=true; OleCheck(LoadRegTypeLib(LIBID_CallbackSrv, 1, 0, 0, typelib)); // 上面LIBID_CallbackSrv為您Server Type Library裡的機碼 FClient:=TClient.Create(typelib, IClient); SocketConnection1.AppServer.SetCallback(FClient as IDispatch); end;ps.一定得用SocketConnection才有Callback的功能, 且SupportCallbacks要設成True才行. <iFrame src="http://www.coss.com.tw/jieshu/sign.htm" width=400 height=105 scolling="NO" border="0"></iFrame> 震江系統(股)公司: http://www.coss.com.tw/ 捷舒軟體設計坊: http://www.coss.com.tw/jieshu/
------
人生有夢,逐夢而行 人若為善,福雖未至,禍已遠離 人若為惡,禍雖未至,福已遠離 http://www.taconet.com.tw/jieshu/ |
alvinmeng70
一般會員 發表:7 回覆:2 積分:1 註冊:2005-03-09 發送簡訊給我 |
非常感謝版主的提示,Dephi的例子我運行調試過,沒有什麼問題。但關鍵是C Builder的很多寫法和Dephi有差異,寫不好老是報位址錯誤。下麵是我的寫法:
在Client端的Unit1.h中
class TClient:public TAutoIntfObject
{
protected:
HRESULT __safecall Progress(int RecNo, int RecCount, Word &Continue);
HRESULT __safecall Done(void);
private:
void *__IClient;
public:
__fastcall TClient(const _di_ITypeLib TypeLib, const GUID &DispIntf) : Comobj::TAutoIntfObject(TypeLib, DispIntf) { };
__fastcall virtual ~TClient(void);
operator IClient*(void) { return (IClient*)&__IClient; }; };
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TEdit *Edit1;
TSocketConnection *SocketConnection1;
TButton *Button2;
TButton *Button3;
TClientDataSet *ClientDataSet1;
TDataSource *DataSource1;
TDBGrid *DBGrid1;
TButton *Button4;
TDCOMConnection *DCOMConnection1;
TButton *Button5;
TListBox *ListBox1;
TButton *Button6;
TButton *Button7;
TClientDataSet *ClientDataSet2;
TButton *Button8;
TLabel *Label1;
TCheckBox *CheckBox1;
TButton *Button9;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall Button4Click(TObject *Sender);
void __fastcall Button5Click(TObject *Sender);
void __fastcall Button6Click(TObject *Sender);
void __fastcall Button7Click(TObject *Sender);
void __fastcall Button8Click(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall Button9Click(TObject *Sender);
private: // User declarations
TClient *FClient;
public: // User declarations
//IRemoteServerModuleDisp TempInterface;
// TDispatchConnection *TempInterface;
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif 在Client端的Unit1.cpp中
void __fastcall TForm1::FormCreate(TObject *Sender)
{
ITypeLib *typelib;
if (!SocketConnection1->Connected)
SocketConnection1->Connected = true;
OleCheck(LoadRegTypeLib(LIBID_LoopServer, 1, 0, 0, &typelib));
FClient=new TClient(typelib,IID_IClient);
IDispatch* disp = (IDispatch *)(SocketConnection1->AppServer);
IRemoteServerModuleDisp TempInterface((IRemoteServerModule*) disp); TempInterface.SetCallback((TVariant *)FClient ); }
//--------------------------------------------------------------------------- void __fastcall TForm1::Button9Click(TObject *Sender)
{
IDispatch* disp = (IDispatch *)(SocketConnection1->AppServer);
IRemoteServerModuleDisp TempInterface((IRemoteServerModule*) disp);
TempInterface.TraverseTable();
}
//------
HRESULT __safecall TClient::Done()
{
ShowMessage("Done!![Call Back]");
return 0;
} HRESULT __safecall TClient::Progress(int RecNo, int RecCount, Word &Continue)
{
Form1->Label1->Caption=RecNo "/" RecCount;
Application->ProcessMessages();
Continue =!(Form1->CheckBox1->Checked);
return 0;
} 在Server端RemoteDataModuleImpl.cpp中
STDMETHODIMP TRemoteServerModuleImpl::SetCallback(
TVariantInParam aCallback)
{
FCallback=aCallback;
return 0;
} STDMETHODIMP TRemoteServerModuleImpl::TraverseTable()
{
/ TOLEBOOL bContinue;
int iRecordCount;
RemoteServerModule->Table1->Open();
RemoteServerModule->Table1->First();
iRecordCount=RemoteServerModule->Table1->RecordCount;
bContinue=true;
IDispatch *Disp=(IDispatch *)(FCallback);
IClientDisp TempInterface((IClient*) Disp);
while ((!RemoteServerModule->Table1->Eof)&& bContinue.operator bool())
{
RemoteServerModule->Table1->Next();
TempInterface.Progress(RemoteServerModule->Table1->RecNo,iRecordCount,&bContinue);
}
RemoteServerModule->Table1->Close();
TempInterface.Done();
return 0;
}
但怎麼也調不通,一直報錯,請版主指點。
|
jieshu
版主 發表:42 回覆:894 積分:745 註冊:2002-04-15 發送簡訊給我 |
引言: 非常感謝版主的提示,Dephi的例子我運行調試過,沒有什麼問題。但關鍵是C Builder的很多寫法和Dephi有差異,寫不好老是報位址錯誤。可否Debug看看, 是跑到哪一行時出現錯誤, 這樣比較好幫您看看是哪裡的問題, 因為我對BCB不熟. <iFrame src="http://www.coss.com.tw/jieshu/sign.htm" width=400 height=105 scolling="NO" border="0"></iFrame> 震江系統(股)公司: http://www.coss.com.tw/ 捷舒軟體設計坊: http://www.coss.com.tw/jieshu/
------
人生有夢,逐夢而行 人若為善,福雖未至,禍已遠離 人若為惡,禍雖未至,福已遠離 http://www.taconet.com.tw/jieshu/ |
roger5089
一般會員 發表:0 回覆:1 積分:0 註冊:2005-03-23 發送簡訊給我 |
引言:not引言: 各位高手,小弟需要用C Builder在多層應用上做一個Callback的功能,也就是從Server上調用Client上的Function。但不知道該怎樣寫。目前我只找到Dephi的例子。有沒有人知道該怎樣寫,或是有C Builder的例子呀?可否告知您哪裡不懂, 我幫您解釋. Server做法: 1.在Type Library定義IClient介面, 且定義好要讓Server呼叫的Function. 2.在RDM裡定義一個FCallback: OleVariant;的變數, 然後以此變數來呼叫Client的Function. 3.在Type Library的RemoteDataModule介面上定義好要給Client呼叫的Function, 也可用DataSetPrivoder的DataRequest事件處理, 一定要有一個SetCallback的Function讓Client呼叫.procedure TServer.SetCallback(aCallback: OleVariant); begin FCallback := aCallback; end;Client做法: 1.加入Server Type Library的Unit. 2.定義TClient類別.TClient = class(TAutoIntfObject, IClient) protected 這裡定義和Server Type Library裡IClient相同的Function, 且在implementation下定義好要執行的程式碼. end;3.宣告一個FClient: TClient;的變數. 4.在FormCreate給執行Server的SetCallback Function.procedure TfrmClient.FormCreate(Sender: TObject); var typelib: ITypeLib; begin SocketConnection1.Connected:=true; OleCheck(LoadRegTypeLib(LIBID_CallbackSrv, 1, 0, 0, typelib)); // 上面LIBID_CallbackSrv為您Server Type Library裡的機碼 FClient:=TClient.Create(typelib, IClient); SocketConnection1.AppServer.SetCallback(FClient as IDispatch); end;ps.一定得用SocketConnection才有Callback的功能, 且SupportCallbacks要設成True才行. <iFrame src="http://www.coss.com.tw/jieshu/sign.htm" width=400 height=105 scolling="NO" border="0"></iFrame> 震江系統(股)公司: http://www.coss.com.tw/ 捷舒軟體設計坊: http://www.coss.com.tw/jieshu/
------
not |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |