2013-05-29 49 views
24

Tuyên bố từ chối: Tôi không quen với API Win32, đặc biệt là cách cửa sổ hoạt động.Cửa sổ chính bị đóng băng khi cửa sổ con bị đóng băng quá mức từ một quá trình khác

Tôi muốn làm cho cửa sổ của một số quá trình là cửa sổ con của một quá trình khác. Hai quy trình cũng là cha mẹ và con. Nhưng tôi không nghĩ rằng vấn đề. Cho đến nay, mọi thứ hoạt động như một nét duyên dáng - Cho đến khi tôi đóng băng luồng chính của cửa sổ con.

Hãy tưởng tượng một container.exe rằng notepad.exe và someApplication.exe 'host'

Khi tôi đình chỉ các chủ đề chính của someApplication.exe trong vài giây, cửa sổ của nó được đông lạnh cho số tiền mà thời gian. Điều đó hoàn toàn dễ hiểu. Nhưng cửa sổ của container.exe cũng sẽ cũng treo cùng một lúc. Cửa sổ con của các quy trình được lưu trữ khác (như notepad.exe) sẽ tiếp tục hoạt động tốt.

Tôi đang sử dụng lệnh SetParent để thực hiện một cửa sổ phi con thường xuyên là con của container.exe của tôi:

SetParent(
    childProcess.HWND, 
    myOwnHWND 
); 

Sau đó, tôi đang sử dụng setWindowPos:

SetWindowPos(
    childProcess.HWND, 
    HWND_TOP, 
    someXPos, 
    someYPos, 
    0, 
    0, 
    SWP_FRAMECHANGED or SWP_NOSIZE or SWP_SHOWWINDOW 
) 

Như số MSDN article on SetParent gợi ý, tôi cũng xóa thuộc tính kiểu WS_POPUP và thêm thuộc tính WS_CHILD. Vì điều đó không giúp được gì, tôi cũng đã thêm thuộc tính kiểu mở rộng WS_EX_NOACTIVATE, cả hai bằng cách sử dụng lệnh SetWindowLongPtr. Cuối cùng, tôi đã thử gửi cả hai cửa sổ WM_UPDATEUISTATE và sau đó là thông báo WM_CHANGEUISTATE nhưng điều đó cũng không thay đổi điều gì.

Điều khiến tôi bối rối là cửa sổ của quy trình gốc tiếp tục được vẽ bình thường, cho đến khi tôi chạm vào nó. Sau đó, nó đóng băng hoàn toàn cho đến khi cửa sổ con không hoạt động. Tôi nghi ngờ một thứ được gọi là hàng đợi nhập '. Các MSDN article về một thông báo WM_ACTIVATE trạng thái:

Đã gửi đến cả hai cửa sổ đang được kích hoạt và cửa sổ bị hủy kích hoạt. Nếu cửa sổ sử dụng cùng một hàng đợi nhập, tin nhắn sẽ được gửi đồng bộ, trước tiên làm thủ tục cửa sổ của cửa sổ cấp cao bị hủy kích hoạt, sau đó đến quy trình cửa sổ của cửa sổ cấp cao nhất được kích hoạt. Nếu các cửa sổ sử dụng các hàng đợi đầu vào khác nhau, thông báo sẽ được gửi không đồng bộ, vì vậy cửa sổ sẽ được kích hoạt ngay lập tức.

Do đó, tôi đã hy vọng cao cho thuộc tính kiểu mở rộng WS_EX_NOACTIVATE.

Để tổng hợp: Thực sự có thể lưu trữ cửa sổ của một quy trình khác và không đóng băng cửa sổ của riêng bạn khi cửa sổ con bị đóng băng không?

+8

+1 Câu hỏi này cực kỳ kỹ lưỡng. –

+2

Đọc liên quan: [Có hợp pháp để gọi có mối quan hệ cửa sổ cha/con hoặc chủ sở hữu/sở hữu chéo không?] (Http://blogs.msdn.com/b/oldnewthing/archive/2013/04/12/10410454 .aspx) – GSerg

+1

* Tại sao * bạn có cần phải làm điều này? Tôi chắc chắn có cách tốt hơn và dễ dàng hơn để đạt được mục đích thực sự của bạn. Đừng rơi vào bẫy vấn đề XY. –

Trả lời

17

Bạn không thể mong đợi chặn luồng GUI của bất kỳ quy trình nào. Trong kịch bản của bạn, mọi thứ phức tạp hơn một chút vì có hai luồng GUI. Một cho mỗi quy trình.

Tuy nhiên, bằng cách thiết lập mối quan hệ cha/con giữa các cửa sổ của các quy trình này, bạn cũng giới thiệu một yêu cầu rằng cả hai giao diện GUI được phục vụ trong thời gian tốt.

Windows trong mối quan hệ cha/con sẽ gửi cho nhau các thư khác. Và nếu những tin nhắn đó được đồng bộ, được gửi thay vì được đăng, sau đó chặn một chuỗi GUI sẽ dẫn đến một chuỗi bị chặn khác.

Quy tắc vàng của lập trình GUI vẫn có hiệu lực: không chặn luồng GUI. Nếu bạn có một nhiệm vụ chạy dài, hãy di chuyển nó lên một chuỗi nền.

Cập nhật

OK, như được giải thích here khi bạn liên hệ cửa sổ từ chủ đề khác nhau mà bạn đính kèm hàng đợi thông điệp của họ với nhau. Và vì vậy nếu bạn chặn một luồng, bạn chặn tất cả các chuỗi được đính kèm.

Vì vậy, đừng chặn luồng GUI.

+1

Cảm ơn bạn. Tất nhiên một thread GUI không nên bị chặn. Tuy nhiên, tôi đang thử nghiệm một kịch bản trường hợp xấu nhất, như ứng dụng _hosted_ hoàn toàn bị đóng băng. Trong trường hợp này, ứng dụng máy chủ chỉ đơn giản là CÓ THỂ KHÔNG đóng băng. Ngoài ra, tôi vẫn tự hỏi làm thế nào quan hệ cha mẹ/con quá trình đi vào chơi ở đây. Nếu cửa sổ tiến trình con không phải là con của cửa sổ tiến trình cha, thì cửa sổ quá trình sẽ không bị đóng băng. Vì vậy, họ không thể thực sự gửi ** tin nhắn. –

+0

"Nếu trẻ em cửa sổ quá trình không phải là con của cửa sổ quy trình cha mẹ, thì quá trình sau sẽ không bị đóng băng". Cuộc gọi của bạn để SetParent làm cho một cửa sổ là một đứa trẻ của người kia. "Họ thực sự không thể gửi tin nhắn." Tại sao không? Toàn bộ Windows GUI là thông điệp dựa trên. Nó hoàn toàn là những gì windows làm. Nếu chặn một luồng GUI, hãy đợi GUI của bạn thất bại. –

+2

Vì vậy, điểm mấu chốt là cả hai cửa sổ hiện sử dụng cùng một hàng đợi _input_. Vấn đề cốt lõi nằm trong ** gửi ** đồng bộ của một thông điệp 'WM_ACTIVATE' đến cửa sổ đã đóng băng. Đây là một bài viết nhóm tin khác bao gồm cùng một chủ đề chính xác: [Link] (http://narkive.com/YmRDFrDR). Vì tôi không mong đợi để có thể tách các cửa sổ con _input queue_ với một cái gì đó giống như lệnh 'AttachThreadInput', tôi chấp nhận điều này như một câu trả lời và sẽ sống một cuộc sống hạnh phúc mà không có các mối quan hệ cửa sổ cha/con. Cảm ơn nhiều! –