2010-02-21 41 views
5

Tôi đã tự hỏi liệu có ai có thể cung cấp thông tin chi tiết về cách triển khai bộ chọn cửa sổ trong Winspector Spy hay không. Về cơ bản, tôi sẽ muốn cung cấp một bảng điều khiển mà tôi có thể di chuyển chuột xuống, kéo qua một cửa sổ quy trình khác (hoặc cửa sổ phụ) và nhận được một cái gì đó giống như HWND ra khỏi nó. Lý tưởng nhất, tôi sẽ làm điều này trong C#, nhưng nếu nó chỉ có thể bằng cách gói các API C, thì tôi có thể làm điều đó trong C++.Kéo và thả như Winspector Spy

Tôi rối tung xung quanh với sự kiện DragDrop và gọi DoDragDrop trên chuột xuống trong C#, nhưng không thực sự chắc chắn nếu điều đó có thể cho tôi những gì tôi muốn. Sẽ dễ dàng hơn khi chỉ nhận được vị trí X/Y toàn cầu của con chuột và tìm cửa sổ trên cùng ở vị trí đó? Có một API mà automagically cho tôi cho x, y tham số?

EDIT: Chỉ cần phát hiện WindowFromPoint cho câu hỏi thứ hai

Trả lời

5

Bạn thường không nhận được tin nhắn chuột khi chuột không nằm trên cửa sổ của bạn. Nhưng bạn cần phải thực hiện thao tác kéo và thả. Vì vậy, Windows cung cấp một cơ chế được gọi là chụp chuột. Để ngăn chặn việc bắt giữ chuột bị lạm dụng, bạn chỉ có thể chụp chuột trên một thông báo nút. Một khi bạn đã nắm bắt, bạn nhận được thông báo di chuyển chuột không có vấn đề mà con chuột trên màn hình cho đến khi bạn phát hành chụp hoặc khi Windows thấy thông báo nút tương ứng.

C++ mã cho điều này có vẻ gì đó như thế này

case WM_LBUTTONDOWN: 
    { 
    SetCapture(hwnd); 
    } 
    break; 

case WM_MOUSEMOVE: 
    if (GetCapture() == hwnd) 
     { 
     POINT pt = {GET_MOUSE_X(lParam), GET_MOUSE_Y(lParam)); 
     ClientToScreen(hwnd, &pt); 
     HWND hwndAtPoint = WindowFromPoint(pt); 
     // Show info for hwndAtPoint.... 
     } 
    break; 

    case WM_LBUTTONUP: 
    if (GetCapture() == hwnd) 
     { 
     ReleaseCapture(); 
     } 
    break; 

    case WM_CANCELMODE: 
    // this is a request from Windows that leave my modal state 
    if (GetCapture() == hwnd) 
     ReleaseCapture(hwnd); 
    break; 

    case WM_CAPTURECHANGED: 
    // notification that I lost capture (I released it or it was taken from me) 
    break;  

Chức năng GetAncestor có thể hữu ích để đi từ cửa sổ tại các điểm, đến cửa sổ cấp cao nhất mà sở hữu nó. GetWindow có thể được sử dụng để đi bộ xung quanh cây cửa sổ.

Trong .NET, lớp Control có một tài sản Capture mà làm điều tương tự thấy http://msdn.microsoft.com/en-us/library/system.windows.forms.control.capture.aspx

+0

Điều này thật tuyệt - cảm ơn rất nhiều. –

0

Nhập khẩu: sử dụng System.Runtime.InteropServices;

Đề xuất của tôi, khi chuột ở trên biểu mẫu của bạn, hãy di chuyển chuột/di chuột lên (Để chụp chuột bên ngoài biểu mẫu bằng móc cửa sổ, xem tại đây: http://support.microsoft.com/kb/318804) và khi nút chuột được nhả ra , nhận vị trí chuột trên màn hình và nhận cửa sổ phía sau con trỏ, sử dụng liên kết bạn đã cung cấp như sau:

Bây giờ bạn có tay cầm cửa sổ, từ đó khả năng là vô tận.

LƯU Ý: Liên kết ở trên, (các cửa sổ móc) sẽ chỉ làm việc nếu chuột xuống xảy ra vào mẫu của bạn, và móc kết thúc khi chuột được nâng lên

0

đơn giản. Bạn chỉ cần thiết lập chuột trên chuột, vì vậy bạn nhận được tất cả các tin nhắn chuột ngay cả khi chúng nằm ngoài cửa sổ của bạn. Sau đó, trên chuột lên, sử dụng WindowFromPoint.

Tôi không quen với .NET, nhưng với API Win32, bạn sử dụng SetCapture để đặt chế độ chụp chuột.

0

Bạn có thể nhìn vào ++ nguồn C cho Winspy++, một chương trình cửa sổ thanh tra tương tự như Winspector Spy. Tuy nhiên, tôi không biết về bất kỳ chương trình C# mã nguồn mở nào như thế này.

2

Bạn sẽ cần cân nhắc cách vẽ hình chữ nhật quanh cửa sổ trước, điều đó ảnh hưởng đến phần còn lại của mã. Cách dễ nhất để thực hiện việc này là sử dụng Biểu mẫu có TransparencyKey được đặt thành BackColor và FormBorderStyle được đặt thành Không.Vẽ một hình chữ nhật trong sự kiện Paint, cùng kích thước với ClientRectangle của biểu mẫu, giúp bạn có một hình chữ nhật có thể nhìn thấy với mọi thứ khác trong suốt. Đặt thuộc tính Vị trí và Kích thước của biểu mẫu để khớp với cửa sổ bạn tìm thấy.

Bây giờ, tìm cửa sổ từ vị trí chuột. Bạn không thể sử dụng WindowFromPoint(), nó không xem xét các cửa sổ bị tắt. Bạn sẽ cần phải sử dụng EnumWindows(). Trong callback, gọi GetWindowRect() và kiểm tra nếu con chuột nằm bên trong hình chữ nhật. Hãy chắc chắn bỏ qua cửa sổ vẽ hình chữ nhật của bạn.

Khi bạn nhận được một trận đấu, bây giờ gọi GetWindow() nhiều lần với GW_HWNDPREV để tìm các cửa sổ chồng lên cửa sổ bạn tìm thấy. Tiếp tục kiểm tra hình chữ nhật và tiếp tục bỏ qua cửa sổ hình chữ nhật của bạn.

Điều này cuối cùng sẽ đưa bạn đến cửa sổ cấp cao nhất mà con trỏ chuột đang bật. Bây giờ sử dụng ChildWindowFromPoint() để kiểm tra xem con chuột có trên cửa sổ con không, nếu có. Tạo hình vẽ hình chữ nhật của bạn, nếu cần thiết, và cung cấp cho nó cùng kích thước và vị trí như cửa sổ tìm thấy.

Gọi mã này từ sự kiện MouseMove, ví dụ: Hộp hình ảnh hiển thị hình ảnh mắt bò. Đặt thuộc tính Capture của nó thành true trong sự kiện MouseDown của nó.

Đóng phương thức Close() của biểu mẫu hình chữ nhật của bạn trong sự kiện MouseUp.

1

Vì bạn đã gắn thẻ này với C#, tôi có thể đặt trong một hoặc hai liên kết cho việc làm này mà bạn đang cố gắng để đạt được và hy vọng sẽ cung cấp cho bạn cái nhìn sâu sắc cần thiết vào làm thế nào để đạt được điều này:

Tất cả các bài viết trên đều nằm trên CodeProject.

Hy vọng điều này sẽ giúp, Trân trọng, Tom.