![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
GetMessage в отдельном потоке
msg © (2006-03-09 12:11:00)В отдельном потоке (TThread) создаю форму:
procedure TTest.Execute;
var
msg:TMsg;
wnd:HWND;
wc:WNDCLASS;
begin
wc.style:=0;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=hInstance;
wc.hIcon:=0;
wc.hCursor:=0;
wc.hbrBackground:=GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName:=nil;
wc.lpszClassName:='asdasd';
wc.lpfnWndProc:=@WndProc;
Windows.RegisterClass(wc);
wnd:=CreateWindow(
'asdasd',
'Hello world',
WS_CAPTION,
10,
10,
200,
80,
HWND_DESKTOP,
0,
hInstance,
nil
);
while GetMessage(Msg,wnd,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
DestroyWindow(wnd);
Windows.UnRegisterClass('asdasd', hInstance);
end;
WndProc выглядит примерно так:
function WndProc(wnd:HWND; msg:UINT; w:UINT; l:UINT):UINT;stdcall;
var
begin
Result:=0;
case msg of
WM_QUIT: ;
WM_PAINT: ;
else
Result:=DefWindowProc(wnd,msg,w,l);
end;
end;
В основном потоке создаю отдельный поток:
var
T: TTest;
procedure TForm1.Button1Click(Sender: TObject);
begin
T := TTest.Create(true);
with T do
begin
FreeOnTerminate:=true;
Resume;
end;
end;
и посылаю сообщение:
procedure TForm1.Button2Click(Sender: TObject);
var
h:hWnd;
begin
h := FindWindow('asdasd', nil);
SendMessage(h, WM_QUIT, 0, 0);
end;
GetMessage ни в какую не желает принимать сообщение, даже если написать GetMessage(Msg,0,0,0), в то же время WndProc сообщение принимает. Я так понимаю, что посланные мной сообщения принимает обработчик главного потока. Так ли это? И нужен ли вообще, в таком случае, GetMessage в отдельном потоке?
Eraser (2006-03-09 18:52:00) [41]
> Crash Coredump © (09.03.06 18:52) [35]
из любой.
Crash Coredump (2006-03-09 18:52:00) [42]Eraser © (09.03.06 18:48) [33]
> не осуществляет выборку.
Из какой очереди сообщений ? Их несколько у потока.
Crash Coredump (2006-03-09 18:51:00) [43]Leonid Troyanovsky © (09.03.06 18:45) [32]
> Никуда оно не перейдет, т.е., выхода из GetMessage при
> обработке nonqueued message не будет.
Об том и речь. С самого начала.
> Ну, а собщения, которые SendMessage из другого потока
> обрабатываются в оконной процедуре потоком-получателем.
> А для того, чтобы оный смог обработать сообщение, он
> должен находится в состоянии ожидания, достигаемого,
> например, той же GetMessage.
Или другими функциями ожидания, связанными с очередью сообщений потока. Вот честно, не проверял, будут ли обрабатываться сообщения, если поток будет ждать какого-нибудь объекта ядра функцией WaitForSingleObject, а что Рихтер на эту тему писал, не помню.
Eraser (2006-03-09 18:48:00) [44]to Crash Coredump © (09.03.06 18:42) [31]
> msg (09.03.06 12:11)
> И нужен ли вообще, в таком случае, GetMessage в отдельном
> потоке?
нужен.
> MsgWaitForMultipleObjects
в данном случае применять эту функцию - извращение.
> WaitMessage
не осуществляет выборку.
так что нормальную очередь сообщений можно построить только на Get/PeekMessage ... остальное - стёб.. imho.
Leonid Troyanovsky (2006-03-09 18:45:00) [45]
> Crash Coredump © (09.03.06 18:22) [27]
> Значит, что
> а) GetMessage возвращает результат (и заполненную структуру
> MSG при ненулевом результате)
> б) Выполнение переходит на команду, следующую за вызовом
> GetMessage
Никуда оно не перейдет, т.е., выхода из GetMessage при
обработке nonqueued message не будет.
В общем-то, картина не так уж проста, поэтому Рихтер и
писал о том, что у потока целых четыре очереди сообщений,
включая и такие, как очередь синхронных сообщений
и очередь ответных сообщений.
Ну, а собщения, которые SendMessage из другого потока
обрабатываются в оконной процедуре потоком-получателем.
А для того, чтобы оный смог обработать сообщение, он
должен находится в состоянии ожидания, достигаемого,
например, той же GetMessage.
--
Regards, LVT.
Crash Coredump (2006-03-09 18:42:00) [46]
> без Get/PeekMessage никуда.
WaitMessage, MsgWaitForMultipleObjects...
> не верно, что ты и доказал сам
Мы сабж будем читать или как ?
Eraser (2006-03-09 18:36:00) [47]
> Crash Coredump © (09.03.06 18:32) [29]
> Вызывает ее GetMessage, PeekMessage, WaitMessage
ну вот! правильно. Об чём спор тогда...
а вот это
> Crash Coredump © (09.03.06 17:27) [25]
> Ну и этим все сказано - сообщение, посланное по SendMessage,
> обрабатывается оконной процедурой, а не появляется в результате
> вызова GetMessage.
не верно, что ты и доказал сам.
без Get/PeekMessage никуда.
Crash Coredump (2006-03-09 18:32:00) [48]
> а кто оконную процедуру вызывает, если сообщение из другово
> потока?
Вызывает ее GetMessage, PeekMessage, WaitMessage, при этом не прерывая своего исполнения до тех пор, пока в очереди нет сообщений.
Напиши пример с окном, которое реагирует на два разных сообщения, из другого потока посылай ему сообщения первого типа через SendMessage, а второго через PostMessage, посмотри, как будет происходить выполнение цикла
while GetMessage .... do begin
// в этом месте можешь сигнализировать каким-то образом, что GetMessage отработал
TranslateMessage
DispatchMessage
end;
Eraser (2006-03-09 18:26:00) [49]
> Crash Coredump © (09.03.06 18:22) [27]
> Значит, что
> а) GetMessage возвращает результат (и заполненную структуру
> MSG при ненулевом результате)
> б) Выполнение переходит на команду, следующую за вызовом
> GetMessage
так точно.
А второй вопрос?
Crash Coredump (2006-03-09 18:22:00) [50]
> Что значит "появляется в результате вызова"?
Значит, что
а) GetMessage возвращает результат (и заполненную структуру MSG при ненулевом результате)
б) Выполнение переходит на команду, следующую за вызовом GetMessage
Eraser (2006-03-09 18:13:00) [51]
> Crash Coredump © (09.03.06 17:27) [25]
> Ну и этим все сказано - сообщение, посланное по SendMessage,
> обрабатывается оконной процедурой, а не появляется в результате
> вызова GetMessage.
Что значит "появляется в результате вызова"?
а кто оконную процедуру вызывает, если сообщение из другово потока?
Crash Coredump (2006-03-09 17:27:00) [52]Сергей М. © (09.03.06 17:23) [24]
> Ну и ?
Ну и этим все сказано - сообщение, посланное по SendMessage, обрабатывается оконной процедурой, а не появляется в результате вызова GetMessage.
Сергей М. (2006-03-09 17:23:00) [53]
> Ты, Серега, повежливее малость, а то опять чтением займешься
О да) .. тебе ли не знать) .. За дурика не держи.
..
Цитирую автора
> в то же время WndProc сообщение принимает.
Ну и ?
Crash Coredump (2006-03-09 17:15:00) [54]Сергей М. © (09.03.06 17:09) [20]
> If the specified window was created by the calling thread,
> the window procedure is called immediately as a subroutine
Кто бы спорил ? И через GetMessage не проходит, об чем я и говорю.
GetMessage сработает на WM_QUIT только если в очереди потока будет стоять флаг QUIT. А если WM_QUIT послано через SendMessage, то в очередь оно не попадет. Недаром придумали вызов PostQuitMessage
begin...end (2006-03-09 17:14:00) [55]> Сергей М. © (09.03.06 17:09) [20]
> If the specified window was created by the calling thread,
> the window procedure is called immediately as a subroutine.
Это к чему? В вопросе потоки разные, вообще-то.
Сергей М. (2006-03-09 17:13:00) [56]
> GetMessage ни в какую не желает принимать сообщение
Бред сивой кобылы.
Эта ф-ция не занимается каким-то там "приемом".
Эта ф-ция занимается ожиданием и выборкой сообщений, отправленных из потоков отличных от того, который вызвал эту ф-цию.
Сергей М. (2006-03-09 17:09:00) [57]
> Crash Coredump © (09.03.06 17:01) [17]
Читать ремарки ! До полного просветления !
Там сказано :
If the specified window was created by the callingthread, the window procedure is called immediatelyas a subroutine.
Эни квешнз ?
Crash Coredump (2006-03-09 17:08:00) [58]Сергей М. © (09.03.06 17:05) [18]
Ты, Серега, повежливее малость, а то опять чтением займешься.
И заодно почитай первый пост из темы:
"GetMessage ни в какую не желает принимать сообщение, даже если написать GetMessage(Msg,0,0,0), в то же время WndProc сообщение принимает"
при ситуации
"GetMessage ни в какую не желает принимать сообщение, даже если написать GetMessage(Msg,0,0,0), в то же время WndProc сообщение принимает"
Сергей М. (2006-03-09 17:05:00) [59]
> Crash Coredump
Ты, чудо, сам-то себе можешь описать ситуацию. когда один и тот же кодовый поток умудрился одновременновызвать две ф-ции ?)
Crash Coredump (2006-03-09 17:01:00) [60]Сергей М. © (09.03.06 17:00) [15]
Так какой раздел мне надо штудировать ?