Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.06.04;
Скачать: [xml.tar.bz2];

Вниз

GetMessage в отдельном потоке   Найти похожие ветки 

 
msg   (2006-03-09 12:11) [0]

В отдельном потоке (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 в отдельном потоке?


 
Crash Coredump ©   (2006-03-09 12:16) [1]


> GetMessage ни в какую не желает принимать сообщение


RTFM, RTFM и еще раз RTFM, как завещал великий Ленин, про отличия SendMessage от PostMessage


 
Сергей М. ©   (2006-03-09 12:24) [2]


> GetMessage ни в какую не желает принимать сообщение


Цитата из справки :

If the function retrieves the WM_QUIT message, the return value is zero

Zero - это False

При этом произойдет выход из while-цикла.


> Я так понимаю, что посланные мной сообщения принимает обработчик
> главного потока. Так ли это?


Нет, не так.
Поток, создавший некое окно, ответственен за прием сообщений, адресованных этому окну.


> нужен ли вообще, в таком случае, GetMessage в отдельном
> потоке?


Разумеется нужен !


 
msg   (2006-03-09 16:00) [3]

> RTFM, RTFM и еще раз RTFM, как завещал великий Ленин, про отличия SendMessage от PostMessage

SendMessage ждет ответ, PostMessage нет, впр не о том обсалютно.

> Цитата из справки :

само собой, мне это известно и справку я читать умею. А GetMessage все равно не вызывается, ну никак и из цикла не выходит...

>Нет, не так.
>Поток, создавший некое окно, ответственен за прием сообщений, адресованных этому окну.


Вот и я всегда так думал...


 
Сергей М. ©   (2006-03-09 16:03) [4]


> GetMessage все равно не вызывается


Бред сивой кобылы несешь.


> Вот и я всегда так думал


Что тут думать ? Это - реальность .. концепция, придуманная не мной и не тобой.


 
Crash Coredump ©   (2006-03-09 16:08) [5]


> SendMessage ждет ответ, PostMessage нет, впр не о том обсалютно.


Не ту справку читаешь, почитай еще. Сообщения по SendMessage никогда не будут выбраны вызовом GetMessage


 
Сергей М. ©   (2006-03-09 16:12) [6]


> Сообщения по SendMessage никогда не будут выбраны вызовом
> GetMessage


Бред сивой кобылы.


 
Crash Coredump ©   (2006-03-09 16:23) [7]

Сергей М. ©   (09.03.06 16:12) [6]

Да ну ? Будут ? И дальше провалятся в TranslateMessage|DispatchMessage ?

А ты код напиши для примера, вместе посмотрим.


 
Сергей М. ©   (2006-03-09 16:44) [8]


> Crash Coredump ©   (09.03.06 16:23) [7]


Ты облажался.
По полной программе.


 
Crash Coredump ©   (2006-03-09 16:45) [9]

Сергей М. ©   (09.03.06 16:44) [8]

Ругаться я не хуже тебя умею, поверь.

Пример кода, в котором GetMessage выбирает сообщения, посланные по SendMessage будет ?


 
Сергей М. ©   (2006-03-09 16:46) [10]

Речь идет об интерпоточном взаимодействии.


 
Сергей М. ©   (2006-03-09 16:48) [11]


> Crash Coredump


В пределах одногго и того же кодового потока понятие "очередь" не имеет смысла.


 
Crash Coredump ©   (2006-03-09 16:52) [12]

Сергей М. ©   (09.03.06 16:46) [10]


> В пределах одногго и того же кодового потока понятие "очередь"
> не имеет смысла


Ты это разработчикам Windows расскажи, а мы вместе посмеемся над их ответом тебе. Заодно посмотри реализацию TCustomForm.Release, в котором понятие "очередь" в пределах одного потока весьма уместно используется.


> Речь идет об интерпоточном взаимодействии.


А какая разница ? GetMessage как занимался выборкой сообщений из очереди сообщений, так и занимается, хоть в одном потоке, хоть в десяти.


 
Сергей М. ©   (2006-03-09 16:55) [13]


> Crash Coredump ©   (09.03.06 16:52) [12]


Нет слов.

Бегом штудировать MSN !


 
Crash Coredump ©   (2006-03-09 16:59) [14]

Сергей М. ©   (09.03.06 16:55) [13]

А ты скажи, какой именно раздел надо штудировать ?

А то вот я один проштудировал, а там написано:

"The GetMessage function retrieves a message from the calling thread"s message queue and places it in the specified structure. This function can retrieve both messages associated with a specified window and thread messages posted via the PostThreadMessage function."

и еще один раздел проштудировал:

"he SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread"s message queue and returns immediately"

Или у тебя есть секретное издание MSDN ?


 
Сергей М. ©   (2006-03-09 17:00) [15]

> GetMessage как занимался выборкой сообщений из очереди сообщений,
>  так и занимается


Так точно.
Кодовый поток процесса, используя WinAPI, занимается либо ожиданием/выборкой, либо синхронной отправкой/ожиданием рез-та. Есть иное мнение ?


 
begin...end ©   (2006-03-09 17:00) [16]

> msg   (09.03.06 16:00) [3]

Сообщения, посылаемые окну потока с помощью SendMessage, называются синхронными, а сообщения, посылаемые функцией PostMessage -- асинхронными.

Вызванная функция GetMessage потока-приёмника вначале определяет по особому флагу в структуре потока, посланы ли потоку синхронные сообщения, и, если да, поочерёдно передаёт эти сообщения непосредственно оконным процедурам нужных окон. После этого GetMessage не возвращает управление (что мы и наблюдаем), а проверяет наличие асинхронных сообщений. И до тех пор, пока в очереди не будет обнаружено асинхронное сообщение или в структуре потока не будет обнаружен один из специальных флагов, GetMessage ничего не возвратит.

> И нужен ли вообще, в таком случае, GetMessage в отдельном
> потоке?

Нужен. Без вызова GetMessage WM_QUIT не передалось бы оконной процедуре.


 
Crash Coredump ©   (2006-03-09 17:01) [17]

Сергей М. ©   (09.03.06 17:00) [15]

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


 
Сергей М. ©   (2006-03-09 17:05) [18]


> Crash Coredump


Ты, чудо,  сам-то себе можешь описать ситуацию. когда один и тот же кодовый поток умудрился одновременно вызвать две ф-ции ?)


 
Crash Coredump ©   (2006-03-09 17:08) [19]

Сергей М. ©   (09.03.06 17:05) [18]

Ты, Серега, повежливее малость, а то опять чтением займешься.

И заодно почитай первый пост из темы:

"GetMessage ни в какую не желает принимать сообщение, даже если написать GetMessage(Msg,0,0,0), в то же время WndProc сообщение принимает"

при ситуации

"GetMessage ни в какую не желает принимать сообщение, даже если написать GetMessage(Msg,0,0,0), в то же время WndProc сообщение принимает"


 
Сергей М. ©   (2006-03-09 17:09) [20]


> Crash Coredump ©   (09.03.06 17:01) [17]


Читать ремарки ! До полного просветления !

Там сказано :

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine.

Эни квешнз ?


 
Сергей М. ©   (2006-03-09 17:13) [21]


> GetMessage ни в какую не желает принимать сообщение


Бред сивой кобылы.

Эта ф-ция не занимается каким-то там "приемом".

Эта ф-ция занимается ожиданием и выборкой сообщений, отправленных из потоков отличных от того, который вызвал эту ф-цию.


 
begin...end ©   (2006-03-09 17:14) [22]

> Сергей М. ©   (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.

Это к чему? В вопросе потоки разные, вообще-то.


 
Crash Coredump ©   (2006-03-09 17:15) [23]

Сергей М. ©   (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


 
Сергей М. ©   (2006-03-09 17:23) [24]


> Ты, Серега, повежливее малость, а то опять чтением займешься


О да) .. тебе ли не знать) .. За дурика не держи.

..

Цитирую автора


> в то же время WndProc сообщение принимает.


Ну и ?


 
Crash Coredump ©   (2006-03-09 17:27) [25]

Сергей М. ©   (09.03.06 17:23) [24]


> Ну и ?


Ну и этим все сказано - сообщение, посланное по SendMessage, обрабатывается оконной процедурой, а не появляется в результате вызова GetMessage.


 
Eraser ©   (2006-03-09 18:13) [26]


> Crash Coredump ©   (09.03.06 17:27) [25]


> Ну и этим все сказано - сообщение, посланное по SendMessage,
>  обрабатывается оконной процедурой, а не появляется в результате
> вызова GetMessage.

Что значит "появляется в результате вызова"?
а кто оконную процедуру вызывает, если сообщение из другово потока?


 
Crash Coredump ©   (2006-03-09 18:22) [27]


> Что значит "появляется в результате вызова"?


Значит, что
а) GetMessage возвращает результат (и заполненную структуру MSG при ненулевом результате)
б) Выполнение переходит на команду, следующую за вызовом GetMessage


 
Eraser ©   (2006-03-09 18:26) [28]


> Crash Coredump ©   (09.03.06 18:22) [27]


> Значит, что
> а) GetMessage возвращает результат (и заполненную структуру
> MSG при ненулевом результате)
> б) Выполнение переходит на команду, следующую за вызовом
> GetMessage

так точно.
А второй вопрос?


 
Crash Coredump ©   (2006-03-09 18:32) [29]


> а кто оконную процедуру вызывает, если сообщение из другово
> потока?


Вызывает ее GetMessage, PeekMessage, WaitMessage, при этом не прерывая своего исполнения до тех пор, пока в очереди нет сообщений.

Напиши пример с окном, которое реагирует на два разных сообщения, из другого потока посылай ему сообщения первого типа через SendMessage, а второго через PostMessage, посмотри, как будет происходить выполнение цикла
while GetMessage .... do begin
   // в этом месте можешь сигнализировать каким-то образом, что GetMessage отработал
   TranslateMessage
   DispatchMessage
end;


 
Eraser ©   (2006-03-09 18:36) [30]


> 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:42) [31]


> без Get/PeekMessage никуда.


WaitMessage, MsgWaitForMultipleObjects...


> не верно, что ты и доказал сам


Мы сабж будем читать или как ?


 
Leonid Troyanovsky ©   (2006-03-09 18:45) [32]


> Crash Coredump ©   (09.03.06 18:22) [27]

> Значит, что
> а) GetMessage возвращает результат (и заполненную структуру
> MSG при ненулевом результате)
> б) Выполнение переходит на команду, следующую за вызовом
> GetMessage


Никуда оно не перейдет, т.е., выхода из GetMessage при
обработке nonqueued message не будет.

В общем-то, картина не так уж проста, поэтому Рихтер и
писал о том, что у потока целых четыре очереди сообщений,
включая и такие, как очередь синхронных сообщений
и очередь ответных сообщений.

Ну, а собщения, которые SendMessage из другого потока
обрабатываются в оконной процедуре потоком-получателем.
А для того, чтобы оный смог обработать сообщение, он
должен находится в состоянии ожидания, достигаемого,
например, той же GetMessage.

--
Regards, LVT.


 
Eraser ©   (2006-03-09 18:48) [33]

to Crash Coredump ©   (09.03.06 18:42) [31]

> msg   (09.03.06 12:11)
> И нужен ли вообще, в таком случае, GetMessage в отдельном
> потоке?

нужен.

> MsgWaitForMultipleObjects

в данном случае применять эту функцию - извращение.

> WaitMessage

не осуществляет выборку.

так что нормальную очередь сообщений можно построить только на Get/PeekMessage ... остальное - стёб.. imho.


 
Crash Coredump ©   (2006-03-09 18:51) [34]

Leonid Troyanovsky ©   (09.03.06 18:45) [32]


> Никуда оно не перейдет, т.е., выхода из GetMessage при
> обработке nonqueued message не будет.


Об том и речь. С самого начала.


> Ну, а собщения, которые SendMessage из другого потока
> обрабатываются в оконной процедуре потоком-получателем.
> А для того, чтобы оный смог обработать сообщение, он
> должен находится в состоянии ожидания, достигаемого,
> например, той же GetMessage.


Или другими функциями ожидания, связанными с очередью сообщений потока. Вот честно, не проверял, будут ли обрабатываться сообщения, если поток будет ждать какого-нибудь объекта ядра функцией WaitForSingleObject, а что Рихтер на эту тему писал, не помню.


 
Crash Coredump ©   (2006-03-09 18:52) [35]

Eraser ©   (09.03.06 18:48) [33]


> не осуществляет выборку.


Из какой очереди сообщений ? Их несколько у потока.


 
Eraser ©   (2006-03-09 18:52) [36]


> Crash Coredump ©   (09.03.06 18:52) [35]

из любой.


 
Crash Coredump ©   (2006-03-09 18:56) [37]

Eraser ©   (09.03.06 18:52) [36]


> из любой.


Очередь сообщений, куда помещаются сообщения, посланные по SendMessage, WaitMessage тоже не обрабатывает, доставляя их оконной процедуре ?


 
Eraser ©   (2006-03-09 18:57) [38]


> Crash Coredump ©   (09.03.06 18:56) [37]

проспись пойди.


 
Crash Coredump ©   (2006-03-09 19:01) [39]

Eraser ©   (09.03.06 18:57) [38]

Это надо понимать, как отсутствие иных аргументов ?


 
Crash Coredump ©   (2006-03-09 19:12) [40]

Eraser ©   (09.03.06 18:57) [38]

Мне не хочешь верить, может, Рихтеру поверишь, который Джеффри:

"When a worker thread sends a message to your window, the SendMessage function internally queues up the message for the window, and then the worker thread suspends itself. The next time the user-interface thread calls GetMessage, PeekMessage, or WaitMessage, it sees the queued sent message, pulls it from the queue, and processes the window"s window procedure. "

http://www.microsoft.com/msj/1197/win321197.aspx



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.06.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.055 c
6-1139192754
Delphi_is_cool
2006-02-06 05:25
2006.06.04
Определить ip dialup сервера


5-1132723716
ККВ
2005-11-23 08:28
2006.06.04
Не запускается программа в режиме отладки


2-1147621441
wirg
2006-05-14 19:44
2006.06.04
Помогите с запросом


4-1142234174
Chaser
2006-03-13 10:16
2006.06.04
Определить активное ДОС-окно


1-1146248975
Archy
2006-04-28 22:29
2006.06.04
Массив





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский