2009-03-25 4 views
6

In un'applicazione Delphi 7, voglio spostare un componente seguendo il mouse. Sto facendo qualcosa di simile:Come ridurre l'utilizzo della CPU durante lo spostamento di un componente in un evento OnMouseMove in Delphi 7?

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.

Qualche idea o segno di spunta per ridurre l'utilizzo della CPU in questo caso?

+0

La prego di aggiungere se il componente e il controllo sotto di esso sono controlli a finestra o no? Hanno un codice di pittura complicato? – mghie

risposta

3

Infine ho modifiche al codice esistente per questo uno:

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 ...

+0

Controlla la tua X & Y lì come Left è X, Top è Y. Se questo funziona per te, allora va bene, ma sembra sbagliato. – mj2008

+0

corretto. Grazie ! –

+0

Mi piace questo meglio della mia soluzione :) – JosephStyons

4

È possibile creare un TTimer che esegue il polling della posizione corrente del mouse ogni 0,10 secondi circa, quindi posiziona "AnotherComponent" in base alla posizione corrente del mouse.

Quindi non si attiva l'evento per ogni pixel di movimento del mouse, non è necessario alcun evento OnMouseMove sul componente di controllo.

Sul mio computer, questo in pratica non ha alcun impatto sulle prestazioni.

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; 
0

Non può essere la mossa in sé che ha bisogno di tanta potenza di CPU, molto probabilmente la mossa provoca la componente di ridisegnare se stesso in qualche modo. Puoi evitare che AnotherComponent venga ridisegnato su ogni mossa? Non dovrebbe essere necessario, a meno che non si tratti di un contenitore di film.

0

Qualsiasi evento legato all'evento di spostamento del mouse verrà chiamato molto frequentemente in quanto i mouse sono dispositivi di input ad alta risoluzione. Non mi preoccuperei comunque dell'uso della CPU perché il gestore viene licenziato il più velocemente possibile in base a quanto è occupato il sistema. In altre parole, è solo il massimo della CPU, perché nient'altro è.

Da MSDN:

Il mouse genera un evento di input quando l'utente sposta il mouse o presse o rilascia un pulsante del mouse. Il sistema converte gli eventi di input del mouse in messaggi e li inserisce nella coda messaggi del thread appropriato . Quando i messaggi del mouse vengono pubblicati più rapidamente di un thread in grado di elaborarli, il sistema scarta tutti tranne il più recente messaggio del mouse .

Ora ci possono essere alcune eccezioni a questo. Potresti fare qualche test per essere sicuro eseguendo qualche altra attività di elaborazione intensiva e vedere quanto l'impatto del mouse sulle cose lo impatta.

+0

I voti negativi senza una spiegazione non sono così costruttivi come potrebbero essere. Se riesci a identificare qualcosa di sbagliato, faccelo sapere. Farò felicemente una correzione alla mia risposta. –

+0

Non ti ho offeso, tuttavia il tuo POV non è multi-tasking-friendly. Il thread della GUI avrà la priorità normale, quindi metterà completamente di fame tutti i thread con priorità più bassa e rimuoverà i cicli dai thread con la stessa priorità. L'ottimizzazione per il minor carico della CPU è importante, anche se fuori moda. – mghie

+0

Potrebbe essere vero come regola generale, ma questa è una procedura GUI. L'interazione con l'utente generalmente ha sempre la precedenza poiché la risposta è una priorità. Sembra che l'autore stia cercando di animare un'operazione di trascinamento del mouse. Non vorrei che saltasse periodicamente fuori sincrono con il mouse. –

3
  1. Non ha nulla a che fare con il Mouse Move stesso.
  2. A meno che non si tratti di ciò che intendevi, stai mismatching X, Y con Top, Left. In alto c'è il coordinatore Y e ha lasciato la X.
  3. Il problema è lo spostamento effettivo 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 si innesca un costoso ridisegno o qualche altro calcolo intensivo della CPU.
Quindi esamina attentamente se hai in primo luogo un gestore di eventi su questo componente, quindi segui il comportamento ereditato ...

1

Forse, invece di spostare il componente stesso, si sposta una "ombra" e si sposta il componente solo quando l'utente lascia il pulsante del mouse. Una specie di resistenza simile a & caduta.

Problemi correlati