Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

GetMessage в отдельном потоке


Страницы:   1 2 3 4

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]

Так какой раздел мне надо штудировать ?


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо