Delphi 7 の OnMouseMove イベントでコンポーネントを移動するときに CPU 使用率を削減するにはどうすればよいですか?
-
22-08-2019 - |
質問
Delphi 7 アプリケーションで、マウスに続いてコンポーネントを移動したいと考えています。私は次のようなことをしています:
procedure MyComponent.MouseMove(Sender: TObject;Shift: TShiftState; X, Y: Integer);
begin
AnotherComponent.Top := X;
AnotherComponent.Left := Y;
end;
最近の PC では、マウスを動かすとメイン コアの CPU 使用率が 100% に達します。
この場合、CPU 使用率を減らすためのアイデアやチェックはありますか?
解決 3
最後に、私はこのために私のコードを変更しました。
procedure MyComponent.MouseMove(Sender: TObject;Shift: TShiftState; X, Y: Integer);
begin
if GetTickCount-LastMoveTick>50 then begin
AnotherComponent.Top := Y;
AnotherComponent.Left := X;
LastMoveTick := GetTickCount;
end;
end;
(2行が追加された)を実装するのはとても簡単で、何のタイマーは、私のためにうまく機能していない...
他のヒント
あなたはポーリング現在のマウス位置ごとに0.10秒程度というTTIMERを作成することができ、その後、現在のマウスの位置に応じて「AnotherComponent」を位置づけています。
そして、あなたはあなたがすべてのコンポーネントを制御する上で任意のONMOUSEMOVEイベントを必要としませんmovement-マウスの画素ごとに、あなたのイベントを発生しません。
私のコンピュータでは、これは基本的にすべてのパフォーマンスに影響を与えません。
procedure TForm1.Timer1Timer(Sender: TObject);
var
pt: TPoint;
begin
//Is the cursor inside the controlling component? if so, position some
//other control based on that mouse position.
GetCursorPos(pt);
if MouseWithin(pt.x,pt.y,MyComponent,Form1.Left,Form1.Top) then begin
//replace with whatever real positioning logic you want
AnotherComponent.Top := pt.y;
AnotherComponent.Left := pt.x;
end;
end;
function TForm1.MouseWithin(mouseX, mouseY: integer;
const comp: TWinControl; const ParentWindowLeft: integer;
const ParentWindowTop: integer): boolean;
var
absoluteCtrlX, absoluteCtrlY: integer;
begin
//take a control, and the current mouse position.
//tell me whether the cursor is inside the control.
//i could infer the parent window left & top by using ParentwindowHandle
//but I'll just ask the caller to pass them in, instead.
//get the absolute X & Y positions of the control on the screen
//needed for easy comparison to mouse position, which will be absolute
absoluteCtrlX := comp.Left + ParentWindowLeft;
absoluteCtrlY := comp.Top + ParentWindowTop +
GetSystemMetrics(SM_CYCAPTION);
Result := (mouseX >= absoluteCtrlX)
and (mouseX < absoluteCtrlX + comp.Width)
and (mouseY >= absoluteCtrlY)
and (mouseY <= absoluteCtrlY + comp.Height);
end;
- マウス移動自体とは何の関係もありません。
- それが意図したものでない限り、X、Y と Top、Left が一致していません。上が Y 座標、左が X 座標です。
- 問題は、AnotherComponent の実際の移動です。
これを理解するには、調整可能な繰り返し/遅延を使用して AnotherComponent を自動的に移動して CPU を監視する TestMove ルーチンを作成することをお勧めします。
おそらく、コストのかかる再描画やその他の CPU を集中的に使用する計算がトリガーされると思います。
したがって、まずこのコンポーネントにイベント ハンドラーがあるかどうかをよく調べてから、継承された動作に従ってください。
たぶん、あなたは「影」を移動し、ユーザーがマウス・ボタンを行くことができます一度のみのコンポーネントを移動する代わりに、コンポーネント自体を移動させます。ソートのドラッグ&ドロップのような。
これはおそらく動きは部品が何らかの形で自分自身を再描画させ、そんなにCPUパワーを必要とする動き自体にすることはできません。
あなたは、各移動して再描画されることAnotherComponent
を避けることはできますか?それは映画のコンテナでない限り、それは、必要ありません。
マウス移動イベントに関連付けられたものは非常に頻繁に呼び出されます。あなたのハンドラが唯一のシステムがどのように忙しいに基づいて、できるだけ速くトリガーされますので、私はしかし、CPUの使用状況を心配しないでしょう。他に何もないので、他の言葉では、それだけでCPUを限界いっぱいまでいます。
MSDNから:
マウスは、入力イベントを生成します ユーザーがマウスを移動したとき、または プレスリリースし、マウスのボタンを押します。 システムは、マウス入力イベントに変換します メッセージに変換し、それらを投稿 適切なスレッドのメッセージキュー。 マウスメッセージが速く掲載されている場合 スレッドには、それらを処理できるよりも、 このシステムは、すべてのほとんどを破棄します 最近のマウスメッセージます。
さて、これにはいくつかの例外があるかもしれません。あなたは、いくつかの他の処理の集中活動を実行することで確認するためにいくつかのテストを行うと、どのくらいのマウス移動のものに影響を与え、それ見ることができました。