Come ridurre l'utilizzo della CPU durante lo spostamento di un componente in un evento OnMouseMove in Delphi 7?

StackOverflow https://stackoverflow.com/questions/682451

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?

È stato utile?

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;
  1. Non ha nulla a che fare con il movimento del mouse stesso.
  2. 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.
  3. 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top