创建透明窗口及其应用--屏幕画笔


示例代码下载:创建透明窗口(屏幕画笔).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);
}

希望对你有所帮助!阿弥陀佛!

创建透明窗口及其应用--屏幕画笔相关推荐

  1. window程序设计(创建、选择和删除画笔)

    尽管使用备用对象中的画笔非常方便,但只能使用实心的黑色画笔.实心的白色画笔 或者没有画笔三种情况.如果想获得更丰富的效果,则必须创建自己的画笔. 这里是创建画笔的一-般过程:调用CreatePen或者 ...

  2. 从零开始创建一个Android主屏幕Widget

    登录 / 注册 IT168首页 手机 整机 DIY硬件 摄影 消费数码 数字家电 企业IT 企业商用 办公 互动 社区 全部频道 IT168技术开发频道 IT168首页 > 技术开发 >  ...

  3. python怎么让按钮透明,python – 有没有办法用Tkinter创建透明窗口?

    我最终尝试使用Tkinter模块用Python创建"形状奇特的窗口".但是现在我将满足于能够使背景透明,同时保持儿童小部件完全可见. 我知道这是通过wxPython和其他一些模块完 ...

  4. SAP 供应商创建默认字段(屏幕格式)后台配置总结

    供应商创建默认字段(屏幕格式)后台配置总结 供应商创建时默认字段(屏幕格式的配置在好几个地方的配置来控制. 一 .定义与采购组织特定的屏幕格式 (事务代码: OMFK) IMG路径为如下图: 在这里特 ...

  5. HTML创建12列小屏幕网格,Bootstrap 网格系统布局详解

    Bootstrap 提供了一套响应式.移动设备优先的流式网格系统(Grid System),随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列. 一.什么是网格(Grid)? 在平 ...

  6. HTML创建12列小屏幕网格,Bootstrap 网格系统(Grid System)

    Bootstrap 网格系统(Grid System) Bootstrap提供了一套响应式,移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列. 什么是 ...

  7. MIGO 行项目屏幕增强创建实例

    本人诚心接ABAP远程开发任务,价格公道,有需要的联系我,欢迎个人,甲方爸爸,乙方私信联系. 1.首先创建一张自建表用于存放客制化信息 2.建立结构,在屏幕数据交换时使用 3.建立表类型 4.给之前创 ...

  8. 现有的画笔和创建自己的画笔6zhongGDI

    Windows会使用当前选入设备环境的"画笔"来绘制直线,画笔决定了线条的颜色,宽度和样式,样式可以是实线,点线或者虚线.画笔的默认设备环境是BLACK_PEN,该画笔绘制了一条实 ...

  9. 现有的画笔和创建自己的画笔

    Windows会使用当前选入设备环境的"画笔"来绘制直线,画笔决定了线条的颜色,宽度和样式,样式可以是实线,点线或者虚线.画笔的默认设备环境是BLACK_PEN,该画笔绘制了一条实 ...

最新文章

  1. 力扣(LeetCode)刷题,简单题(第5期)
  2. Verilog以及VHDL所倡导的的代码准则
  3. Excel实战技巧之[活用条件格式]
  4. 面向服务的计算(SOC)课程相关资料
  5. [Winform]一个简单的账户管理工具
  6. Linux学习之zImage内核镜像解压过程详解
  7. 西工大java高级网络编程_奥鹏西工大16春《JAVA高级网络编程》平时作业
  8. 特斯拉CEO马斯克又怼巴菲特:别把冰雪皇后给毁了
  9. 【二分】【中等难度】noip模拟赛 聪哥的工资
  10. Python执行Linux系统命令方法
  11. python处理access数据库教程_Python操作Access数据库基本步骤分析
  12. PID 详解 (附伪代码
  13. 三维实景拍摄虚拟现实!- Panorama
  14. [RK3288][Android6.0] 主动从WLAN网络切换到移动数据网络
  15. 腾讯云神笔低代码平台的申请没通过,只能等公测了
  16. HTTP状态码完整介绍
  17. 2023北京影视技术设备展览会
  18. windows下安装speedtest的经历和问题
  19. 跑过的城市,走过的路
  20. 【连接池】Tomcat 连接池中 maxActive,maxWait,maxAge,testOnBorrow,testWhileIdle等选项的作用

热门文章

  1. 【小练习06】HTML+CSS--电影公告
  2. Centos7下关闭带验证的MongoDB
  3. Linux新建yaml文件,yaml文件创建pod和deployment
  4. python访问服务器注册表,如何在Python中使用写入权限打开Windows注册表
  5. java强制转换_java强制类型转换
  6. python装饰器深度讲解_python核心知识讲解,干货!!!
  7. 微软商店中的WSL预览版现已可用!Windows 11用户狂喜
  8. 【GOTC 预告】王思宇:从 OpenKruise 看云原生应用负载发展趋势
  9. Java 线上问题排查神器 Arthas 快速上手与原理浅谈
  10. java date 操作类_JAVA时间操作类常用方法汇总