当前位置:C++技术网 > 精选软件 > Windows零基础入门:2.26 窗口阴影效果CS_DROPSHADOW解密

Windows零基础入门:2.26 窗口阴影效果CS_DROPSHADOW解密

更新时间:2015-09-23 15:28:45浏览次数:1+次

    终于快将窗口类风格讲完了,很是兴奋哦。对于CS_GLOBALCLASS风格,在窗口类中重点讲过了,这类就不在重复了。而今天讲的这个窗口类是最后一个,实现的效果也是非常的棒哦。这个在网上资料几乎没有哦。
    这个窗口类风格就是CS_DROPSHADOW,MSDN解释说,这个风格可以让窗口产生阴影效果。阴影效果就是窗口边缘处的渐变阴影。要想有阴影效果,我们要先使用SPI_SETDROPSHADOW标志来启动阴影或者关闭阴影。调用的函数如下:
SystemParametersInfo(SPI_SETDROPSHADOW,0, (PVOID)TRUE, 0); // - 开启阴影效果
SystemParametersInfo(SPI_SETDROPSHADOW,0, (PVOID)FALSE, 0);// - 关闭阴影效果

     这种效果主要用来凸显增强窗口的层次关系,在最上层的产生厚重的阴影,而不仅仅是窗口标题栏颜色变深。要想窗口有这种阴影效果,创建窗口的窗口类含有这个窗口类风格。窗口不能是子窗口。
    我们先来看看效果图。

    正常的无阴影的效果如下:

   

    有阴影效果的窗口效果如下:

   

     阴影窗口获得焦点和失去焦点时,效果图如下:

   

    以上说的SystemParametersInfo 函数设置的 SPI_SETDROPSHADOW 标志产生的开关阴影效果,是对系统全局有效的。函数名称就是系统参数信息,也就是获取和设置系统参数。所以,如果你开启了这个阴影效果,系统的其他窗口也会产生一样的阴影效果,看看记事本窗口的效果,如下图所示:

   

   而平时我们去掉窗口边框,想实现窗口边框的阴影效果,如果不想自己实现,就可以用这个风格快速实现,下面是效果图:

   

    因为这个效果是让窗口在多个窗口之间凸显层次关系的,所以不适用子窗口。多个窗口都是独立的窗口,才有必要显示这种效果。所以,如果你的窗口设置了WS_CHILD效果,这个阴影就不起作用了。子窗口属于父窗口的一部分,是不能够作为一个独立的窗口来显示效果的,不能自立门户哦。子窗口和父窗口都设置阴影效果,子窗口没有阴影,而父窗口有阴影,效果图如下:

   

    因为阴影效果是全局的设置,你开启后其他窗口也会产生阴影效果。如果关闭,其他窗口的阴影效果也没有了。当然些窗口得具有这个窗口类风格。如果你不开启,是看不到效果的。很多人以为,只要用了这个窗口类风格注册窗口类就行了,其实不是的。阴影效果也很可能被其他程序关掉。所以,要顺利正常的使用,实现前,你一定要手动开启。如果你不想影响到其他窗口,那么显示你的窗口前,你可以开启,显示完后,可以关闭掉。这样就可以保证你的窗口有阴影效果,而不会应用到其他窗口上。或者说开启的时间很短,影响也不会很大。具体的细节,你可以去慢慢研究,研究好了,可以分享到网站哦。一起学习。

    这个风格其实这样说了之后,你就不难理解了。而且有图有真相,一看就明白了。而在网上对于这个风格,没有资料解释,偶有一两篇,还是发的求助帖。实在是感叹原创高质量的资料的稀缺呀。其实很多人费力实现的窗口阴影,不就是想摸你这个效果吗,如果你懂了,是不是分分钟的事情呢?这些网上没有,我们就来构建,提供一个良好的学习环境,提供高质量技术资料的平台。如果你有一些原创经验和技术心得,请无私分享一下吧。

    那么到此,第二章就讲完了。窗口类的相关的东西,基本介绍完毕。至于其他各种API等的使用,已经不是难事了。因为你对窗口类几乎了解的很透彻了。可以说,已经是走在了Windows大神的路上了。当然这个必须是你认真学习了每一节课程哦。成为大神的路,已经免费为你铺开,走不走,就看你自己了。

    其实本节课,并不需要代码验证,因为很简单。不过,就是多了一个函数的使用而已。不过为了完整性,还是将代码贴出来吧,代码如下:

#include <Windows.h>
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);// - 窗口过程函数的声明

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
    WNDCLASS wndclass;
    // - 给创建的窗口类指定各种特性值
    wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DROPSHADOW;// - 窗口基本风格特性
    wndclass.lpfnWndProc = WinProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = L"MyClass";
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, L"注册窗口类失败,此程序需要运行在Windows NT平台下。", L"注册窗口类提示", MB_ICONERROR);
        return 0;
    }
    SystemParametersInfo(SPI_SETDROPSHADOW,0, (PVOID)TRUE, 0);
    HWND hwnd = CreateWindow(L"MyClass", L"有阴影窗口_C++技术网", WS_OVERLAPPEDWINDOW , 100, 100, 600, 600, NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
    SystemParametersInfo(SPI_SETDROPSHADOW, 0, (PVOID)FALSE, 0);
    MSG  msg;
    // - 消息循环
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
HDC hdc;
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // - 放在此处,作为函数内的局部变量,函数结束后,自动释放此句柄
    PAINTSTRUCT ps;
    RECT rect,TRect;
    TRect.left = 0;
    TRect.top = 0;
    TRect.right = 400;
    TRect.bottom = 400;
    TCHAR Tip[256] = {L"C++技术网提示:这是有阴影窗口。"};
    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
        GetWindowRect(hwnd, &rect);
        DrawText(hdc, Tip, -1, &TRect, DT_SINGLELINE);
        EndPaint(hwnd, &ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}


    最终的运行效果如下,我的窗口有阴影,而系统的资源管理器窗口等没有阴影: