Come ridurre l'utilizzo della CPU durante lo spostamento di un componente in un evento OnMouseMove in Delphi 7?
-
22-08-2019 - |
Domanda
In Delphi 7 applicazione, voglio spostare un componente seguendo il mouse. Sto facendo qualcosa di simile:
procedure MyComponent.MouseMove(Sender: TObject;Shift: TShiftState; X, Y: Integer);
begin
AnotherComponent.Top := X;
AnotherComponent.Left := Y;
end;
Quando sposto il mouse l'utilizzo della CPU per il nucleo principale va fino al 100% su un recente PC.
Qualsiasi idea o zecche per ridurre l'utilizzo della CPU in questo caso?
Soluzione 3
Finalmente ho cambiare il mio codice per questo:
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;
Veramente facile da implementare (2 linee), nessun timer, funziona bene per me ...
Altri suggerimenti
È possibile creare un TTimer che i sondaggi la posizione corrente del mouse ogni 0.10 secondi o giù di lì, poi le posizioni "AnotherComponent", secondo la posizione corrente del mouse.
Allora non avrebbe sparato il vostro evento per ogni pixel del mouse del movimento- non sarà necessario ogni caso OnMouseMove sul controllo della componente a tutti.
Sul mio computer, questo non ha fondamentalmente alcun impatto sulle prestazioni a tutti.
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;
- Non ha nulla a che fare con il movimento del mouse stesso.
- A meno che non è quello che si intende, si sta mismatching X, Y con Top, Sinistra. Top è il coord Y e sinistra del X uno.
- Il problema è il movimento reale di AnotherComponent.
Per cercare di capirlo, vi suggerisco di scrivere una routine TestMove che si muove l'AnotherComponent automaticamente con ripetizione regolabile / ritardi per monitorare la CPU.
Scommetto che innesca un ridisegno costosa o qualche calcolo intensivo altra CPU.
Quindi esaminare attentamente se avete qualsiasi gestore di eventi su questa componente prima, poi con il comportamento ereditato ...
Forse, invece di spostare il componente stesso si sposta un 'ombra' e solo spostare il componente di una volta che l'utente lascia il via mousebutton. Un po 'come il drag & drop.
Non può essere la mossa in sé che ha bisogno di tanta potenza di CPU, molto probabilmente la mossa fa sì che la componente di ridisegnare se stesso in qualche modo.
Si può evitare che AnotherComponent
viene ridisegnata su ogni mossa? Non dovrebbe essere necessario, a meno che non si tratta di un contenitore di film.
Tutto legato all'evento spostamento del mouse sarà chiamato molto frequentemente come topi sono un dispositivo di ingresso ad alta risoluzione. Io non mi preoccuperei l'utilizzo della CPU, però, perché il vostro gestore unico viene licenziato il più velocemente possibile in base a come il sistema sia impegnato. In altre parole, è solo maxing la CPU perché niente altro è.
Da MSDN:
Il mouse genera un evento di ingresso quando l'utente sposta il mouse, o presse o rilascia un pulsante del mouse. Il sistema converte eventi di input del mouse in messaggi e li pubblica al coda di messaggi del thread appropriato. Quando i messaggi del mouse sono inviati più veloce di un filo di loro, il grado di elaborare sistema scarta tutti ma il più messaggio recente del mouse.
Ora ci possono essere alcune eccezioni a questa. Si potrebbe fare un po 'di test per essere sicuri eseguendo qualche altra attività ad alta intensità di elaborazione e vedere quanto impatto esso la roba spostamento del mouse.