2009-03-25 14 views
6

Trong một ứng dụng Delphi 7, tôi muốn di chuyển một thành phần theo con chuột. Tôi đang làm một cái gì đó như thế này:Làm thế nào để giảm mức sử dụng CPU khi di chuyển một thành phần trong một sự kiện OnMouseMove trong Delphi 7?

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

Khi tôi di chuyển chuột, mức sử dụng CPU cho lõi chính tăng lên 100% trên PC gần đây.

Bất kỳ ý tưởng hoặc đánh dấu nào để giảm mức sử dụng CPU trong trường hợp này?

+0

thể bạn vui lòng thêm liệu thành phần và điều khiển bên dưới nó là điều khiển cửa sổ hay không? Họ có mã vẽ phức tạp không? – mghie

Trả lời

3

Cuối cùng tôi đã thay đổi mã của tôi cho một này:

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; 

Thật dễ thực hiện (2 dòng gia tăng), không hẹn giờ, hoạt động tốt đối với tôi ...

+0

Kiểm tra X & Y của bạn ở đó là Trái là X, Trên cùng là Y. Nếu điều này phù hợp với bạn, thì tốt, nhưng có vẻ như sai. – mj2008

+0

Đã sửa. cảm ơn ! –

+0

Tôi thích điều này tốt hơn so với giải pháp của tôi :) – JosephStyons

4

Bạn có thể tạo TTimer để thăm dò vị trí chuột hiện tại sau mỗi 0,10 giây hoặc lâu hơn, sau đó vị trí "AnotherComponent" theo vị trí chuột hiện tại.

Sau đó, bạn sẽ không kích hoạt sự kiện của mình cho mỗi pixel di chuyển chuột - bạn sẽ không cần bất kỳ sự kiện OnMouseMove nào trên thành phần điều khiển của bạn cả.

Trên máy tính của tôi, điều này về cơ bản không có tác động hiệu suất nào cả.

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

Nó không thể là bản thân di chuyển cần nhiều nguồn cpu, có lẽ di chuyển nhất khiến cho thành phần vẽ lại bằng cách nào đó. Bạn có thể tránh được rằng AnotherComponent được vẽ lại trên mỗi lần di chuyển không? Nó không phải là cần thiết, trừ khi nó là một container phim.

0

Mọi thứ liên quan đến sự kiện di chuyển chuột sẽ được gọi rất thường xuyên vì chuột là thiết bị đầu vào có độ phân giải cao. Tôi sẽ không lo lắng về việc sử dụng CPU mặc dù bởi vì xử lý của bạn chỉ bị sa thải càng nhanh càng tốt dựa trên cách bận rộn của hệ thống. Nói cách khác, nó chỉ tối đa CPU vì không có gì khác.

Từ MSDN:

Con chuột tạo ra một sự kiện đầu vào khi người dùng di chuyển chuột, hoặc ép hoặc phát hành một nút chuột. Hệ thống chuyển đổi các sự kiện nhập chuột thành các tin nhắn và đăng chúng lên hàng đợi tin nhắn của chủ đề thích hợp . Khi thông báo bằng chuột được đăng nhanh hơn so với chuỗi có thể xử lý chúng, hệ thống sẽ hủy tất cả trừ hầu hết thông báo chuột gần đây nhất .

Hiện tại, có thể có một số ngoại lệ. Bạn có thể làm một số thử nghiệm để chắc chắn bằng cách chạy một số hoạt động chuyên sâu xử lý khác và xem có bao nhiêu công cụ di chuyển chuột tác động đến nó.

+0

Bỏ phiếu không có giải thích không mang tính xây dựng như chúng có thể. Nếu bạn có thể xác định điều gì đó sai, vui lòng cho chúng tôi biết. Tôi sẽ vui vẻ sửa lại câu trả lời của tôi. –

+0

Tôi không downvote bạn, tuy nhiên POV của bạn không phải là đa tác vụ thân thiện. Các thread GUI sẽ có ưu tiên bình thường, do đó, nó sẽ hoàn toàn bỏ đói tất cả các chủ đề với ưu tiên thấp hơn, và lấy đi chu kỳ từ các chủ đề với cùng một ưu tiên. Tối ưu hóa cho tải CPU thấp nhất là quan trọng, ngay cả khi không thời trang. – mghie

+0

Điều đó có thể đúng với quy tắc chung nhưng đây là quy trình GUI. Tương tác với người dùng nói chung luôn được ưu tiên vì phản hồi là ưu tiên. Có vẻ như tác giả đang cố gắng tạo hoạt ảnh kéo chuột. Sẽ không muốn nhảy định kỳ không đồng bộ với chuột. –

3
  1. Nó không liên quan gì đến việc di chuyển chuột.
  2. Trừ khi đó là những gì bạn dự định, bạn không khớp X, Y với Trên cùng, Bên trái. Đầu là Y phối hợp và rời khỏi X.
  3. Vấn đề là di chuyển thực tế của AnotherComponent.

Để thử và hiểu nó, tôi khuyên bạn nên viết một thường trình TestMove để tự động di chuyển phần mềm khác của bạn bằng điều chỉnh lặp lại/trì hoãn để giám sát CPU.
Tôi đặt cược nó kích hoạt một lần trả lại tốn kém hoặc một số tính toán chuyên sâu CPU khác.
Vì vậy, hãy kiểm tra kỹ nếu bạn có bất kỳ trình xử lý sự kiện nào trên thành phần này trước, sau đó đi với hành vi kế thừa ...

1

Có thể, thay vì di chuyển thành phần, bạn di chuyển một 'bóng' và chỉ di chuyển thành phần khi người dùng cho phép nút chuột đi. Sắp xếp giống như kéo & thả.

Các vấn đề liên quan