|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#16
|
|||
|
|||
да, пример рабочий.
нужно чтобы программа А подгружала длл и вызывала в длл sendmessage окну программы B. у вас программа А и B в одном - test. |
#17
|
||||
|
||||
Да, в разных процессах (ДЛЛ в процессе A, окно в процессе B) вроде не заработает. Придется копировать структуру.
ЗЫЖ в одном процессе не стоит передавать адрес локальной структуры: структура будет в стеке, и в теории может затереться до приема её окном (хотя на практике шанс конечно стремится к нулю, но отличен от нуля; а по закону Мерфи это значит, что в самый неподходящий момент она затрётся). Лучше сделать глобальную структурку, или же выделить под нее память. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 11.03.2012 в 19:14. |
#18
|
||||
|
||||
Код:
Form1:=TForm.Create; Form1.Show();... Хотя я как-то писал вроде формочку, которая была целиком в DLLке. Никаких проблем не возникало. Поищу, может найду. UPD: нашел. Писал так: Код:
Form2 := TForm2.Create(Ctrl^); Windows.SetParent(Form2.Handle, Ctrl^.Handle); Windows.SetWindowPos(Form2.Handle, 0, 0, 0, Ctrl^.Width, Ctrl^.Height, 0); Form2.BorderStyle := bsNone; Form2.Show; jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 11.03.2012 в 19:31. |
#19
|
||||
|
||||
Цитата:
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#20
|
||||
|
||||
Оказывается, SendMessage блокирующий. Не знал, спасибо.
Тогда согласен, локальные юзать можно в одном процессе. jmp $ ; Happy End! The Cake Is A Lie. |
#21
|
||||
|
||||
Вариация, использующая 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 в.д. Последний раз редактировалось angvelem, 12.03.2012 в 00:45. |