d32coder
asked on
more dll help
App1 can call processes in a dll
App2 can send data directly to App1.
App1 cannot send messages directly to App2. (App1 is not my own creation)
Dll unloads itself between calls (I don't want to keep it loaded as it may not be used frequently enough to warrant that).
Goal: Event driven messages from App1 to App2 with dll as mediator.
Details: App1 calls a process in the dll (this already works). DLL then sends a string to App2 (initiates the event). The help files say Sendmessage() will not work for this but that seems wrong.
Sample code, please, for DLL initiating a message with a string (or PChar) to App2 and create an event in App2 to receive the string.
I already have code for locating the HWND for each app.
Thanks for you time.
Don
App2 can send data directly to App1.
App1 cannot send messages directly to App2. (App1 is not my own creation)
Dll unloads itself between calls (I don't want to keep it loaded as it may not be used frequently enough to warrant that).
Goal: Event driven messages from App1 to App2 with dll as mediator.
Details: App1 calls a process in the dll (this already works). DLL then sends a string to App2 (initiates the event). The help files say Sendmessage() will not work for this but that seems wrong.
Sample code, please, for DLL initiating a message with a string (or PChar) to App2 and create an event in App2 to receive the string.
I already have code for locating the HWND for each app.
Thanks for you time.
Don
Hi,
You may use system-wide message defined by yourself and Application.OnMessage to receive it:
in the dll:
// declaration
var TheMessage: cardinal;
// initialization
TheMessage := RegisterWindowMessage(PCha r('geobul' ));
// sending the message
PostMessage(<WindowHandle> , TheMessage, 0,0);
in the App2:
// in TForm1 class
procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
// declaration
var TheMessage: cardinal;
// in Form1.OnCreate register the same message
TheMessage := RegisterWindowMessage(PCha r('geobul' ));
Application.OnMessage := AppMessage; // assign the event handler
// and
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var
i,j : integer;
begin
// our registered custom message received
if (Msg.Message = TheMessage) then begin
// do here what you want
Handled := True;
end;
end;
Regards, Geo
You may use system-wide message defined by yourself and Application.OnMessage to receive it:
in the dll:
// declaration
var TheMessage: cardinal;
// initialization
TheMessage := RegisterWindowMessage(PCha
// sending the message
PostMessage(<WindowHandle>
in the App2:
// in TForm1 class
procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
// declaration
var TheMessage: cardinal;
// in Form1.OnCreate register the same message
TheMessage := RegisterWindowMessage(PCha
Application.OnMessage := AppMessage; // assign the event handler
// and
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var
i,j : integer;
begin
// our registered custom message received
if (Msg.Message = TheMessage) then begin
// do here what you want
Handled := True;
end;
end;
Regards, Geo
ASKER
If I understand this so far, the 'GeoBul' message is a static message. Do my all of my messages have to be pre-defined or can I send any run-time-defined PChar(string) in there?
ASKER
Sorry, that was vague.. What I need is a message that I can attach an undefined string, perhaps as a param. If GeoBul is the message can I pass a param along with it?
example
message = 'GeoBul' (I realize this is arbitrary)
param = 'C:\Temp\AnyFile.txt'
param2 = '64k'
Thanks again,
Don
example
message = 'GeoBul' (I realize this is arbitrary)
param = 'C:\Temp\AnyFile.txt'
param2 = '64k'
Thanks again,
Don
Sending a message from a .DLL to an App that has that .DLL loaded can get information to the app using Pointers. Since the App and the Dll share memory space, pointers are an effective way to get info to or from a .DLL.
you could add a procedure like this to your .DLL
procedure SendPointer(Handle: THandle);
var
SomeText, OtherText: PChar;
Recieved: Boolean
begin
{Handle is the Handle of the App you want to sent this to}
SomeText := 'Attention this is an improtant message, maybe';
OtherText := 'This is a text of the Other';
if SendMessage(Handle, WM_USER+33, Integer(SomeText), Integer(OtherText)) = 33 then
Recieved := True else
Recieved := False;
{you can send other types of variables, just use pointers}
end;
and in your app you have to be sure the .DLL is loaded and get the message to your form as WM_USER+ whatever. Here's a kind of Form message procedure,
procedure TForm1.WindProc(var Message: TMessage);
var
SomeText, OtherText: String;
begin
if Message.Msg = WM_USER+33 then
begin
SomeText := PChar(Message.WParam);
OtherText := PChar(Message.LParam);
Label3.Caption := SomeText;
if Length(SomeText) > 0 then
Message.Result := 33 else
Message.Result := 0;
Exit;
end;
inherited;
end;
- - - -- - - - - - - - - - - - - - --
hope this helps you
you could add a procedure like this to your .DLL
procedure SendPointer(Handle: THandle);
var
SomeText, OtherText: PChar;
Recieved: Boolean
begin
{Handle is the Handle of the App you want to sent this to}
SomeText := 'Attention this is an improtant message, maybe';
OtherText := 'This is a text of the Other';
if SendMessage(Handle, WM_USER+33, Integer(SomeText), Integer(OtherText)) = 33 then
Recieved := True else
Recieved := False;
{you can send other types of variables, just use pointers}
end;
and in your app you have to be sure the .DLL is loaded and get the message to your form as WM_USER+ whatever. Here's a kind of Form message procedure,
procedure TForm1.WindProc(var Message: TMessage);
var
SomeText, OtherText: String;
begin
if Message.Msg = WM_USER+33 then
begin
SomeText := PChar(Message.WParam);
OtherText := PChar(Message.LParam);
Label3.Caption := SomeText;
if Length(SomeText) > 0 then
Message.Result := 33 else
Message.Result := 0;
Exit;
end;
inherited;
end;
- - - -- - - - - - - - - - - - - - --
hope this helps you
ASKER
Thanks Slick. I didn't know that.
"Since the App and the Dll share memory space, pointers are an effective way to get info to or from a .DLL"
Can 2 Apps have the same .dll loaded at the same time or does each app make it's own copy? If App1 posts data to the dll and App2 has the dll loaded, seems to me like there would be 2 copies of the dll and thus not sharing the same data between the 2 copies.
Hope I'm wrong.
Don
"Since the App and the Dll share memory space, pointers are an effective way to get info to or from a .DLL"
Can 2 Apps have the same .dll loaded at the same time or does each app make it's own copy? If App1 posts data to the dll and App2 has the dll loaded, seems to me like there would be 2 copies of the dll and thus not sharing the same data between the 2 copies.
Hope I'm wrong.
Don
As far as I can figure, but I whole Windows system memory management is not entirely clear to me, I think the functional data memory (the .DLL file loaded) is a single copy. There may be some memory separation of function parameters and variables acording to what process calls the function. But I Know two apps can not share info with a pointer sent in a SendMessage.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
P.S: If App1 is not your application, how to you make it load your dll? It's possible, of course, just want to know, whether you really succeeded in that... :-)
ASKER
mIRC has a script language that allows it. Thanks for the tip on COPYDATA, I'll look into that right now.
Don
Don
ASKER
Borland had a FAQ (link below) that shows WM_COPYDATA code. It does exactly what I needed. Thanks to all for responses.
http://community.borland.com/article/0,1410,16525,00.html
Don
http://community.borland.com/article/0,1410,16525,00.html
Don
ASKER
...Windows message. OnMessage only receives messages that are posted to the message queue, not those sent directly with the Windows API SendMessage function.