2012-05-09 481 views
2

我有一個程序不是由我寫的。我沒有它的來源,該程序的開發者正在獨立開發。他給了我該程序的HWNDHINSTANCE句柄。 我使用win32 api在他的窗口上創建了一個子窗口。 我需要做的第一件事就是讓這個子窗口在某些區域具有透明度,而在其他區域則具有不透明度(例如遊戲的頭部顯示(HUD)),以便用戶可以在兩個窗口中看到事物。在非透明父窗口(win 32)上創建一個透明子窗口

第二件事,我需要的是將所有的輸入指向父窗口。我的孩子窗口不需要輸入。

我知道WS_EX_TRANSPARENT只會讓孩子畫在畫家算法的末尾。 我不能使用WS_EX_LAYERED,因爲它是一個子窗口。

在此先感謝:)

p.s. 我看到處處都是,但沒有找到任何解決方案,雖然有類似的問題在互聯網上。 實際上這是一款適用於該遊戲的HUD。我不能直接在父窗口上繪製,因爲多線程的複雜性還有很多其他的原因。

- 編輯--------------------------- 嘿傢伙, 我仍在努力。嘗試不同的方式與你所有的建議。 是否有將directXSetWindowRgn()函數或directxBitBlt()函數結合的方法。我認爲這會做到這一點。 當前我正在測試所有的東西作爲子窗口和分層窗口。

+0

它很醜,但你可以在窗口上創建一個頂層框架並跟蹤窗口下方的移動。然後設置透明區域: http://www.codeguru.com/cpp/wd/dislog/non-rectangulardialogs/article.php/c5037/Creating-Shaped-Windows-Using-Regions-with-Win32.htm – Pete

+0

如果你使窗口透明,只允許你看到父窗口。你想在父窗口打個洞嗎? – Ben

+0

那麼,你至少需要WS_EX_TRANSPARENT。你需要處理的一個問題是,作者將在WM_ERASEBKGND消息上擦除他的窗口,這將消除你從樣式標誌中獲得的背景像素。因此,您需要對其窗口過程進行子類化並取消或替換該消息。使用WM_PAINT繪製的內容是否仍然運行良好是您需要自行找出的一個懸而未決的問題。如果包含任何具有消除鋸齒邊緣的文字或圖形,則賠率很低。作爲評論發佈,因爲成功的可能性很小。 –

回答

3

好的朋友,最後我做了一些瘋狂的事情,讓它發生。但其效率不如直接使用x直接繪製。

我做什麼,

  • 用在CreateWindowEx
  • (WS_EX_ TRANSPARENT | WS_EX_LAYERED | WS_EX_ TOOLWINDOW)和() 創建窗口後,取出(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)從窗口樣式也 從擴展窗口樣式刪除(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_APPWINDOW)
    • 這給了我一個沒有邊框的窗口,它現在也顯示在 任務欄中。我的 窗口也會傳遞命中率。
  • 子類,其他窗口的窗口過程,並得到了
    • WM_CLOSEWM_DESTROY,送WM_CLOSEWM_DESTROY分別到我的窗口
    • WM_SIZEWM_MOVE,調整大小和移動根據我的窗口另一個 窗口
    • WM_LBUTTONUP,WM_RBUTTONUP,WM_MBUTTONUP,使我的窗口到頂部,仍然保持着對其他窗口,讓我的窗口沒有得到隱藏在其他窗口後面
  • 作出的DirectX設備有兩個通道,
    • 在第一遍它繪製在黑色的所有元素在白色背景上的頂並將backbuffer數據複製到另一個表面(所以​​它給出了黑色的&白色的二進制圖像)
    • 在第二遍中,它將正常繪製事物。
  • 通過使用SetWindowRgn函數讀取黑色&白色曲面,創建另一個線程來保持窗口透明度。

這是完美的工作,唯一的事情是它不是很透明。 另一個問題是給繪製的對象進行alpha混合。 ,但您可以使用SetLayeredWindowAttributes函數輕鬆設置產品alpha(透明度)。

感謝你們給予的所有幫助,你們告訴我的所有事情都被使用過了,他們引導我如你所見。 :) 可悲的是我們決定不使用這種方法,因爲效率問題:( 但我學到了很多東西,這是一個很棒的體驗。那對我來說都很重要:) 謝謝:)

1

您可以使用SetWindowRgn在父窗口打個洞。

此外,僅僅因爲它不是你的窗口並不意味着你不能使它成爲一個分層窗口。

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

最後,您可以通過使用子類採取另一個窗口的控制 - 本質上,你替換你的WndProc代替他們的,處理要處理消息,然後將殘餘傳遞到原來的WndProc。

+0

SetWindowRgn()只是使屏幕繪製在屏幕儀式的某個部分?我試過了,它可以幫助我。 謝謝。 :) – Deamonpog

+0

我看到之前的鏈接,並嘗試過他們。但我擔心如果它會以某種其他方式影響該程序(遊戲)。所以即時嘗試不改變那個窗口,只是得到他的手柄和其他信息,並操縱我的窗口。謝謝你的想法:) – Deamonpog

2

您可以使用WS_EX_LAYERED來自Windows 8及更高版本中的child windows

爲了支持Windows的早期版本,只需創建一個層級窗口作爲彈出窗口(不帶鉻)並確保其位於遊戲窗口的適當位置。大多數用戶不會隨時移動他們正在工作的窗戶,因此,當您需要監控移動的父窗口並重新定位HUD時,這不應該成爲阻擋器。

不注意焦點(在作爲子窗口的情況下)或激活(在彈出的情況下)更有趣,但仍然相當有用: - 操作系統實際上不會自動分配任何焦點或激活到一個點擊的窗口 - Windows WindowProc總是通過調用SetFocus或其他變體SetActiveWindowSetForegroundWindow自己來關注或激活。這裏最重要的是,如果你在不傳遞給DefWindowProc的情況下消耗所有鼠標和非客戶端鼠標消息,你的HUD將永遠不會通過點擊來從遊戲窗口竊取激活或鍵盤焦點。

作爲一個彈出窗口或另一個線程上的窗口,您可能必須手動處理窗口過程所獲得的任何鼠標消息,並將它們發佈到遊戲窗口。否則,對WM_NCHITTESTHTTRANSPARENT(類似於WS_EX_TRANSPARENT達到的效果)的響應可以使系統繼續向下傳遞鼠標消息,直到找到目標爲止。