Конференция "WinAPI" » Отловить сообщение во втором потоке созданным CreateThread
 
  • Black_Tomcat (26.12.07 07:08) [0]
    Здравствуйте.
    Подскажите пожалуйста как отправить сообщение во второй поток и как его там поймать. А то, я что запутался окончательно вроде отправка осуществляется при помощи функции PostThreadMessage, а прием PeekMessage. Но вот только PostThreadMessage возвращает False, a GetLastError 1159. Что я не так делаю?
  • Сергей М. © (26.12.07 08:34) [1]
    Что говорит SysErrorMessage(GetLastError) ?
  • Black_Tomcat (26.12.07 09:19) [2]

    > Что говорит SysErrorMessage(GetLastError) ?


    'Сообщение может быть использовано только с операциями синхронизации'
    А что это значит?
  • Сергей М. © (26.12.07 09:27) [3]
    А какое конкретно сообщение ты посылаешь ?
  • Black_Tomcat (26.12.07 09:35) [4]
    var
    Data:tagCOPYDATASTRUCT;

    PostThreadMessage(ThreadID,WM_COPYDATA,0,lParam(@Data));

  • Сергей М. © (26.12.07 09:38) [5]
    Тогда отлуп ты получаешь вполне резонно - сообщение с кодом WM_COPYDATA есть специальный зарезервированный вид сообщения, которое можно отправлять только синхронно, т.е. с использованием SendMessage, а не Post[Thread]Message
  • Black_Tomcat (26.12.07 09:43) [6]
    Ясно спасибо.
    А как его отловить во втором потоке?
  • Сергей М. © (26.12.07 09:47) [7]
    Прежде чем его "ловить" нужно осознать, что ф-ция SendMessage подразумевает адресатом окно (или окна) , а не нить. Целевая нить у тебя создает хоть одно окно ?
  • Black_Tomcat (26.12.07 09:53) [8]
    Это я знаю :-)
    Окно у меня есть. И оно умеет обрабатывать это сообщение. Мне нужно его как-то перехватить перед тем как окно его обработает. Это возможно?
  • Сергей М. © (26.12.07 10:11) [9]

    > Окно у меня есть


    Оно откуда взялось ? Его какая нить создала - целевая ?
  • Black_Tomcat (26.12.07 10:17) [10]
    Я пишу на VCL окно стандартное.
    Целевая нить и основной поток это одно и тоже?
  • Сергей М. © (26.12.07 10:20) [11]
    Поток (кодовый) = нить = тред = thread.

    Если ты отправляешь сообщение основному потоку, то разумеется он является целевым потоком.
  • Сергей М. © (26.12.07 10:22) [12]
    Определись, кому ты посылаешь сообщение - потоку или окну..
  • Black_Tomcat (26.12.07 10:30) [13]
    Мне нужно отправить это сообщение в созданный поток.
    И из созданного потока обратно окну.
    Oкну можно его отправить  например так SendMessage(Form1.Handle,WM_COPYDATA,0,lParam(i)) .

    Но вот как отправить это сообщение в созданный мною поток? И как его там обработать, я не могу понять.
    Может ли мною созданный поток, выгребать сообщения из очереди сообщений окна?
  • Сергей М. © (26.12.07 10:47) [14]

    > как отправить это сообщение в созданный мною поток?


    Никак. Только окну его можно отправить.
    Меняй концепцию и логику.


    > Может ли мною созданный поток, выгребать сообщения из очереди
    > сообщений окна?


    А собссно зачем ? Поясни ..
  • Black_Tomcat (26.12.07 10:53) [15]
    Я отправляю сообщение окну.
    Поток его забирает из очереди собщений, например занимает семафор, а процедура обработки сообщения целевого потока в зависимости от состояния семаформа решает обрабатывать его или нет.
    Или я вообще неправильно думаю.
  • Сергей М. © (26.12.07 11:02) [16]

    > Поток его забирает из очереди собщений


    Его забирает тот поток, который создал окно, т.е. в твоем случае основной.

    Далее этот поток смотрит на семафор - если он занят, то делает с полученным сообщением одно действие , иначе другое.
  • Black_Tomcat (26.12.07 11:07) [17]
    Спасибо.
    Теперь пойду валить препода. :-)
  • Сергей М. © (26.12.07 11:23) [18]

    > пойду валить препода


    Как бы он тебя не завалил)
  • Black_Tomcat (28.12.07 10:45) [19]
    У меня возник еще вопросик.
    Я во втором потоке создал окно все вроде работает, но  функция обработки сообщений созданного окна выполняется в основном потоке, как ее выполнить в потоке создавшем окно?
    Вот код на всякий случай.

    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
       //do something
      else
       if nMsg=WM_SEND_DATA then
         //do something
    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;



    Все я не стал копировать, но я думаю смысл от этого не изменится.
 
Конференция "WinAPI" » Отловить сообщение во втором потоке созданным CreateThread
Есть новые Нет новых   [134431   +15][b:0][p:0.002]