Вариация, использующая WM_COPYDATA:
Вызывающее приложение
Код:
program Test;
uses
Windows, Messages;
type
TSetMessage = procedure; stdcall;
const
szAppName = 'MainForm';
szCaptionName = 'test';
var
Window : HWND;
Msg : TMsg;
WndClass : TWndClassEX;
SizeX, SizeY : Integer;
hDll : HMODULE;
hBtn : HWND;
SetMessage : TSetMessage;
//---------------------------------------------------------
procedure InitApp(Wnd : HWND);
begin
hDLL := LoadLibrary(PChar('mydll.dll'));
if hDLL = 0 then
Exit;
@SetMessage := GetProcAddress(hDLL, 'SetMessage');
if Addr(SetMessage) = NIL then
Exit;
hBtn := CreateWindow('BUTTON', 'Жми', WS_CHILD or WS_VISIBLE, 280, 400, 80, 25, Wnd, 100, hInstance, NIL);
end;
//---------------------------------------------------------
procedure DeInitApp(Wnd : HWND);
begin
DestroyWindow(hBtn);
if hDll <> 0 then
FreeLibrary(hDLL);
end;
//---------------------------------------------------------
function MainProc(Wnd : HWND; Msg : Integer; wParam, lParam : Longint) : Integer; stdcall;
begin
Result := 0;
case Msg of
WM_CREATE : InitApp(Wnd);
WM_COMMAND :
case LOWORD(wParam) of
100 :
if hDll <> 0 then
SetMessage;
end;
WM_CLOSE : DestroyWindow(Wnd);
WM_DESTROY :
begin
DeInitApp(Wnd);
PostQuitMessage(0);
Exit;
end;
end;
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
//---------------------------------------------------------
begin
SizeX := 640;
SizeY := 480;
FillChar(WndClass, SizeOf(TWndClassEx), 0);
WndClass.cbSize := SizeOf(TWndClassEx);
WndClass.style := CS_HREDRAW or CS_VREDRAW;
WndClass.lpfnWndProc := @MainProc;
WndClass.cbClsExtra := 0;
WndClass.cbWndExtra := 0;
WndClass.hInstance := hInstance;
WndClass.hCursor := LoadCursor(0, IDC_ARROW);
WndClass.hbrBackGround := GetSysColorBrush(COLOR_BTNFACE);
WndClass.lpszClassName := szAppName;
if RegisterClassEx(WndClass) = 0 then
Halt(255);
Window := CreateWindowEx(0, szAppName, szCaptionName,
WS_DLGFRAME or WS_SYSMENU or WS_MINIMIZEBOX,
0, 0, SizeX, SizeY, 0, 0, hInstance, NIL);
ShowWindow(Window, SW_SHOW);
while(GetMessage(Msg, 0, 0, 0)) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
Halt(Msg.wParam);
end.
Получающее приложение
Код:
program Main;
uses
Windows, Messages;
const
szAppName = 'SuperMainForm';
szCaptionName = 'test';
var
Window : HWND;
Msg : TMsg;
WndClass : TWndClassEX;
SizeX, SizeY : Integer;
//---------------------------------------------------------
function MainProc(Wnd : HWND; Msg : Integer; wParam, lParam : Longint) : Integer; stdcall;
var
cds : PCOPYDATASTRUCT;
St : AnsiString;
Buf : array[Word] of AnsiChar;
begin
Result := 0;
case Msg of
WM_COPYDATA :
begin
cds := PCopyDataStruct(lParam);
if (cds^.dwData = DWORD($12345678)) then
begin
lstrcpynA(@Buf[0], cds^.lpData, cds^.cbData);
SetString(St, Buf, cds^.cbData);
if St <> '' then
MessageBox(Wnd, PChar(St), '', MB_OK);
end;
end;
WM_CLOSE : DestroyWindow(Wnd);
WM_DESTROY :
begin
PostQuitMessage(0);
Exit;
end;
end;
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
//---------------------------------------------------------
begin
SizeX := 320;
SizeY := 240;
FillChar(WndClass, SizeOf(TWndClassEx), 0);
WndClass.cbSize := SizeOf(TWndClassEx);
WndClass.style := CS_HREDRAW or CS_VREDRAW;
WndClass.lpfnWndProc := @MainProc;
WndClass.cbClsExtra := 0;
WndClass.cbWndExtra := 0;
WndClass.hInstance := hInstance;
WndClass.hCursor := LoadCursor(0, IDC_ARROW);
WndClass.hbrBackGround := GetSysColorBrush(COLOR_BTNFACE);
WndClass.lpszClassName := szAppName;
if RegisterClassEx(WndClass) = 0 then
Halt(255);
Window := CreateWindowEx(0, szAppName, szCaptionName,
WS_DLGFRAME or WS_SYSMENU or WS_MINIMIZEBOX,
800, 0, SizeX, SizeY, 0, 0, hInstance, NIL);
ShowWindow(Window, SW_SHOW);
while(GetMessage(Msg, 0, 0, 0)) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
Halt(Msg.wParam);
end.
dll
Код:
library mydll;
uses
Windows, Messages;
const
St = 'Hello World';
procedure SetMessage; stdcall; export;
var
Wnd : HWND;
cds : COPYDATASTRUCT;
begin
Wnd := FindWindow('SuperMainForm', NIL);
if Wnd <> 0 then
begin
cds.dwData := $12345678;
cds.lpData := @St[1];
cds.cbData := Length(St) + 1;
SendMessage(Wnd, WM_COPYDATA, 0, DWORD(@cds));
end
else
MessageBox(0, 'fail', 'Error', MB_OK);
end;
exports
SetMessage;
begin
end.
Кроме передачи через WM_COPYDATA, можно также использовать:
1. Обмен через файлы
2. Каналы передачи данных Pipe
3. Каналы передачи данных Mailslot
Добавлено:
Статью с примерами, можно прочитать здесь.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
|