Window 視窗屬性及內凹視窗到D3D渲染視窗頂層

來源:互聯網
上載者:User

Window視窗有很多屬性,可以通過設定window的style和ex style中知道。

這些屬性有時候在實現某些效果的時候,是非常非常重要(以前都沒有怎麼詳細瞭解,只是在用到對應的API時看一下,根本沒有詳細深入)。

這裡想記錄一下最近工作上遇到的問題,是關於視窗的層次關係或者可以說是彼此之間的內含項目關聯性,和視窗控制的經驗

首先,需要知道parent和owner之間的區別:

1、如果一個視窗有WS_CHILD屬性,那麼它一定有一個父視窗,即GetParent()返回的一定是其父視窗;

2、如果一個視窗有WS_CHILD屬性,那麼它一定不能夠是popup/overlap(這兩個屬性在CreateWindow裡面出入,或者使用GetWindowLong/SetWindowlong,GWL_STYLE進行設定)視窗;

3、top-level視窗是指,在案頭下一層的視窗,它只能是popup/overlap視窗;

4、popup/overlap視窗,是top-level視窗,通常popup視窗是我們看到的普通的dialog視窗,而overlap視窗是我們用MFC直接建立的那些single document的視窗;

5、owner視窗只能是top-level視窗,owned視窗也是top-level視窗;

6、GetParent()函數返回的是對應視窗的parent,或者是owner視窗

7、GetWindow(hWnd, GW_OWNER)返回的只能夠是owner視窗,否則就是NULL;

8、要擷取真正的parent視窗,邏輯應該這樣:UINT style = GetWindowLong(hWnd, GWL_STYLE);  return style & WS_CHILD ? GetParent(hWnd) : GetWindow(hWnd, GW_OWNER);

由於以下這篇文章寫得實在太好了,我是參考下面得出上面的結論的:

http://www.laho.gov.cn/cjs_new/print.jsp?oldID=34

這個blog也有對視窗屬性的詳細講解,我也參考了一些呢:

http://www.cppblog.com/Clouderman/default.html?page=2

然後就是MSDN上的東西也是需要看的:

http://msdn.microsoft.com/en-us/library/ms632599%28v=VS.85%29.aspx

msdn貌似才是最權威的,但上面的那個文章中提及的東西和其中的實驗,非常值得一看,看完上面,再看下面,會比較實際,呵呵

如何將一個視窗掛在一個D3D渲染的視窗前面,目前有三種選擇:

1、建立owner/owned視窗

由於owned視窗一定在owned視窗前面,所以這個方法是行得通的。window的機制,能夠確保:

1) owner視窗渲染完之後,再渲染owned視窗;

2) owner視窗最小化時,owned視窗也一起最小化;

3) owner視窗恢複的時候,owned視窗也一起恢複;

如果你在spy++中查看owner和owned視窗的層次,你會發現他們是在同一層的,owner/owned視窗關係沒有parent/child視窗關係強!(詳細的看上面的連結,裡面有更清楚的描述)。

我這裡想說的是,owner/owned視窗,有一個限制條件,就是owner/owned視窗都必須是top-level視窗。這就出問題了:如果我的D3D視窗是某個視窗的子視窗,怎麼辦呢?那麼這時候,就會很容易出現問題了,由於渲染的D3D視窗本身是一個child視窗,十分容易收到父視窗的影響,而你建立的這個owned視窗,是受渲染視窗的父視窗控制的,由於你通常都是擁有渲染視窗的HANDLE,有時候owner視窗做出的操作並不是你想要的!這時候就麻煩了,需要通過檢測各種各樣的訊息避免一些你不想出現的情況。

PS:建立owner/owned視窗的SDK方法是:CreateWindow("mywinclass", "title",
WS_POPUP,
x, y, w, h,
hOwnerWnd, NULL, hInst, NULL); 其中WS_POPUP和hOwnerWnd這裡必須要填,WS_POPUP可以是WS_OVERLAPPED屬性(因為這樣可以建立出一個top-level視窗)

2、parent/child關係的視窗

其實可以將owner/owned看作是一種弱的parent/child關係。所以上面描述的有點,parent/child都有。但parent不需要一定是top-level,所以你的child肯定可以綁定在parent上,而且一定是顯示在parent視窗前面,這正是我們想要的。但parent在invalid的時候,會發送repaint訊息到child中,由於是D3D視窗(一般在30幀渲染一次,導致視窗invalid),所以一定會導致child視窗不停收到repaint的訊息,而出現閃爍的問題。

ms已經想到有這個情況了,所以提供了一個WS_CLIPCHILEDREN的屬性,用來設定parent的視窗,這樣,parent在invalid的時候,就不會不停地發訊息過去了。

所以這裡也需要注意了,這個child視窗的渲染,必須你自己來管理,如果你依賴parent視窗invalid的時候重新整理的話,那麼不好意思,肯定有BUG了

3、top-most視窗

這個不用多說了吧,在SetWindowPos的時候可以設定的,不同通常用在全屏是,其他情況應該很少用到

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.