当社のアプリケーションは、測定デバイスから読み込まれなければならず、データベースに格納されている測定データを扱います。PeekMessageはメッセージキューにマウスボタンの入力を照会するのに十分ですか?
一度に多くの測定データセットを一括読み取りするオプションを提供します(&)。これは時間がかかるプロセスなので、モーダルダイアログボックスには進行状況バーと操作をキャンセルするボタンが表示されます。
測定データの完全なセットが読み込まれて保存された後に操作をキャンセルすることができます。アプリケーションのより
procedure TProgressWithAbort.CheckMouseButtonInput;
var
Msg: TMsg;
begin
// if the left mouse button was pressed while the mouse was at the
// Cancel button call the application's message loop to process the event
if PeekMessage(Msg, btnCancel.Handle, WM_LBUTTONUP, WM_LBUTTONUP, PM_NOREMOVE) then
Application.ProcessMessages;
end;
:
はItemsToStore := GetSelectedTreeItems();
DlgProgress := TProgressWithAbort.Create(Screen.ActiveForm);
try
for i := 0 to Pred(ItemsToStore.Count) do
begin
if DlgProgress.Cancel then exit;
DlgProgress.Description := ItemsToStore[i].Name;
ReadAndStoreItem(ItemsToStore[i].Id);
DlgProgress.Position := Succ(i) * 100 div ItemsToStore.Count;
end;
finally
DlgProgress.Free;
end;
進捗ダイアログのPositionプロパティのセッターは、現在、以下のようにコーディングされているCheckMouseButtonInputという名前のプロシージャを呼び出します。
ザ・は次のように&ストア・ループがある読んでメッセージループでは、プロパティを介してアクセス可能な変数を設定する次のボタンクリックハンドラが呼び出されます。
procedure TProgressWithAbort.btnCancelClick(Sender: TObject);
begin
FCancel := true;
end;
すべて正常です。しかし、上記のCheckMouseButtonInputの実装が多すぎるCPU時間を消費するのではないかと思います。 PeekMessage
の前にGetQueueStatus
またはMsgWaitForMultipleObjects
(ハンドルなしでタイムアウト0)に電話する方が良いでしょうか?
移動。 – Victoria
'MsgWaitForMultipleObjects'を同期オブジェクトなしで呼び出すと、' WaitMessage'を呼び出すのと同じ効果があります。 'WaitMessage'に続いて' PeekMessage'を呼び出すことは 'GetMessage'を呼び出すのと同じ効果を持ちます。これが解決策であっても、それを実装するのに最も複雑な方法です。 – IInspectable
メインのUIスレッドを読み込みおよび保存中にブロックしたい場合は、キャンセルボタンのみが応答する必要があります。したがって、ワーカースレッドは必要ありません。現在の解決策は、特定のメッセージのメッセージキューをスキャンするポーリング戦略です。私は、GetQueueStatusまたはMsgWaitForMultipleObjectsがPeekMessageと同じ原則に従っているかどうか、あるいは単純にいくつかのフラグや何か(それほどリソースを消費しない)をテストするだけで作業をするかどうかを知りたいと思っています。 – DinkumOil