2008-09-04 35 views
15

Có cách nào để theo dõi cửa sổ nào hiện có tiêu điểm bàn phím hay không. Tôi có thể xử lý WM_SETFOCUS cho mỗi cửa sổ nhưng tôi tự hỏi nếu có một phương pháp thay thế, đơn giản hơn (tức là một trình xử lý tin nhắn ở đâu đó).Làm thế nào tôi có thể theo dõi cửa sổ nào hiện tại có tiêu điểm bàn phím

Tôi có thể sử dụng OnIdle() trong MFC và gọi GetFocus() nhưng điều đó có vẻ hơi khó hiểu.

+0

Trình theo dõi lấy nét dường như đã chuyển đến đây: https://github.com/Microsoft/WPF-Samples/tree/master/Accessibility/FocusTracker (Xin lỗi, tôi không có đủ danh tiếng để thêm nhận xét này làm nhận xét cho câu trả lời có liên quan ở trên). – greiginsydney

Trả lời

3

Làm thế nào về Win32 GetForegroundWindow?

+0

Tôi biết cách lấy tiêu điểm cửa sổ, tôi đang tìm cách được thông báo khi thay đổi tiêu điểm ở một vị trí duy nhất. – jmatthias

16

Vì vậy, từ cách bạn diễn đạt câu hỏi tôi phỏng đoán rằng bạn muốn có trình xử lý sự kiện được gọi bất cứ khi nào tiêu điểm chuyển giữa các cửa sổ. Bạn muốn được thông báo, thay vì phải thăm dò ý kiến. Tôi thực sự không nghĩ rằng việc gọi GetFocus từ OnIdle là rất nhiều hack - chắc chắn nó đang bỏ phiếu, nhưng nó không có tác dụng phụ - nhưng nếu bạn thực sự muốn theo dõi, Windows Hooks có lẽ là lựa chọn tốt nhất của bạn . Cụ thể là bạn có thể cài đặt móc CBT (WH_CBT) và nghe thông báo HCBT_SETFOCUS.

Windows gọi móc WH_CBT bằng mã móc này khi Windows sắp đặt trọng tâm vào bất kỳ cửa sổ nào. Trong trường hợp móc cụ thể theo chủ đề, cửa sổ phải thuộc về chủ đề. Nếu hàm lọc trả về TRUE, tiêu điểm sẽ không thay đổi.

Bạn cũng có thể thực hiện với móc WH_CALLWNDPROC và nghe tin nhắn WM_SETFOCUS.

Tùy thuộc vào việc bạn đặt móc nối toàn cục hay ứng dụng cục bộ, bạn có thể theo dõi tiêu điểm trên tất cả các cửa sổ trên hệ thống hoặc chỉ các cửa sổ thuộc sở hữu của quy trình của bạn.

+0

Đây là câu trả lời đúng. –

0

Vâng, điều này có thể không được rất duyên dáng ... nhưng bạn có thể lấy lại hiện kiểm soát tập trung khá dễ dàng. Vì vậy, bạn có thể xem xét việc thiết lập một bộ đếm thời gian yêu cầu mỗi 1/2 giây hoặc lâu hơn "Trọng tâm hiện tại ở đâu?" ... Sau đó, bạn có thể quan sát các thay đổi. Ví dụ mã Delphi là dưới đây; nó sẽ khá dễ dàng để thích nghi, vì công việc thực sự là trong các cuộc gọi Windows API.

<snip> 

function TForm1.GetCurrentHandle: integer; 
var 
    activeWinHandle: HWND; 
    focusedThreadID : DWORD; 
begin 
    //return the Windows handle of the currently focused control 
    Result := 0; 
    activeWinHandle := GetForegroundWindow; 
    focusedThreadID := GetWindowThreadProcessID(activeWinHandle,nil); 
    if AttachThreadInput(GetCurrentThreadID,focusedThreadID,true) then begin 
    try 
     Result := GetFocus; 
    finally 
     AttachThreadInput(GetCurrentThreadID, focusedThreadID, false); 
    end; 
    end; //if attached 
end; 

procedure TForm1.Timer1Timer(Sender: TObject); 
begin 
    //give notification if the handle changed 
    //(this code gets fired by a timer) 
    CurrentHandle := GetCurrentHandle; 
    if CurrentHandle <> PreviousHandle then begin 
    Label1.Caption := 'Last focus change occurred @ ' + DateTimeToStr(Now); 
    end; 
    PreviousHandle := CurrentHandle; 
end; 

<snip> 
3

Có một cách dễ dàng sử dụng Net Framework 3.5: thư viện UI Automation cung cấp một tập trung sự kiện thay đổi mà cháy mỗi khi thay đổi tập trung vào một điều khiển mới.

Page on MSDN

mẫu:

public void SubscribeToFocusChange() 
{ 
    AutomationFocusChangedEventHandler focusHandler 
     = new AutomationFocusChangedEventHandler(OnFocusChanged); 
    Automation.AddAutomationFocusChangedEventHandler(focusHandler); 
} 

private void OnFocusChanged(object src, AutomationFocusChangedEventArgs e) 
{ 
    AutomationElement focusedElement = sender as AutomationElement; 
    //... 
} 

api này trên thực tế các cửa sổ sử dụng treo đằng sau hậu trường để làm điều đó. Tuy nhiên, bạn phải sử dụng .Net Framework ...

0

http://msdn.microsoft.com/en-us/library/ms771428.aspx

Có mẫu theo dõi tiêu điểm cửa sổ.

+0

Tôi không thể tìm thấy tệp tải xuống cho mã nguồn ở bất kỳ đâu và không được bao gồm trong quá trình cài đặt SDK của tôi. Có ai biết làm thế nào tôi có thể nắm giữ nó? – sparrowt

1

Nếu bạn đang lập trình .net 3.5, các gói phần mềm tự động hóa olorin đề cập đến là dễ nhất, nhưng hãy cẩn thận khi sử dụng nó trong một chương trình có giao diện người dùng, ít nhất là nếu giao diện người dùng được thực hiện trong WPF - móc theo dõi lấy nét bị nhầm lẫn bởi các sự kiện trong ứng dụng riêng của nó và nhanh chóng khóa giao diện người dùng. Tôi đã gửi MS một số bug report trên đó. Tôi đã không quan sát cùng một vấn đề bằng cách sử dụng giao diện người dùng Windows Forms truyền thống. Bạn có thể, tất nhiên, đặt mã theo dõi trong một ứng dụng giao diện điều khiển riêng biệt và sử dụng một số loại ipc để truyền tải thông tin bạn cần.

Cách thay thế hấp dẫn khi sử dụng Interop để truy cập móc khóa WH_CBT từ C# sẽ không hoạt động - the only global hooks you can get at from C# are the mouse and keyboard.

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