Q&A

  • 쓰레드 안에서의MsgWaitForMultipleObjects....
도저히 해결점을 찾지 못해 글을 올려봅니다..
윈도우 기본 메세지 처리 방법입니다.. 인터넷에서 돌아다니는 거 모아 짜집기....
버튼2를 실행하면 윈도우가 종료 되지 않습니다. 왜냐면 메세지퀴에서 루프를 돌면
메세지를 가져와 WM_Quit 이면 그냥 버려 버리닌까요...(wndproc 후킹과는 조금 다릅니다..)
그런데 이것을 좀더 프로그램 속도를 높이기 위해 쓰레드안에서 그대로 했더니...(버튼1 클릭)
기능이 작동하지 않습니다.
while not Terminated do begin
      if MsgWaitForMultipleObjects(0, Handles, False, INFINITE, QS_ALLINPUT)=WAIT_OBJECT_0 then

MsgWaitForMultipleObjects에서 하염없이 기다리는 것 같습니다...
쓰레드에서는 왜 이게 안되는 거죠?
저도 이런건 첨이라 도저히 알수가 없습니다....
도와주세요!!!




unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }

  public
    { Public declarations }
  end;

type
  TMyThread = class (TThread)
    Owner:TComponent;
    constructor CreateSuspended(aOwner: TComponent);
    procedure Execute; override;
  end;

var
  Form1: TForm1;
  MyThread:TMyThread;

implementation

{$R *.dfm}

constructor TMyThread.CreateSuspended(aOwner: TComponent);
begin
   Owner := aOwner;
   Create(false);
end;

procedure TMyThread.Execute;
var
  msg: TMsg;
  Handles : array [0..0] of THandle;

begin

Handles[0]:=0;
while not Terminated do begin
      if MsgWaitForMultipleObjects(0, Handles, False, INFINITE, QS_ALLINPUT)=WAIT_OBJECT_0 then
      begin
        if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then
          case msg.Message of
            WM_QUIT:begin
                TForm1(owner).Label1.Caption:='종료???';
            end else
            begin
                TranslateMessage(msg);
                DispatchMessage(msg);
              end;
           end;
      end;
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyThread:=TMyThread.CreateSuspended(self);
  with MyThread do
  begin
      FreeOnTerminate := True;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  msg: TMsg;
  Handles : array [0..0] of THandle;
begin
Handles[0]:=0;
      while MsgWaitForMultipleObjects(0, Handles, False, INFINITE, QS_ALLINPUT)=WAIT_OBJECT_0 do
      begin
        if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then
          case msg.Message of
            WM_QUIT:begin
                Label1.Caption:='종료???';
            end else
            begin
                TranslateMessage(msg);
                DispatchMessage(msg);
              end;
           end;
      end;

end;

end.
2  COMMENTS
  • Profile
    한만교 2003.07.08 06:11
    에 ~
    저 역시 쓰레드안에서의 메세지 처리 때문에 해결점을 못찾아서 헤맨적이 있는데요...쓰레드를 통기화하여 돌리면 잘 들어먹습니다..
    근데 프로그램 속도가 떨어집니다..CPU점유가 한없이 올라가더군여..
    그래서 타임어를 사용했으나 중간에 데이터 끝어짐 현상이 생기더군여..
    그래서 이벤트 처리를 했지요..타임어를 사용해서..쓰레드 동기화 해주구..
    쓰레드가 할일을 최소한 줄이고 이벤트 처리를 했지요...
    아마 이런 비슷한 문제일꺼라 생각이 드는군요..
    그럼 즐프하시길 항상 해결책은 당신이 하는 곳 옆에 있답니다...



  • Profile
    박상철 2003.06.21 02:08

    PeekMessage 도 쓰레드안에서 안먹습니다..
    아무런 메세지도 못가져 옵니다.. 분명히 있는데...
    방법이 없을까요?