Mega Code Archive

 
Categories / Delphi / Ide Indy
 

Using queued components in Delphi

Title: Using queued components in Delphi Question: Example showing queued components in Delphi. Answer: Queued Components are feature of COM+ based on Microsoft Message Queuing Services (MSMQ). They provide an easy way to invoke and execute components asynchronously. Processing can occur without regard to the availability or accessibility of either the sender or the receiver. In COM terms, a queue is a storage area that saves messages for later retrieval. Queuing provides a mechanism for connectionless communication. That is, the sender and receiver are not connected directly and communicate only through queues. Queuing provides a way to hold the information until the receiver is ready to obtain it. The sender and receiver are indirectly communicating so that each can operate independently, unaffected by the other. Here is a simple example of creating and using a queued component in Delphi 6. First we will create a server. All methods in your interfaces must use IN parameters only. Methods can not have return values. This is because there is no "real-time" connection between the client and server. Since you don't know exactly when the call will be processed the client cannot sit waiting for a response from the server. In Delphi 6 go to File | New | Other | ActiveX and open a new ActiveX Library. Next go back to this same menu option and add an Automation Object. Select a name for your server object. I used QdComponent. Leave the other options at the default and click OK. You should now see the type library editor. Add a new method here by clicking the interface IQdComponent and then clicking the green icon at the top for adding a new method. Call it Task1 and add a parameter called SendMessage. Make this parameter of type BSTR (WideString in Delphi). If you have your type library options set to show Pascal code (in Environment options) then this is what the text for your method should look like: procedure Task1(TaskMessage: WideString) [dispid $00000001]; safecall; Save your project. I called my project MyQdServer and my implementation unit (Unit1 by default) I named QdServer. Fill in the implementation code for the procedure TQdComponent.Task1 in unit QdServer. My component will simply display a message that is sent via the MessageString parameter. Compile, save all and close. Here is what the server unit looks like: unit QdServer; {$WARN SYMBOL_PLATFORM OFF} interface uses ComObj, ActiveX, MyQdServer_TLB, StdVcl, Dialogs; type TQdComponent = class(TAutoObject, IQdComponent) protected procedure Task1(const TaskMessage: WideString); safecall; { Protected declarations } end; implementation uses ComServ; procedure TQdComponent.Task1(const TaskMessage: WideString); begin ShowMessage(TaskMessage) end; initialization TAutoObjectFactory.Create(ComServer, TQdComponent, Class_QdComponent, ciMultiInstance, tmApartment); end. Installing the server In the control panel go to the Component Services tool. Expand the tree in order to see "COM+ Application". Right click on this folder and choose New | Application. Choose "Create an empty application" and follow the prompts. When you are done find your new application listed below, right-click on it and go to properties. Go to the Queuing tab and check both check boxes - Queued and Listen. Listen means that any incoming messages on this queue will be processed immediately when it is active. Under your new application right click on Components and choose New | Component. Choose "Install new component(s)" and follow the prompts to find and install your DLL. Next expand the tree to show the interfaces and right click on IQdComponent to show the properties. Click the Queuing tab and check "Queued". If you see an error message Stating that MSMQ is not running then you probably do not have it installed. It is not installed by default and can be installed by going to Add/Remove programs if you have your OS CDs. Creating a Client Create a new Delphi Application. Add MyQdServer_TLB to your uses clause. Add a TButton and a TEdit. You will need to create your object when your application starts. To do this you will use a Moniker which specifies the component information. The syntax for this is shown in the FormShow event handler below. This moniker can also contain Server.InterfaceName instead of the GUID/CLSID. unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComObj, ActiveX, MyQdServer_TLB; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } QInterface : IQdComponent; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} Function NewCoGetObject(pazName: PWideChar; pBindOptions: PBindOpts; const iid: TIID; out ppv): HResult; stdcall; external 'ole32.dll' name 'CoGetObject'; procedure TForm1.Button1Click(Sender: TObject); begin QInterface.Task1(Edit1.Text); Edit1.Clear; end; procedure TForm1.FormShow(Sender: TObject); var QMoniker : PWideChar; begin QMoniker := 'Queue:/new:{A7ECB8CA-9BBB-4BAB-B018-33210095AE34}'; OleCheck(NewCoGetObject(QMoniker, nil, IQdComponent, QInterface)); end; end. Run the client and send a text string. You will notice the message does not appear because you have not started the server. There are a few ways to start the server. The simplest is to go back to the component services in control panel, find your server, right click on it and choose 'Start'. After you start the server the message should appear.