2008-09-09 30 views
5

Khi một ứng dụng nằm phía sau một ứng dụng khác và Tôi nhấp vào biểu tượng trên thanh tác vụ của ứng dụng, tôi mong đợi toàn bộ ứng dụng đến đến đầu đơn đặt hàng z, ngay cả khi hộp thoại WS_POPUP kiểu ứng dụng là mở .Tại sao việc nhấp vào cửa sổ con không phải lúc nào cũng mang ứng dụng đến nền trước?

Tuy nhiên, một số thời gian, đối với một số hộp thoại của tôi (và những người khác), chỉ có hộp thoại xuất hiện phía trước; phần còn lại của ứng dụng ở lại phía sau.

Tôi đã xem Spy ++ và cho những người hoạt động chính xác, tôi có thể thấy WM_WINDOWPOSCHANGING đang được gửi tới phụ huynh của hộp thoại. Đối với những người mà để lại phần còn lại của ứng dụng phía sau, WM_WINDOWPOSCHANGING không phải là được gửi tới phụ huynh của hộp thoại.

Tôi có ví dụ trong đó một hộp thoại thường mang đến toàn bộ ứng dụng với nó và hộp kia thì không. Cả hộp thoại làm việc và hộp thoại không hoạt động đều có cùng kiểu cửa sổ, trạm biến áp, cha mẹ, chủ sở hữu, ontogeny.

Tóm lại, cả hai đều là các cửa sổ WS_POPUPWINDOW được tạo bằng DialogBoxParam(), đã chuyển vào các HWND giống hệt nhau làm đối số thứ ba.

Có ai khác nhận thấy sự kỳ quặc hành vi này trong các chương trình Windows không? TaskBar gửi thông điệp gì đến ứng dụng khi tôi nhấp vào nút của nó? Trách nhiệm của ai là đảm bảo rằng tất cả các cửa sổ của ứng dụng đều đến nền trước?

Trong trường hợp của tôi cơ sở cha mẹ là một khung MDI ... có yếu tố đó bằng cách nào đó?

Trả lời

0

Cửa sổ chính của hộp thoại có được đặt chính xác không?

Sau khi tôi đăng nội dung này, tôi đã khởi động ứng dụng Windows Forms của riêng mình và sao chép sự cố bạn mô tả. Tôi có hai hộp thoại, một trong những hoạt động chính xác khác không và tôi không thể thấy bất kỳ lý do ngay lập tức là tại sao họ cư xử khác nhau. Tôi sẽ cập nhật bài đăng này nếu tôi tìm hiểu.

Raymond Chen bạn ở đâu!

1

Khi bạn nhấp vào biểu tượng thanh tác vụ, Windows sẽ gửi thông báo WM_ACTIVATE tới ứng dụng của bạn.

Bạn có chắc chắn mã của bạn là đi qua các WM_ACTIVATE thông điệp tới các thủ tục cửa sổ hàm DefWindowProc để chế biến?

4

Tôi biết điều này rất cũ, nhưng tôi chỉ tình cờ gặp nó, và tôi biết câu trả lời.

Trong các ứng dụng bạn đã thấy (và được viết) trong đó đưa hộp thoại lên nền trước làm không mang cửa sổ chính lên cùng với nó, nhà phát triển đã bỏ qua chỉ định chủ sở hữu của hộp thoại.

Điều này áp dụng cho cả hai cửa sổ phương thức, như hộp thoại và hộp tin nhắn, cũng như các cửa sổ không mod. Đặt chủ sở hữu của cửa sổ bật lên không modeless cũng giữ cửa sổ bật lên phía trên chủ sở hữu của nó mọi lúc.

Trong Win32 API, các chức năng để đưa ra một hộp thoại hoặc một hộp thông báo mất sổ chủ sở hữu như một tham số:

INT_PTR DialogBox(
    HINSTANCE hInstance, 
    LPCTSTR lpTemplate, 
    HWND hWndParent,  /* this is the owner */ 
    DLGPROC lpDialogFunc 
); 

int MessageBox(
    HWND hWnd,   /* this is the owner */ 
    LPCTSTR lpText, 
    LPCTSTR lpCaption, 
    UINT uType 
); 

Tương tự, trong .NET WinForms, chủ sở hữu có thể được xác định:

public DialogResult ShowDialog(
    IWin32Window owner 
) 

public static DialogResult Show(
    IWin32Window owner, 
    string text 
) /* ...and other overloads that include this first parameter */ 

Thêm vào đó, trong WinForms, thật dễ dàng để thiết lập các chủ sở hữu của một cửa sổ modeless:

public void Show(
    IWin32Window owner, 
) 

hoặc tương đương:

form.Owner = this; 
form.Show(); 

Trong mã WinAPI thẳng, chủ sở hữu của một cửa sổ modeless thể được thiết lập khi cửa sổ được tạo ra:

HWND CreateWindow(
    LPCTSTR lpClassName, 
    LPCTSTR lpWindowName, 
    DWORD dwStyle, 
    int x, 
    int y, 
    int nWidth, 
    int nHeight, 
    HWND hWndParent, /* this is the owner if dwStyle does not contain WS_CHILD */ 
    HMENU hMenu, 
    HINSTANCE hInstance, 
    LPVOID lpParam 
); 

hoặc sau đó:

SetWindowLong(hWndPopup, GWL_HWNDPARENT, (LONG)hWndOwner); 

hoặc (Tương thích 64 bit)

SetWindowLongPtr(hWndPopup, GWLP_HWNDPARENT, (LONG_PTR)hWndOwner); 

Lưu ý rằng MSDN đã nói như sau về SetWindowLong[Ptr]:

Đừng gọi SetWindowLongPtr với chỉ số GWLP_HWNDPARENT thay đổi phụ huynh của một cửa sổ con. Thay vào đó, hãy sử dụng hàm SetParent.

Điều này có phần gây hiểu nhầm, vì dường như ngụ ý rằng hai đoạn trích ở trên là sai. Đây không phải như vậy. Gọi số SetParent sẽ biến cửa sổ bật lên dự định thành một số con của cửa sổ chính (đặt số WS_CHILD bit), thay vì đặt cửa sổ này thành cửa sổ được sở hữu. Mã ở trên là cách chính xác để làm cho cửa sổ bật lên hiện có là cửa sổ được sở hữu.

+0

Cảm ơn câu trả lời của bạn! Tuy nhiên, đây không phải là nguyên nhân của vấn đề với đơn đăng ký của tôi. Như tôi đã nói trong câu hỏi của mình, tôi đang chuyển chủ sở hữu trong mọi trường hợp. Bất kỳ ý tưởng nào khác? –

+0

Bạn có mẫu có thể tái sản xuất không? –

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