1

ユーザーは、アプリケーション内の「重要なイベント」ごとにポップアップ ボックスを要求します。メモまたはリスト ボックスに行を追加することは受け入れられません。

PC が無人であることが多いため、標準のモーダル ボックスを使用できません。アプリケーションは、ユーザーが [OK] をクリックするのを待ってから続行します。

メモ コンポーネントと [OK] ボタンを含むフォームを動的に作成し、メモに表示するテキストを渡すことはできますか?

やってみたところ、OKをクリックするとアクセス違反になってしまいました。

質問:

  • モードレスに表示されているため、フォームを表示するためにスレッドを起動する必要はありますか?
  • コンストラクターのパラメーター (prent) として何を渡す必要がありますか? 無、フォルム自体が壊れてしまうので?
  • ユーザーが [OK] をクリックしたとき、何を呼び出せばよいですか? Close() または Free() ? これらのいずれも、[OK] をクリックしてから約 1/2 秒後にアクセス違反が発生しますが、関数で何もしなければ、コードは正常に実行されます (もちろん、メモリ リークが発生します)。

フォームはそれ自体を破壊する必要があるため、Google はあまり役に立ちませんが、例では作成者がフォームを破壊しています。


主な形式:

     theDialogForm := TDialogFormForm.Create(Nil);
     theDialogForm.ShowTheForm('Database error '+#13+#10+''+#13+#10+
                E.ClassName+#13+#10+
                E.Message);

そしてダイアログフォーム...

unit fDialogForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TDialogFormForm = class(TForm)
    Memo1: TMemo;
    OkButton: TButton;
    procedure OkButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
      procedure ShowTheForm(const theMessage : String);
  end;

implementation

{$R *.dfm}

// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
procedure TDialogFormForm.FormCreate(Sender: TObject);
begin
   Visible := False;
end;

// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
procedure TDialogFormForm.OkButtonClick(Sender: TObject);
begin
//   Close();
   Free();
end;

// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
procedure TDialogFormForm.ShowTheForm(const theMessage : String);
begin
   Memo1.Text := theMessage;
   Show();
end;

end.

コール スタック

main thread ($630):
005164e3 +013 StoreRoom.exe Vcl.Controls          TControl.WMLButtonUp
00515b30 +2d4 StoreRoom.exe Vcl.Controls          TControl.WndProc
0051a47b +5b3 StoreRoom.exe Vcl.Controls          TWinControl.WndProc
00537bf0 +06c StoreRoom.exe Vcl.StdCtrls          TButtonControl.WndProc
00519ad0 +02c StoreRoom.exe Vcl.Controls          TWinControl.MainWndProc
0048dea4 +014 StoreRoom.exe System.Classes        StdWndProc
76677885 +00a USER32.dll                          DispatchMessageW
005b7c63 +0f3 StoreRoom.exe Vcl.Forms             TApplication.ProcessMessage
005b7ca6 +00a StoreRoom.exe Vcl.Forms             TApplication.HandleMessage
005b7fd9 +0c9 StoreRoom.exe Vcl.Forms             TApplication.Run
00823616 +17a StoreRoom.exe StoreRoom      56 +24 initialization
75c43398 +010 kernel32.dll                        BaseThreadInitThunk
4

4 に答える 4

7

フォームを閉じるには、次のいずれかを実行できます

  • 呼び出して閉じ、OnClose イベントでCloseアクションを設定します。caFree
  • callReleaseは Free の特別なフレーバーであり、特にフォーム用です。

を呼び出す際の問題Freeは、閉じるボタンのクリック イベントをまだ処理している間に、フォームがすぐに解放されることです。そのプロセス中にフォームとボタンが解放され、アクセス違反が発生します。内部的にフォームにメッセージを送信し、クリックが処理されたReleaseにフォームを閉じます。

于 2012-09-18T10:45:06.667 に答える
4
  1. フォームを表示するためにスレッドは必要ありません。ただし、フォームは表示されたままにする必要があるため、に設定することをお勧めしFormStyleますfsStayOnTop
  2. nilフォームを破棄しているので、に渡すことができますCreate()
  3. フォームを破棄するには、 を呼び出しClose、フォームのOnCloseイベントで に設定ActioncaFreeます。
于 2012-09-18T10:48:26.707 に答える
2

重要なイベントが発生すると表示され、ユーザーが [OK] をクリックすると非表示になる、ダイアログ ボックスのような非表示パネルを自分で簡単に作成してみませんか?

于 2012-09-19T12:17:40.103 に答える
1

モードレスに表示されているため、フォームを表示するためにスレッドを起動する必要はありますか?

VCL はマルチスレッドではありません。フォームは常にメイン スレッドで実行する必要があります。おそらく、追加のスレッドで Win32 API ShowMessageBox を呼び出すことができますが、その場合は単一のメッセージに対してのみです。イベントを TMemo またはグリッドに蓄積する方法はありません。

コンストラクターのパラメーター (prent) として何を渡す必要がありますか?

私はアプリケーションを渡しますが、それは大したことではありません。

ユーザーが [OK] をクリックしたとき、何を呼び出せばよいですか? Close() または Free() ?

どちらも、フォームを作成/削除する意味はありません。同じクラスの多くのフォームを持つことができる場合にのみ意味があります。今回は、プログラムの開始/終了時に Delphi に自動作成および自動破棄させるだけです。

表示または非表示にするだけです。手動で作成して破棄しても意味がありません。


次に、スレッドについて - なぜアプリケーションをブロックする必要があるのでしょうか? そのウィンドウを AlwaysOnTop にしてから、TApplication.OnActivateイベントを使用して、ユーザーがいつ切り替えたかを確認し、そのウィンドウを画面/メインフォームの前面と中央に移動します。そのユーザーはそれを見るでしょう。

または、メッセージの有効期限が切れないようにするオプションを備えた Snarl などのサードパーティの通知ツールを試すこともできます。

于 2012-09-18T12:04:02.553 に答える