2

FRAME (フォームではありません)とスレッドがあります。スレッドからフレームのコントロールを参照するにはどうすればよいですか?たとえば、スレッドのボタンを無効にしたい。しかし、ボタンへのポインタがなく、フレームにグローバル変数がありません。

ありがとう!

4

2 に答える 2

7

実際には、メソッドを呼び出したり、VCLコントロールのプロパティを変更したり、ユーザーに表示されるもの(アプリケーションのユーザーインターフェイス、つまり、フレーム内かどうかに関係なく、Delphiで通常VCLコントロールを使用すること)を直接変更しないでください。バックグラウンドスレッドから。

PostMessageただし、、、またはを使用して、イベントまたは通知をメインスレッドに送信できTThread.SynchronizeますTThread.Queue

スレッドオブジェクトにフレームまたはコントロールへの参照を設定するよりも、フレームまたはその他のコントロールを含むフォームのハンドルをスレッドに渡して、ユーザーメッセージ(WM_USER + 10001)を使用する方がよい場合があります。 )このように。

TTHread.SynchronizeやQueueよりもPostMessageの方が好きです。なぜなら、それは本当にシンプルで、うまく機能するからです。Win32 APIに関連付けられているため、クロスプラットフォームに適した手法ではありません。

次のように同期を呼び出す必要があります。

  TMyThread = class(TThread)
  private
    FFrame: TFrame;
    ...
  public
    constructor Create(AFrame: TFrame); 
    ...
  end;

  constructor TMyThread.Create(AFrame: TFrame);
  begin
    FFrame := AFrame;
    inherited Create;
  end;

  // do not call directly, only using Synchronize
  procedure TMyThread.AMethodWithNoParameters; 
  begin
     FFrame.Button1.Enabled := not FBusy;
  end;

  procedure TMyThread.DoWork; // called from Execute.
  begin
    FBusy := true; 
    Synchronize(AMethodWithNoParameters);
    Sleep(100); //dummy;
    FBusy := false; 
    Synchronize(AMethodWithNoParameters);
  end;
于 2011-08-04T19:43:44.417 に答える
2

正しく指摘されているように、バックグラウンド スレッドでビジュアル コンポーネントのメンバーを呼び出すことはできません。

スレッドコード内からボタンを無効にするには、ボタンへの参照、またはスレッドオブジェクトを割り当てることができるイベントへの参照が必要です-その後、次のように、キューまたは同期されたプロシージャ内でスレッドを起動できます:-

    type
      test=class(tthread)
         ondisablebutton:tnotifyevent;

{...}

次に、tthread.synchronize でカプセル化したプロシージャーでイベントを呼び出すことができます。イベントが割り当てられているかどうかをテストすることを忘れずに....

procedure test.synchronisedprocedure;
begin
  if assigned(ondisablebutton) then
    ondisablebuttone(self);
end;

設計したスレッド オブジェクトを作成するときは、次のようなボタンを含むフォームのプロシージャに ondisablebutton を割り当てる必要があります。

procedure form1.threadwantstodisablebutton(sender:tobject);
begin
  button1.enabled:=false;
end;

スレッドの作成には追加の行が必要です:-

  mythread:=test.create;
  test.ondisablebutton:=form1.threadwantstodisablebutton;

そのように、明らかに、スレッドを定義および作成している form1 (またはボタンを含むフォーム) にアクセスする必要があります。これは必ずしも良い設計ではありませんが、機能します。

于 2011-08-04T22:35:56.307 に答える