-
Здравствуйте. Подскажите пожалуйста как отправить сообщение во второй поток и как его там поймать. А то, я что запутался окончательно вроде отправка осуществляется при помощи функции PostThreadMessage, а прием PeekMessage. Но вот только PostThreadMessage возвращает False, a GetLastError 1159. Что я не так делаю?
-
Что говорит SysErrorMessage(GetLastError) ?
-
> Что говорит SysErrorMessage(GetLastError) ?
'Сообщение может быть использовано только с операциями синхронизации' А что это значит?
-
А какое конкретно сообщение ты посылаешь ?
-
var
Data:tagCOPYDATASTRUCT;
PostThreadMessage(ThreadID,WM_COPYDATA,0,lParam(@Data));
-
Тогда отлуп ты получаешь вполне резонно - сообщение с кодом WM_COPYDATA есть специальный зарезервированный вид сообщения, которое можно отправлять только синхронно, т.е. с использованием SendMessage, а не Post[Thread]Message
-
Ясно спасибо. А как его отловить во втором потоке?
-
Прежде чем его "ловить" нужно осознать, что ф-ция SendMessage подразумевает адресатом окно (или окна) , а не нить. Целевая нить у тебя создает хоть одно окно ?
-
Это я знаю :-) Окно у меня есть. И оно умеет обрабатывать это сообщение. Мне нужно его как-то перехватить перед тем как окно его обработает. Это возможно?
-
> Окно у меня есть
Оно откуда взялось ? Его какая нить создала - целевая ?
-
Я пишу на VCL окно стандартное. Целевая нить и основной поток это одно и тоже?
-
Поток (кодовый) = нить = тред = thread.
Если ты отправляешь сообщение основному потоку, то разумеется он является целевым потоком.
-
Определись, кому ты посылаешь сообщение - потоку или окну..
-
Мне нужно отправить это сообщение в созданный поток. И из созданного потока обратно окну. Oкну можно его отправить например так SendMessage(Form1.Handle,WM_COPYDATA,0,lParam(i)) .
Но вот как отправить это сообщение в созданный мною поток? И как его там обработать, я не могу понять. Может ли мною созданный поток, выгребать сообщения из очереди сообщений окна?
-
> как отправить это сообщение в созданный мною поток?
Никак. Только окну его можно отправить. Меняй концепцию и логику.
> Может ли мною созданный поток, выгребать сообщения из очереди > сообщений окна?
А собссно зачем ? Поясни ..
-
Я отправляю сообщение окну. Поток его забирает из очереди собщений, например занимает семафор, а процедура обработки сообщения целевого потока в зависимости от состояния семаформа решает обрабатывать его или нет. Или я вообще неправильно думаю.
-
> Поток его забирает из очереди собщений
Его забирает тот поток, который создал окно, т.е. в твоем случае основной.
Далее этот поток смотрит на семафор - если он занят, то делает с полученным сообщением одно действие , иначе другое.
-
Спасибо. Теперь пойду валить препода. :-)
-
> пойду валить препода
Как бы он тебя не завалил)
-
У меня возник еще вопросик. Я во втором потоке создал окно все вроде работает, но функция обработки сообщений созданного окна выполняется в основном потоке, как ее выполнить в потоке создавшем окно? Вот код на всякий случай.
unit Unit1;
var Thread2:THandle;
FormThread2:HWND;
Procedure Query;
function SecondWinProc (hWnd: THandle; nMsg: UINT;wParam, lParam: Cardinal): Cardinal; export; stdcall;
begin
if nMsg=WM_COPYDATA then
else
if nMsg=WM_SEND_DATA then
end;
var xPos,yPos,nWidth,nHeight : Integer;
var wc : TWndClassEx;
Msg : TMsg;
begin
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@SecondWinProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=Thread2;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='SecondForm';
RegisterClassEx(wc);
xPos:=0;
yPos:=0;
nWidth:=0;
nHeight:=0;
FormThread2:=CreateWindowEx(
0,
'SecondForm',
'SecondForm',
ws_overlappedwindow,
xPos,
yPos,
nWidth,
nHeight,
0,
0,
Thread2,
nil
);
While GetMessage(Msg,FormThread2,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Thread2:=CreateThread(nil,2048,@Query,nil,0,ThreadID2);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SendMessage(FormThread2,WM_COPYDATA,0,lParam(123));
SendMessage(FormThread2,WM_COPYDATA,0,Integer(321));
end;
Все я не стал копировать, но я думаю смысл от этого не изменится.
|