zoukankan      html  css  js  c++  java
  • Win7风格DWM界面的一些高级应用 .

        DWM的高级使用

    本介绍下win7下dwm的一些高级使用,如果还不了解dwm的基础的朋友可以先看下dwm的基础应用,本文主要讨论下如何使用dwm进行自己绘制标题以及如何改变鼠标点击测试,重点是解决gdiplus与透明界面的融合问题。

    开发环境为win7和vs2010,编码语音采用c++,win32的sdk平台进行开发。下面先从第一个问题说起,

    我们也许自己利用DwmExtendFrameIntoClientArea函数进行了简单的绘制,就像这样

    MARGINSmargins={-1};

     

           margins.cxLeftWidth = leftlength;      // 8

           margins.cxRightWidth = rightlength;    // 8

           margins.cyBottomHeight = bottomlength; // 20

           margins.cyTopHeight = toplength;      // 27

     

          

     

           DwmExtendFrameIntoClientArea(hWnd,&margins);

    然后界面就变成了这样 ,但是当我们用鼠标点击上标题下边自己扩展出的区域时,发现鼠标事件不起作用了,于是想该怎么办呢?然后有人想到改变WM_NCCALCSIZE,这样做是不行的,本人亲自做过实验,会导致一部分界面变成白色,然后程序猿们纠结了,这如何是好,当然笔者也让这个问题困扰了好久,然后看到有位大神的文章解决了这个问题,文章地址(http://msdn.microsoft.com/en-us/library/bb688195(VS.85).aspx)把这个文章阅读一次,然后进过消化总结,大概如下几步,先将原来的WndProc函数分成两份,一份是CustomCaptionProc,另一份是AppWinProc,然后我们在自己定义的回调函数中处理标题绘制和点击测试。
    自己定义的回调函数要处理5个消息WM_CREATE,WM_ACTIVATE,WM_PAINT,WM_NCCALCSIZE,WM_NCHITTEST,虽然WM_NCCALSIZE中令非客户增加均为0,但是必须要做,这样才能让系统改变非客户区以实现我们自己去绘制软件界面,然后然后照着大神的代码抄写一遍,自己理解下其中他做了一些什么事情。除了以上要注意的地方,其他都是具体代码实现了,我就不做说明了。OK了鼠标点击问题搞定了,其中比较重要的是要掌握dwmwinproc控制界面的时机,然后调用NCHITTEST去处理界面控制请求,当然还有其他处理方式(把他们全部变成客户区,然后自己绘制界面上的缩小放大关闭框),不过这样的方式付出的代价会变的很大!这样你会发现出现这样的情况:
    
    
    我们的界面的标题没了,于是我们就该想到自己去绘制一个标题给这个窗口,现在
    
    

    我们解决自己绘制标题的过程,以下是我自己写的几个绘制标题的方式,其中第三种绘制方式可能让你感觉在什么情况下都能利用,但是你若仔细去看会发现它的处理会导致在启用了DwmEnableBlurBehindWindow的情况下颜色部分失真,也就是变浅!大家可以将我写的三个绘制标题的函数与SetLayeredWindowAttributes和DwmEnableBlurBehindWindow两者进行组合,你会发现很多有趣的现象,这些情况我就不进行介绍了,原理我目前也无法分析清楚,

    我们可以利用PaintCustomCaption3方式进行绘制窗口的标题,在使用了SetLayeredWindowAttributes时,我们需要采用PaintCustomCaption3的方式进行窗口的标题的绘制。其他情况先不说了,自己去体验吧!(绘制代码放在最后,需要的可以去看下),然后说明如何解决上次说的控件鼠标局部穿透问题,采用解决方案首先获取原来窗口的风格,然后将窗口的风格中CS_PARENTDC去除这样就可以设置子窗口的形状,然后将其形状改变为我们要绘制的形状,完美解决gdiplus和DWM进行窗口绘制时的问题,不加代码前点击“这是个按钮”周围4个角落时会出现鼠标穿透现象,原因是我先将其进行透明色填充,然后再进行按钮样式的绘制,就会产生鼠标穿透界面到达位于界面后方的现象!(最后把关键部分代码附上!)

     

    DWORD style = GetClassLong(g_hedit, GCL_STYLE);

     

        SetClassLong(g_hedit, GCL_STYLE, style &~CS_PARENTDC);   

        HRGN hRgn = CreateEllipticRgn(0, 0, 120,30);

     

        SetWindowRgn(g_hedit, hRgn, FALSE);

     

    然后附上3个绘制标题的函数!结合我上传的dwm上次出现穿透现象的程序一起使用!

     

    voidPaintCustomCaption(HWND hWnd, HDC hdc,LPCTSTR strContent,COLORREF color)

    {

        RECT rcClient;

        GetClientRect(hWnd, &rcClient);

     

     

        HTHEME hTheme =OpenThemeData(::GetDesktopWindow(), L"Window");

        if (hTheme)

        {

           HDC hdcPaint = CreateCompatibleDC(hdc);

           if(hdcPaint)

           {

               intcx = rcClient.right-rcClient.left;

               intcy = rcClient.bottom-rcClient.top;

     

               // Definethe BITMAPINFO structure used to draw text.

               // Notethat biHeight is negative. This is done because

               //DrawThemeTextEx() needs the bitmap to be in top-to-bottom

               // order.

               BITMAPINFO dib = { 0 };

               dib.bmiHeader.biSize            = sizeof(BITMAPINFOHEADER);

               dib.bmiHeader.biWidth           = 150;

               dib.bmiHeader.biHeight          = -30;

               dib.bmiHeader.biPlanes          = 1;

               dib.bmiHeader.biBitCount        = 32;

               dib.bmiHeader.biCompression     = BI_RGB;

     

     

               HBITMAP hbm = CreateDIBSection(hdc,&dib, DIB_RGB_COLORS, NULL, NULL, 0);

              

               if(hbm)

               {

                 

     

                  HBITMAP hbmOld =(HBITMAP)SelectObject(hdcPaint, hbm);

                 

                  HBRUSHThemeBrush=CreateSolidBrush(TRANSPARENT_COLOR);

     

                  FillRect(hdcPaint,&rcClient,ThemeBrush);

                  // Setupthe theme drawing options.

                  DTTOPTS DttOpts      = {sizeof(DTTOPTS)};

                  DttOpts.dwFlags      = DTT_COMPOSITED |DTT_GLOWSIZE|DTT_TEXTCOLOR|DTT_SHADOWTYPE;

                  DttOpts.iGlowSize = 20;

                  DttOpts.crText       = color;

                  DttOpts.iTextShadowType  = 32;

     

     

                  //Select a font.

                  LOGFONT lgFont={0};

                  HFONT hFontOld = NULL;

     

     

                  HFONT hFont =  CreateFont(0,0,0,0,400,

                      FALSE,FALSE,FALSE,DEFAULT_CHARSET,

                      OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH,

                      L"华文行楷");

                  hFontOld = (HFONT)SelectObject(hdcPaint, hFont);

     

                 

     

                  // Drawthe title.

                  RECT rcPaint = rcClient;

                  rcPaint.top += 8;

                  rcPaint.right -= 0;

                  rcPaint.left += 8;

                  rcPaint.bottom = 50;

                  DrawThemeTextEx(hTheme,

                      hdcPaint,

                      0, 0,

                      strContent,

                      -1,

                      DT_LEFT | DT_WORD_ELLIPSIS,

                      &rcPaint,

                      &DttOpts);

     

                  BLENDFUNCTION ftn = { 0 };

                  ftn.BlendOp = AC_SRC_OVER;                                                        //目前只能设置这个值

                  ftn.AlphaFormat =AC_SRC_ALPHA;                                              // 也只能设置这个值

                  ftn.BlendFlags = 0;                                                                         //必须为0

                  ftn.SourceConstantAlpha =255;                                                   //指定源图片的alpha

     

                  // 调用这个函数来进行Alpha混合

                                AlphaBlend(hdcPaint,0,0,150,30,hdc,0,0,150,30,ftn);

     

                  // Blittext to the frame.

                  BitBlt(hdc, 0, 0, cx, cy,hdcPaint, 0, 0, SRCCOPY);

     

                  SelectObject(hdcPaint, hbmOld);

                  if(hFontOld)

                  {

                      SelectObject(hdcPaint,hFontOld);

                  }

                  DeleteObject(hbm);

               }

               DeleteDC(hdcPaint);

           }

           CloseThemeData(hTheme);

        }

    }

     

    voidPaintCustomCaption2(HWND hWnd, HDC hdc,LPCTSTR strContent,COLORREF color)

    {

        HTHEME hTheme =OpenThemeData(::GetDesktopWindow(), L"Window");

        HDC hdcPaint = CreateCompatibleDC(hdc);

     

        RECT rcClient;

        GetClientRect(hWnd, &rcClient);

     

        int cx =rcClient.right-rcClient.left;

        int cy =rcClient.bottom-rcClient.top;

     

        if (hTheme)

        {

           DTTOPTS DttOpts      = {sizeof(DTTOPTS)};

           DttOpts.dwFlags      = DTT_COMPOSITED | DTT_GLOWSIZE|DTT_TEXTCOLOR|DTT_SHADOWTYPE;

           DttOpts.iGlowSize = 1;

           DttOpts.crText       = color;

           DttOpts.iTextShadowType  = 2;

     

     

           // Select afont.

           LOGFONT lgFont={0};

           HFONT hFontOld = NULL;

     

     

           HFONT hFont =  CreateFont(0,0,0,0,400,

               FALSE,FALSE,FALSE,DEFAULT_CHARSET,

               OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH,

               L"华文行楷");

     

           hFontOld = (HFONT)SelectObject(hdc,hFont);

     

           // Draw thetitle.

           RECT rcPaint = rcClient;

           rcPaint.top += 8;

           rcPaint.right -= 0;

           rcPaint.left += 8;

           rcPaint.bottom = 50;

           DrawThemeTextEx(hTheme,

               hdc,

               0, 0,

               strContent,

               -1,

               DT_LEFT | DT_WORD_ELLIPSIS,

               &rcPaint,

               &DttOpts);

     

           // Blit text tothe frame.

          

           SelectObject(hdc,hFontOld);

        }

        CloseThemeData(hTheme);

    }

     

    voidPaintCustomCaption3(HWND hWnd, HDC hdc,LPCTSTR strContent,COLORREF color)

    {

        RECT rcClient;

        GetClientRect(hWnd, &rcClient);

     

     

        HTHEME hTheme = OpenThemeData(NULL, L"CompositedWindow::Window");

        if (hTheme)

        {

           HDC hdcPaint = CreateCompatibleDC(hdc);

           if(hdcPaint)

           {

               intcx =rcClient.right-rcClient.left;

               intcy =rcClient.bottom-rcClient.top;

     

               // Definethe BITMAPINFO structure used to draw text.

               // Notethat biHeight is negative. This is done because

               //DrawThemeTextEx() needs the bitmap to be in top-to-bottom

               // order.

               BITMAPINFO dib = { 0 };

               dib.bmiHeader.biSize            = sizeof(BITMAPINFOHEADER);

               dib.bmiHeader.biWidth           = cx;

               dib.bmiHeader.biHeight          = -cy;

               dib.bmiHeader.biPlanes          = 1;

               dib.bmiHeader.biBitCount        = BIT_COUNT;

               dib.bmiHeader.biCompression     = BI_RGB;

     

               HBITMAP hbm = CreateDIBSection(hdc,&dib, DIB_RGB_COLORS, NULL, NULL, 0);

               if(hbm)

               {

                  HBITMAP hbmOld =(HBITMAP)SelectObject(hdcPaint, hbm);

     

                  // Setupthe theme drawing options.

                  DTTOPTS DttOpts      = {sizeof(DTTOPTS)};

                  DttOpts.dwFlags      = DTT_COMPOSITED |DTT_GLOWSIZE|DTT_TEXTCOLOR|DTT_SHADOWTYPE;

                  DttOpts.iGlowSize = 20;

                  DttOpts.crText       = color;

                  DttOpts.iTextShadowType  = 2;

     

     

                  //Select a font.

                  LOGFONT lgFont={0};

                  HFONT hFontOld = NULL;

     

     

                  HFONT hFont =  CreateFont(0,0,0,0,400,

                      FALSE,FALSE,FALSE,DEFAULT_CHARSET,

                      OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH,

                      L"华文行楷");

                  hFontOld = (HFONT)SelectObject(hdcPaint, hFont);

     

                  // Drawthe title.

                  RECT rcPaint = rcClient;

                  rcPaint.top += 8;

                  rcPaint.right -= 0;

                  rcPaint.left += 8;

                  rcPaint.bottom = 50;

                  DrawThemeTextEx(hTheme,

                      hdcPaint,

                      0, 0,

                      strContent,

                      -1,

                      DT_LEFT | DT_WORD_ELLIPSIS,

                      &rcPaint,

                      &DttOpts);

     

                  // Blittext to the frame.

                  BitBlt(hdc, 0, 0, cx, cy,hdcPaint, 0, 0, SRCCOPY);

     

                  SelectObject(hdcPaint, hbmOld);

                  if(hFontOld)

                  {

                      SelectObject(hdcPaint,hFontOld);

                  }

                  DeleteObject(hbm);

               }

               DeleteDC(hdcPaint);

           }

           CloseThemeData(hTheme);

        }

    }

  • 相关阅读:
    什么是linux的ftp
    linux安装ftp组件
    菜鸟之linux问题之图形界面和dos界面的登录问题
    linux第一面
    vmware下linux系统的安装过程
    vmware的安装
    装饰器的邪门歪道
    关于任务脚本里面用异步
    写类装饰器的2个小问题
    VUE 与其他常见前端框架对比
  • 原文地址:https://www.cnblogs.com/jinsedemaitian/p/5589112.html
Copyright © 2011-2022 走看看