You are passing the data through lParam, wParam comes to the other empty process.
SendMessage(HWND_BROADCAST, WM_SHUTDOWN_THREADS, 0, LongInt(@MyData));
↑
If I understand what you want to do, you will have a problem with the current code, because it is trying to pass the address of a structure to another process, an address only has meaning within a single process.
Because a process is a set of segments, all running in a single address space, each process has at least one segment, the main segment. Only segments of the same process can do the sharing resources, such as accessing any valid address on process address space.
You can do what the Vinicius Gobbo A. de Oliveira said in comment, utilise named Pipes. Here have an article explaining about the inter-process communication by means of named Pipes, applicable for Delphi and . NET.
An alternative is map the file in memory using the functions CreateFileMapping
to create the mapping, OpenFileMapping
to open the file and MapViewOfFile
to read the contents of the file.
An alternative (a little simpler) that can be used is the Data Copy feature(Data Copy) which allows data to be sent from one application to another.
To use it you will have to send the message WM_COPYDATA
through function PostMessage
or SendMessage
(to send to a segment of the same process can be used PostThreadMessage
, but that is not the case!).
Data must be passed to a structure COPYDATASTRUCT
.
The example below will send a structure that will contain the Handle and the PID of the process that will send the message.
type
TMyStruct = packed record // Estrutura que vai ser enviada a outro processo
lpHandle: HWND;
lpProcessid: DWORD;
end;
procedure PostData; // Método responsável por enviar
var
H: HWND;
MyStruct: TMyStruct;
copyDataStruct: TCopyDataStruct;
Begin
Try
MyStruct.lpHandle := Application.Handle; // Pega a handle da aplicação
MyStruct.lpProcessid := GetCurrentProcessId(); // Pega o PID
copyDataStruct.cbData := SizeOf(MyStruct); // Tamanho em bytes dos dados apontados em lpdata
copyDataStruct.lpData := @MyStruct; // Dados que serão enviados a outro processo
H := FindWindow(nil, 'Form2'); // Pega a handle da janela que tenha o Form2 no título
if IsWindow(h) then // Se for uma janela existente
SendMessage(h, WM_COPYDATA, 0, Integer(@copyDataStruct)); // Envia a mensagem
Except
End;
end;
To receive the message (application you will receive):
type
TMyStruct = packed record // Estrutura que vai receber os dados do outro processo
lpHandle: HWND;
lpProcessid: DWORD;
end;
type
TForm1 = class(TForm)
private
{ Private declarations }
protected
procedure WMCopyData(var Msg : TWMCopyData); message WM_COPYDATA; // Quando a aplicativo receber essa mensagem
public
{ Public declarations }
end;
// .....
procedure TForm1.WMCopyData(var Msg: TWMCopyData); // Método que vai tratar a mensagem WM_COPYDATA
var
MyStruct: TMyStruct;
TempHandle, TempProcessID: string;
Begin
MyStruct := TMyStruct(Msg.CopyDataStruct.lpData^); // Coloca em MyStruct o que foi recebido
TempHandle := Inttostr (MyStruct.lpHandle); // Coloca em TempHandle a handle recebida de outro proceso
TempProcessID := Inttostr( MyStruct.lpProcessid); // Coloca em TempProcessID o PID do outro processo
// Daqui em diante fazer algo...
ShowMessage(Format('Dados do outro processo:'#13'Handle %s ProcessID %s', [TempHandle, TempProcessID]));
end;
The above example was done with forms, some things will not work for an application console or for a DLL, you will have to adapt according to your need.
There is a good article that explains about this in:
Who sends and who receives are different processes? If yes, there is your explanation. You are sending an address in the parameter
LongInt(@MyData)
, which is invalid for the process receiving the message. I believe this form of IPC does not support data of arbitrary sizes.– Vinícius Gobbo A. de Oliveira
Thank you for answering... and yes are different processes, each process carries a different dll and would like them to communicate. What is the solution to this ?
– Anderson de Oliveira
Use a socket or named pipe. Named pipe is faster than sockets, but usually the staff feels more comfortable with socket. I couldn’t find an accessible tutorial in Delphi, but I did find one in C++, easily translatable to Delphi: http://avid-insight.co.uk/2012/03/introduction-to-win32-named-pipes-cpp/
– Vinícius Gobbo A. de Oliveira