創建透明窗口及其應用--屏幕畫筆

創建透明窗口及其應用--屏幕畫筆


 

示例代碼下載:創建透明窗口(屏幕畫筆).zip (請不要直接使用迅雷下載)

注:VC6下編譯通過

 


 

 

一、使窗口透明其實很簡單。就是一個函數SetLayeredWindowAttributes

 

步驟如下:

 

步驟一:讓窗口具透明的特性

::SetWindowLong(m_hWnd,GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_LAYERED);

 

當你不希望窗口透明時,就使這個添加的屬性去掉就可以了,如下:

 

 //取消透明
  ::SetWindowLong(m_hWnd,GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)& ~WS_EX_LAYERED);

 

當然,最後別忘記先定義WS_EX_LAYERED,否則編譯時會無法識別WS_EX_LAYERED

#define WS_EX_LAYERED 0x00080000

 

步驟二:獲得SetLayeredWindowAttributes函數

 

這個函數需要從USER32.DLL裏獲得,調用如下。

  //獲取模塊裏的函數
HINSTANCE hInst=GetModuleHandle(_T("USER32.DLL")); 

 BOOL (WINAPI *SetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD)=
    (BOOL (WINAPI*)  (HWND,COLORREF,BYTE,DWORD))GetProcAddress(hInst,"SetLayeredWindowAttributes");

 

這樣我們就獲得了函數SetLayeredWindowAttributes。函數解釋如下

BOOL SetLayeredWindowAttributes(
HWND hwnd,   handle to the layered window
COLORREF crKey,   specifies the color key
BYTE bAlpha,  value for the blend function
DWORD dwFlags  action);
   其中dwFlags有LWA_ALPHA(值爲2)和LWA_COLORKEY(值爲1)兩種設置,如果LWA_ALPHA被設置的話,
通過bAlpha參數指定窗體的透明度;如果LWA_COLORKEY標誌被設置的話,則指定關鍵色爲crKey,
該顏色所覆蓋的區域將從窗體去除,去除後的區域將不再進行點擊檢測,其他顏色則正常顯示。
如果阿爾法混合值設置爲0,其窗口區域同樣不進行點擊檢測。

 

步驟三:調用函數設置透明。

 

方式一:設置我們指定的顏色透明掉。(第4參數設爲1,此時第二個參數是要透明的顏色,其他參數不管)

   //設置窗口透明。第4參數爲1時,第二個參數是要透明的顏色
   SetLayeredWindowAttributes(m_hWnd,RGB(244,243,238),0,1); 

具體代碼如下:(複製粘貼後可以直接使用)

 HINSTANCE hInst=GetModuleHandle(_T("USER32.DLL"));
 if (hInst)
 {
  //獲取模塊裏的函數
  BOOL (WINAPI *SetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD)=
    (BOOL (WINAPI*)  (HWND,COLORREF,BYTE,DWORD))GetProcAddress(hInst,"SetLayeredWindowAttributes");

  //函數指針正確獲取
  if(SetLayeredWindowAttributes)
  {
   //讓窗口具透明的特性
   ::SetWindowLong(m_hWnd,GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_LAYERED);
   
   //設置窗口透明。第4參數爲1時,第二個參數是要透明的顏色
   SetLayeredWindowAttributes(m_hWnd,RGB(244,243,238),0,1); 
  }

  FreeLibrary(hInst); //釋放調模塊句柄
 }

 

方式二:設置窗口具有某種透明度。(第4參數設爲2,此時第三個參數表示透明度的值,其他參數不管)

 

   //設置窗口透明。第4參數爲2時,第三個參數表示透明度
   SetLayeredWindowAttributes(m_hWnd, 0, 80, 2); 

具體代碼如下:(複製粘貼後可以直接使用)

 HINSTANCE hInst=GetModuleHandle(_T("USER32.DLL"));
 if (hInst)
 {
  //獲取模塊裏的函數
  BOOL (WINAPI *SetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD)=
    (BOOL (WINAPI*)  (HWND,COLORREF,BYTE,DWORD))GetProcAddress(hInst,"SetLayeredWindowAttributes");

  //函數指針正確獲取
  if(SetLayeredWindowAttributes)
  {
   //讓窗口具透明的特性
   ::SetWindowLong(m_hWnd,GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_LAYERED);
   
   //設置窗口透明。第4參數爲2時,第三個參數表示透明度
   SetLayeredWindowAttributes(m_hWnd, 0, 80, 2); 
  }

  FreeLibrary(hInst); //釋放調模塊句柄
 } 

 


 

二、透明窗口的應用:屏幕畫筆

 

1.我們可以創建一個透明的窗口。讓其背景色透明掉。比如背景色是RGB(244,243,238),我們使用:

 SetLayeredWindowAttributes(m_hWnd,RGB(244,243,238),0,1);

就可以把背景色去掉。

 

2.當我們使用窗口的屏幕DC畫圖時,由於顏色不是背景顏色RGB(244,243,238),所以我們畫的線都會保留在透明窗口上。

 

3.把窗口的邊框去掉,並且覆蓋整個屏幕。而且要置窗口爲最頂層窗口。這樣就可以實現屏幕畫筆了。

 

4.畫圖時,由於窗口透明瞭,所以我們的鼠標消息不會給透明窗口捕獲到。這時我們可以安裝一個低級鼠標鉤子(之所以要用

低級鼠標鉤子因爲它夠方便,直接寫在程序裏,不用dll),用於捕獲鼠標的說有消息。

 

具體代碼如下:當然你也可以參考我上面提供的源代碼。

 

 

HWND g_hWnd;
POINT LastPoint;
bool IsDrawingLine=false;

BOOL CDemoDlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE);   // Set big icon
 ::SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); //設置窗口最頂
  static CLoadMyLibrary inst(m_hWnd);
 //-----------------------------------------------------------------------------

 g_hWnd=m_hWnd;
 OnButton1();

 return TRUE; 
}


/****************************************************************************
低級鼠標鉤子
#define   _WIN32_WINNT   0x0500  //必須在stdafx.h中添加這一句
****************************************************************************/
HHOOK g_LowLevelMouseHook=NULL; //鉤子句柄
LRESULT CALLBACK LowLevelMouseProc(int nCode,WPARAM wParam, LPARAM lParam)
{
 if (nCode<0 )
  return CallNextHookEx(g_LowLevelMouseHook,nCode,wParam,lParam);
 
 static POINT point;
 point=(POINT)((MSLLHOOKSTRUCT *)lParam)->pt;

 switch (wParam)
 {
 case WM_LBUTTONDOWN:
  {
   TCHAR ClassName[20]={0};
   ::GetClassName(::WindowFromPoint(point),ClassName,sizeof(ClassName)/sizeof(TCHAR));
   if (_tcscmp(ClassName,_T("Button"))==0)
    break;

   ::ScreenToClient(g_hWnd,&point);
   LastPoint=point;
   IsDrawingLine=true;
   return 1;
  }
  break;
 case WM_LBUTTONUP:
  {
   IsDrawingLine=false;
  }
  break;
 case WM_MOUSEMOVE:
  {
   if (IsDrawingLine)
   {
    ::ScreenToClient(g_hWnd,&point);

    //畫鼠標移動痕跡
    HDC hdc=::GetDC(g_hWnd);   //畫曲線
    HPEN pen=::CreatePen(PS_SOLID,4,RGB(30,30,30));
    SelectObject (hdc,pen) ;
    ::MoveToEx(hdc,LastPoint.x,LastPoint.y,NULL);
    ::LineTo(hdc,point.x,point.y);
    LastPoint=point;
    DeleteObject(pen);
    ::ReleaseDC(NULL,hdc) ;
   }
   
  }
  break;
 }
 return CallNextHookEx(g_LowLevelMouseHook,nCode,wParam,lParam); //傳遞鉤子信息  
}

 

#define WS_EX_LAYERED 0x00080000

void CDemoDlg::OnButton1()
{
 HINSTANCE hInst=GetModuleHandle(_T("USER32.DLL"));
 if (hInst)
 {
  //獲取模塊裏的函數
  BOOL (WINAPI *SetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD)=
    (BOOL (WINAPI*)  (HWND,COLORREF,BYTE,DWORD))GetProcAddress(hInst,"SetLayeredWindowAttributes");

  //函數指針正確獲取
  if(SetLayeredWindowAttributes)
  {
   //讓窗口具透明的特性
   ::SetWindowLong(m_hWnd,GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_LAYERED);
   
   //設置窗口透明。第4參數爲1時,第二個參數是要透明的顏色
   SetLayeredWindowAttributes(m_hWnd,RGB(244,243,238),0,1); 
  }

  FreeLibrary(hInst); //釋放調模塊句柄
 }
}


void CDemoDlg::OnButton5()
{
 HINSTANCE hInst=GetModuleHandle(_T("USER32.DLL"));
 if (hInst)
 {
  //獲取模塊裏的函數
  BOOL (WINAPI *SetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD)=
    (BOOL (WINAPI*)  (HWND,COLORREF,BYTE,DWORD))GetProcAddress(hInst,"SetLayeredWindowAttributes");

  //函數指針正確獲取
  if(SetLayeredWindowAttributes)
  {
   //讓窗口具透明的特性
   ::SetWindowLong(m_hWnd,GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_LAYERED);
   
   //設置窗口透明。第4參數爲2時,第三個參數表示透明度
   SetLayeredWindowAttributes(m_hWnd, 0, 80, 2); 
  }

  FreeLibrary(hInst); //釋放調模塊句柄
 } 
}


void CDemoDlg::OnButton2()
{
 //取消透明
  ::SetWindowLong(m_hWnd,GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)& ~WS_EX_LAYERED);
}

 

void CDemoDlg::OnButton3()
{
 //取消所有邊框
 ::SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)
  & ~WS_CAPTION & ~WS_THICKFRAME  );  
 ::SetWindowPos(m_hWnd,NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED); 

// //如果有WS_EX_DLGMODALFRAME還要取消WS_EX_DLGMODALFRAME
// ::SetWindowLong(m_hWnd,GWL_EXSTYLE,GetWindowLong(m_hWnd,GWL_EXSTYLE)
//  & ~WS_EX_DLGMODALFRAME);
// ::SetWindowPos(m_hWnd,NULL,0,0,0,0,SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); 

 int cx=GetSystemMetrics(SM_CXSCREEN);
 int cy=GetSystemMetrics(SM_CYSCREEN);
 ::SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,cx,cy,NULL);
}

void CDemoDlg::OnButton4()
{
 //添加標題欄
 ::SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)
  | WS_CAPTION  );  
 ::SetWindowPos(m_hWnd,HWND_TOPMOST,100,100,400,400,SWP_FRAMECHANGED);
}

 

void CDemoDlg::OnButton6()
{
 if(g_LowLevelMouseHook!=NULL)
  return;

 //start Low Level mouse hook
 g_LowLevelMouseHook=SetWindowsHookEx(WH_MOUSE_LL,LowLevelMouseProc,GetModuleHandle(NULL),0);
 if(!g_LowLevelMouseHook)
  ::MessageBox(m_hWnd,TEXT("SetWindowsHookEx LowLevelMouseProc failed"),NULL,MB_OK);
 
}

void CDemoDlg::OnButton8()
{
 //stop Low Level mouse hook
 UnhookWindowsHookEx(g_LowLevelMouseHook);
 g_LowLevelMouseHook=NULL;
}

 

void CDemoDlg::OnButton7()
{
 ::InvalidateRect(m_hWnd,NULL,true); 
}

 

 

 

希望對你有所幫助!阿彌陀佛!

 


 

 

 

推薦:

獅姐的博客(獅子窩,學佛與靈魂之探究)
大方廣(學習傳統文化)
慈善點擊(輕鬆一點,行善積德,何樂不爲)
電影《地球公民》(揭示不爲人知的一面)  
心向光明 遠離邪淫(現世警鐘,不可不看)
戒淫(上篇)(正淫節慾,戒除邪淫) 
戒淫(中篇)(縱慾之樂,憂患隨之)
公民教育——命由我造

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章