這裏所謂「窗口盜竊」,是指把其餘窗口「裝」進程序自身,感受就像是把其餘程序「偷」到了本身的袋裏。程序還有另外一個重要功能,就是讓其餘程序沒法響應鍵盤、鼠標消息——固然,這就有點邪惡了,不過實現方法倒是有時在編寫Win32程序常常用到的一種技術。本文先簡單講解功能一的實現,下一篇文章將會對功能二進行介紹。函數
要想知道如何把其餘程序「裝」入自身,那麼首先須要理解父窗口的概念。先從窗口提及。
在Win32中,窗口有着豐富的含義,除了常見的大多數應用程序都有的矩形區域是窗口之外,還有不少部分其實也是窗口,好比按鈕、編輯框、標籤等控件也是窗口,因此在理解什麼是窗口時,咱們必定不能僅僅侷限於矩形區域這種思惟模式下。
爲了能更深刻地讀懂窗口以及窗口背後的代碼,先來看一下Win32 Platform SDK中用於建立窗口的API CreateWindow的定義:指針
HWND WINAPI CreateWindow( _In_opt_ LPCTSTR lpClassName, _In_opt_ LPCTSTR lpWindowName, _In_ DWORD dwStyle, //指定要建立的窗口的樣式 _In_ int x, _In_ int y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam );
這裏咱們只關心其中的dwStyle參數,關於CreateWindow
的具體用法和更多API介紹,我會在以後的其餘文章中陸續給出。
dwStyle是一個32位的雙字,也就是說咱們能夠用位或操做(|)
將多個屬性組合到一塊兒,好比,要建立一個按鈕時,咱們就能夠這麼寫:code
CreateWindow( "BUTTON", "OK", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, //只看這裏 10, 10, 100, 100, hwnd, NULL, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
這裏,咱們就用了三個屬性的組合,其中WS_CHILD
代表這是一個子窗口,BS_DEFPUSHBUTTON
說明要建立一個按鈕。orm
那麼爲何要說明這個按鈕是一個子窗口呢?由於獨立的按鈕是不存在的,任何控件都是爲了更好的協助用戶與主窗口(程序)之間的交互而存在的,控件脫離了所屬的窗口是沒有意義的。因此,這裏的按鈕就有一個父窗口,也就是說,按鈕所在的窗口就是按鈕的父窗口。
不過這裏的按鈕可不是簡單地畫在父窗口上,而是附着。說得再直白點,父窗口若是被關閉了,那麼按鈕也就沒有了附着的空間,因而按鈕也要被銷燬。若是把父窗口當成一面牆,那麼按鈕就比如是粘在牆上的掛鉤;要是牆不存在了,那難道掛鉤還能粘在空氣上嗎?進程
窗口上粘着一大堆控件,咱們也能夠把別的程序的窗口當成控件一塊兒粘在咱們的窗口上。因此,核心思想就是把別的程序的父窗口設置成咱們的窗口,並且不去管它本來到底有沒有父窗口。
這裏咱們要用到的最關鍵的API是CWnd
類中的成員函數 SetParent(這裏的示例程序用MFC完成,因此不使用Plaform SDK版本的)。這個函數很簡單:get
CWnd* SetParent(CWnd* pWndNewParent);
參數指明要成爲該窗口新的父窗口的指針。form
既然把大象裝進冰箱要三步,那麼通常地,把別的窗口裝進咱們的窗口也須要三步:class
找到別的窗口原理
獲取該窗口的句柄(指針)程序
裝進咱們的窗口
是否是很是的簡單?