窗体半透明特效的实现
前面已经对分层窗口做了较为详细的介绍。这里将对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,其窗口区域同样不进行点击检测。
前面说过,SetLayeredWindowAttributes()函数是Windows 2000新增的一个API函数,它所在的模块为USER32.DLL。在用GetModuleHandle()装载USER32.DLL模块并调用GetProcAddress()得到函数 SetLayeredWindowAttributes()在User32.dll中的指针后就可以通过SetLayeredWindowAttributes()函数将窗体设置为半透明了:
// 全局变量 typedef BOOL (WINAPI *lpfn) (HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags); lpfn g_pSetLayeredWindowAttributes; …… // 获取函数 SetLayeredWindowAttributes 在User32.dll中的指针 HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL")); g_pSetLayeredWindowAttributes = (lpfn)GetProcAddress(hUser32, "SetLayeredWindowAttributes"); if (g_pSetLayeredWindowAttributes == NULL) ::PostQuitMessage(0); |
这段代码通常在程序初始化时运行以及时将USER32.DLL模块装载到内存并获取得到SetLayeredWindowAttributes()函数指针。在程序退出前需要通过FreeLibrary()函数释放先前加载的模块:
// 卸载模块 if (m_hUser32 != NULL) FreeLibrary(m_hUser32); |
在将窗体设置为半透明时,首先要获取得到该窗体的窗口句柄,以指明要操作的是哪一个窗口。如果是对本应用程序中的某个窗口进行设置,可以通过传递窗口句柄或是用GetSafeHwnd()来动态获取。如果要对本程序外的某个程序窗口进行设置,一般的做法是通过对FindWindow()函数的调用来获取指定窗口标题的窗口句柄。在得到窗口句柄之后并不能直接调用SetLayeredWindowAttributes()进行设置,需要在GetWindowLong()获取得到当前窗口风格设置后在其基础之上添加WS_EX_LAYERED扩展风格,并通过SetWindowLong()函数将其设置:
// 半透明 HWND hWnd = GetSafeHwnd(); LONG lWindowLong = GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED; ::SetWindowLong(hWnd, GWL_EXSTYLE, lWindowLong); g_pSetLayeredWindowAttributes(hWnd, 0, (BYTE)m_sldAlpha.GetPos(), 2); ::RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); |
为了能够使用该函数,还必须在上述语句之前添加预定义语句:
| #define WS_EX_LAYERED 0x00080000 |
异形窗体特效的实现
使用SetLayeredWindowAttributes()创建异形窗体是非常简单的,具体过程与半透明窗体的实现极为类似,所不同的只是将标志设置为LWA_COLORKEY并指定需要透明显示的关键色:
// 指定关键色 HWND hWnd = GetSafeHwnd(); LONG lWindowLong = GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED; ::SetWindowLong(hWnd, GWL_EXSTYLE, lWindowLong); g_pSetLayeredWindowAttributes(hWnd, RGB(255, 255, 255), 0, 1); ::RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); |
小结
本文通过对Windows 2000新增API函数SetLayeredWindowAttributes()的使用非常简单的实现了窗体的半透明设置和异形窗体的创建。除了SetLayeredWindowAttributes()函数,Windows 2000还提供了其他许多类似的特效函数比如用于窗体动态滑动显示的AnimateWindow()。由于这些函数是系统提供的API函数,因此不会受编程(www.cppentry.com)语言的制约,也就是说,并不只在VC++(www.cppentry.com)下可以实现上述特效。在C++(www.cppentry.com) Builder、Delphi等其他开发环境下也是可以用类似的方法来实现的。本文所述程序代码在Windows 2000 Professional下由Microsoft Visual C++(www.cppentry.com) 6.0编译通过。
|