2009-07-14 34 views
6

vì tôi không thể tìm thấy câu trả lời cho câu hỏi this Tôi đã nghiên cứu thêm một chút về MSDN và tôi đã tìm thấy isChild(). Nó có thể cho tôi câu trả lời cho câu hỏi khác.lấy HWND cho ứng dụng của riêng tôi trong C

Bây giờ, để sử dụng isChild() tôi cần phải vượt qua HWND của ứng dụng cha mẹ mà tôi muốn kiểm tra, trong trường hợp này là ứng dụng của riêng tôi. Làm cách nào để nhận được HWND của đơn đăng ký của riêng tôi?

Tôi không biết tiêu đề vì nó thay đổi liên tục nên tôi không thể sử dụng FindWindow().

Cảm ơn

Edit:

Vì nó không rõ ràng, tôi sẽ bổ sung thêm thông tin: tôi không tạo ra một cửa sổ. Tôi không có quyền truy cập vào việc tạo cửa sổ. Mã của tôi là một đoạn mã được biên dịch cùng với bất kỳ ứng dụng nào mà lập trình viên khác đang mã hóa và tôi không có quyền truy cập vào cách cửa sổ được tạo, tiêu đề hoặc bất kỳ thông tin nào khác. Vì vậy, làm cách nào để tải HWND về "WINDOW" của ứng dụng tôi đang chạy?

Trả lời

6

Sử dụng GetTopWindow() và GetNextWindow() để đi qua cửa sổ z-order.

Tuy nhiên, đừng nghĩ rằng đó là cần thiết, nhưng bạn có thể sử dụng GetCurrentProcessId() và GetWindowThreadProcessId(), có thể là một cái gì đó giống như dưới đây sẽ giúp bạn:

HWND FindMyTopMostWindow() 
{ 
    DWORD dwProcID = GetCurrentProcessId(); 
    HWND hWnd = GetTopWindow(GetDesktopWindow()); 
    while(hWnd) 
    { 
     DWORD dwWndProcID = 0; 
     GetWindowThreadProcessId(hWnd, &dwWndProcID); 
     if(dwWndProcID == dwProcID) 
      return hWnd;    
     hWnd = GetNextWindow(hWnd, GW_HWNDNEXT); 
    } 
    return NULL; 
} 
+0

GetTopWindow() luôn trả về 0. Tương tự với GetActiveWindow() – wonderer

+0

Cảm ơn bạn đã phát lại, nhưng GetTopWindow() nếu được gọi với NULL có thể trả về cửa sổ trên cùng của chương trình khác (như tôi đã biết trong câu hỏi trước) và tôi đã nêu trong câu hỏi đó và trong câu hỏi này tôi đang tìm kiếm thông tin về ứng dụng và cửa sổ của riêng tôi. – wonderer

+0

Vì vậy, bạn tìm thấy cửa sổ trên cùng - sau đó lặp qua các cửa sổ theo thứ tự z bằng cách sử dụng GetNextWindow và so sánh từng cửa sổ với bạn. Đầu tiên phù hợp là những gì bạn cần. Tôi nghĩ rằng nó có thể được thực hiện như vậy ... –

1

Bạn không thể giữ tay cầm được trả về từ CreateWindow? Nếu không, tai sao không?

+0

vì tôi không tạo ra một cửa sổ. My my là một mô-đun được biên dịch với mã của người khác. Do đó tôi không có quyền truy cập vào việc tạo cửa sổ. Bây giờ, khi biết rằng, làm thế nào để tôi nhận được HWND cho cửa sổ của ứng dụng mà tôi đang chạy? – wonderer

+0

Vì vậy, bạn thậm chí không có quyền truy cập vào máy bơm tin nhắn của cửa sổ tôi giả sử? Sau đó, điều duy nhất tôi có thể nghĩ đến là EnumWindows và sau đó gọi GetWindowLong bằng tham số GWL_HINSTANCE và so sánh HINSTANCE được trả lại cho tham số được trả về từ GetModuleHandle. – Goz

+0

Điều đáng chú ý là bạn sẽ nhận được MỌI HWND liên quan đến HINSTANCE của bạn mặc dù ... – Goz

0

Điều này là cũ đối với tôi, nhưng IIRC bạn sẽ nhận được HWND như một tham số trong cửa sổ proc. Bạn có thể lưu nó trong một biến toàn cục ở đâu đó trong phần đầu.

+1

Thực ra thay vì lưu trữ nó dưới dạng toàn cầu, bạn có thể chuyển nó hoặc con trỏ tới cấu trúc khác làm tham số cuối cùng của CreateWindowEX. Con trỏ đó sau đó sẽ có sẵn cho thủ tục Windows trong thông báo WM_CREATE. –

9

Đơn đăng ký của bạn không có HWND. Cửa sổ hiện ra. Một ứng dụng có thể không có cửa sổ hoặc nó có thể có nhiều cửa sổ, do đó không có chức năng chung để "Lấy HWND của ứng dụng".

Giải pháp hiển nhiên chỉ là giữ tay cầm khi bạn nhận được. Khi bạn tạo cửa sổ, HWND sẽ được trả lại. Lưu trữ đó.

+0

Ok xin lỗi vì đã không chính xác. – wonderer

0

Còn tên lớp cửa sổ của bạn thì sao? Nó có khác biệt khi tạo cửa sổ không? Nếu không bạn vẫn có thể FindWindow().

1

Như những người khác đã chỉ ra

  • Nói chung, một ứng dụng có thể có không hoặc nhiều cửa sổ cấp cao nhất.
  • Nếu bạn đang tự tạo cửa sổ, bạn chỉ cần nhớ HWND ở đâu đó.

Nhưng có thể mã của bạn nằm trong tệp DLL nên bạn không thực sự tự tạo cửa sổ cấp cao nhất. Vậy lam gi?

tôi xin đề nghị như sau:

  • Sử dụng EnumWindows để liệt kê tất cả các cửa sổ cấp cao nhất.
  • Sử dụng GetWindowLongPtr để nhận HINSTANCE cho mỗi cửa sổ cấp cao nhất. So sánh điều này với HINSTANCE của ứng dụng mà bạn có thể nhận được bằng cách sử dụng GetModuleHandle(NULL). Nếu chúng giống hệt nhau, bạn đã tìm thấy cửa sổ chính của mình.

Chỉnh sửa: Đây là một số mã. Hóa ra bạn cũng phải sử dụng IsWindowVisible vì dường như có một vài cửa sổ "trợ giúp" vô hình.

HWND hwndMain; 

BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam) 
{ 
    HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL); 

    if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst && 
     IsWindowVisible(hwnd)) 
    { 
     hwndMain=hwnd; 
     return FALSE; 
    } 
    else 
     return TRUE; 
} 

Sau đó ở nơi bạn muốn tìm cửa sổ:

hwndMain=NULL; 
EnumWindows(EnumWindowProc, 0); 

Và sau này, hwndMain nên chứa các xử lý của cửa sổ, hoặc NULL nếu không tồn tại.

Sử dụng EnumWindows hơi phiền phức nhưng được đề nghị khi gọi GetWindow trong vòng lặp vì MSDN ghi chú: "Một ứng dụng gọi GetWindow để thực hiện nhiệm vụ này có nguy cơ bị bắt trong vòng lặp vô hạn hoặc tham chiếu đến cửa sổ đã bị phá huỷ."

+0

Cảm ơn. Điều đó trông giống như rất nhiều mã để có được một cái gì đó rất đơn giản. Bạn có mẫu không? – wonderer

1

Có lẽ mã của bạn được gọi bằng mã ứng dụng chính, nếu không thì sử dụng mã nào? Trong trường hợp này, tôi không thấy tại sao API của mã của bạn không thể bao gồm một số cách thông báo cho bạn về xử lý của cửa sổ chính của ứng dụng.

+0

Vì không có trong giấy thiết kế. Đó là tất cả. – wonderer

+1

Sau đó thay đổi thiết kế! –

+0

Suy nghĩ của tôi chính xác. Đây là tất cả những gì cần thiết. – kurige

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