Win32實現窗口盜竊(一)

Win32實現窗口盜竊(一)

這裏所謂「窗口盜竊」,是指把其餘窗口「裝」進程序自身,感受就像是把其餘程序「偷」到了本身的袋裏。程序還有另外一個重要功能,就是讓其餘程序沒法響應鍵盤、鼠標消息——固然,這就有點邪惡了,不過實現方法倒是有時在編寫Win32程序常常用到的一種技術。本文先簡單講解功能一的實現,下一篇文章將會對功能二進行介紹。函數

實現原理

1. 廣義的窗口

要想知道如何把其餘程序「裝」入自身,那麼首先須要理解父窗口的概念。先從窗口提及。
在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

2. 父窗口的引入

那麼爲何要說明這個按鈕是一個子窗口呢?由於獨立的按鈕是不存在的,任何控件都是爲了更好的協助用戶與主窗口(程序)之間的交互而存在的,控件脫離了所屬的窗口是沒有意義的。因此,這裏的按鈕就有一個父窗口,也就是說,按鈕所在的窗口就是按鈕的父窗口。
不過這裏的按鈕可不是簡單地畫在父窗口上,而是附着。說得再直白點,父窗口若是被關閉了,那麼按鈕也就沒有了附着的空間,因而按鈕也要被銷燬。若是把父窗口當成一面牆,那麼按鈕就比如是粘在牆上的掛鉤;要是牆不存在了,那難道掛鉤還能粘在空氣上嗎?進程

3. 在本例中的應用

窗口上粘着一大堆控件,咱們也能夠把別的程序的窗口當成控件一塊兒粘在咱們的窗口上。因此,核心思想就是把別的程序的父窗口設置成咱們的窗口,並且不去管它本來到底有沒有父窗口。
這裏咱們要用到的最關鍵的API是CWnd類中的成員函數 SetParent(這裏的示例程序用MFC完成,因此不使用Plaform SDK版本的)。這個函數很簡單:get

CWnd* SetParent(CWnd* pWndNewParent);

參數指明要成爲該窗口新的父窗口的指針。form

代碼演示

既然把大象裝進冰箱要三步,那麼通常地,把別的窗口裝進咱們的窗口也須要三步:class

  1. 找到別的窗口原理

  2. 獲取該窗口的句柄(指針)程序

  3. 裝進咱們的窗口

是否是很是的簡單?

相關文章
相關標籤/搜索