2009-03-25 8 views
6

En una aplicación Delphi 7, quiero mover un componente siguiendo el mouse. Estoy haciendo algo como esto:Cómo reducir el uso de la CPU al mover un componente en un evento OnMouseMove en Delphi 7?

procedure MyComponent.MouseMove(Sender: TObject;Shift: TShiftState; X, Y: Integer); 
begin 
    AnotherComponent.Top := X; 
    AnotherComponent.Left := Y; 
end; 

Cuando muevo el ratón el uso de CPU para el núcleo principal va hasta el 100% en una reciente PC.

¿Alguna idea o tilde para reducir el uso de la CPU en este caso?

+0

Podría, por favor añadir si el componente y el control debajo de él son controles con ventana o no? ¿Tienen código de pintura complicado? – mghie

Respuesta

3

fin he cambiar mi código para éste:

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; 

realmente fácil de implementar (2 líneas añadido), no hay ningún temporizador, funciona bien para mí ...

+0

Revisa tus X e Y allí ya que Izquierda es X, Superior es Y. Si esto funciona para ti, está bien, pero parece estar mal. – mj2008

+0

Corregido. Gracias ! –

+0

Me gusta esto mejor que mi solución :) – JosephStyons

4

Puede crear un TTimer que sondee la posición actual del mouse cada 0,10 segundos aproximadamente, y luego coloca "Otro componente" de acuerdo con la posición actual del mouse.

Entonces no dispararía su evento por cada píxel del movimiento del mouse; no necesitará ningún evento OnMouseMove en absoluto en su componente de control.

En mi computadora, esto básicamente no tiene ningún impacto en el rendimiento.

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

No puede ser el propio movimiento que necesita tanta energía de la CPU, lo más probablemente el movimiento hace que el componente que volver a dibujar en sí de alguna manera. ¿Se puede evitar que se vuelva a dibujar AnotherComponent en cada movimiento? No debería ser necesario, a menos que sea un contenedor de película.

0

Cualquier cosa relacionada con el movimiento del mouse se invocará con mucha frecuencia ya que los ratones son un dispositivo de entrada de alta resolución. Sin embargo, no me preocuparía el uso de la CPU porque su manejador solo se dispara lo más rápido posible en función de lo ocupado que esté el sistema. En otras palabras, solo está maximizando la CPU porque nada más lo es.

De MSDN:

El ratón genera un evento de entrada cuando el usuario mueve el ratón, o prensas o suelta un botón del ratón. El sistema convierte los eventos de entrada del mouse en mensajes y los publica en la cola de mensajes del subproceso . Cuando los mensajes del mouse se publican más rápido que un subproceso puede procesarlos, el sistema descarta todos menos mensaje de mouse reciente.

Ahora puede haber algunas excepciones a esto. Podría hacer algunas pruebas para asegurarse de ejecutar otra actividad de procesamiento intensivo y ver cuánto lo impacta el movimiento del mouse.

+0

Los votos a la baja sin una explicación no son tan constructivos como podrían ser. Si puede identificar algo incorrecto, háganos saber. Estaré encantado de corregir mi respuesta. –

+0

No te devolví el voto, sin embargo, tu POV no es multitarea amigable. El hilo de la GUI tendrá prioridad normal, por lo que matará de hambre por completo a todos los hilos con menor prioridad, y eliminará los ciclos de los hilos con la misma prioridad. Es importante optimizar la carga más baja de la CPU, incluso si está fuera de moda. – mghie

+0

Eso puede ser cierto como regla general, pero este es un proceso de GUI. La interacción con el usuario generalmente siempre tiene prioridad ya que la capacidad de respuesta es una prioridad. Parece que el autor está intentando animar una operación de arrastre del mouse. No querría que salte periódicamente fuera de sincronización con el mouse. –

3
  1. No tiene nada que ver con el movimiento del mouse.
  2. A menos que sea lo que pretendía, no coincide X, Y con la parte superior, izquierda. La parte superior es la coord Y y la izquierda la X.
  3. El problema es el movimiento real de AnotherComponent.

Para intentar entenderlo, sugiero que escriba una rutina TestMove que mueva su AnotherComponent automáticamente con repeticiones/retrasos ajustables para monitorear la CPU.
Apuesto a que desencadena un costoso repintado o algún otro cálculo intensivo de CPU.
Examina detenidamente si tienes algún controlador de eventos en este componente primero, luego sigue el comportamiento heredado ...

1

Quizás, en lugar de mover el componente en sí, mueva una 'sombra' y solo mueva el componente una vez que el usuario deja ir el botón del mouse. Algo así como arrastrar & soltar.

Cuestiones relacionadas