zoukankan      html  css  js  c++  java
  • GDI+ 为了阴影和透明,使用双层窗口遇到的一些问题

    在wnidows C++ 客户端开发中,使用GDI+和png透明或者异形图片,结合UpdateLayeredWindow 双层窗口,可以实现透明,阴影,异形的效果。 其原理便是背景窗口使用UpdateLayeredWindow,刷新png图片,前景窗口作为实际窗口放一些空间,但前景窗口实际上是透明的,这样可以点击移动背景窗口,然后当背景窗口移动时,移动前景窗口。


    1.当时候产品马上要发布的时候,在XP系统上,出现了当窗口最小化到任务栏,无法点击回来。各种使用ModifyStyle(0,  WS_MINIMIZEBOX, 0);

    使用OnACtive(),各种难受就是谈不出来,无奈只好绕过了这个问题。后来才发现了原因。

    void CBackDlg::OnMove(int x, int y) 
    {
    	CDialog::OnMove(x, y);
    	CRect rect;
    	GetWindowRect(rect);
    
        //在XP和win7行都正常。
        m_pChildWnd->MoveWindow(rect.left, rect.top, rect.Width(), rect.Height());                   
    
        //在XP系统上,当窗口回到任务栏时候,点击任务栏窗口就出不来了。但在win7上正常。
        //m_pChildWnd->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_SHOWWINDOW);
    }


    2.第一次启动窗口位置设定,UpdateLayeredWindow的第二个参数,当然你也可以在OnInitDialog中设置,但有时候效果

    似乎不是很好。

    BOOL CBackDlg::OnEraseBkgnd(CDC *pDC)
    {
        CRect  rect;
        this->GetClientRect(rect);
    
        if(!m_pBkImage)
        {
            m_pBkImage = new Image(_T("main_frame.png"));
        }
    
    	int wndW = rect.Width();
    	int wndH = rect.Height();
    
        CDC  memDC;
        CBitmap memBmp;
        memDC.CreateCompatibleDC(pDC);
        memBmp.CreateCompatibleBitmap(pDC, wndW, wndH);
        CBitmap *pOldBmp = memDC.SelectObject(&memBmp);
    
        ModifyStyleEx(0, WS_EX_LAYERED);
    
        Graphics bmpGraphics(memDC.m_hDC);
        bmpGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
        bmpGraphics.DrawImage(m_pBkImage, 0, 0, wndW, wndH); 
    
        BLENDFUNCTION  _Blend;
        _Blend.BlendOp = 0;
        _Blend.BlendFlags = 0;
        _Blend.AlphaFormat =1;
        _Blend.SourceConstantAlpha = 255;
    
        int posX = (GetSystemMetrics ( SM_CXSCREEN ) - wndW)/2; 
        int posY = (GetSystemMetrics ( SM_CYSCREEN ) - wndH)/2; 
    
        //此时,鼠标会穿透窗体中Alpha值为0的区域。 并且计算了在屏幕的位置
        UpdateLayeredWindow(pDC, &CPoint(posX, posY), &CSize(wndW, wndH),
            &memDC, &CPoint(0, 0), 0, &_Blend, ULW_ALPHA);
    
        bmpGraphics.ReleaseHDC(memDC.m_hDC);
        memDC.SelectObject(pOldBmp);
        memDC.DeleteDC();
        return TRUE;
    }
    


    3.托盘菜单遮盖对话框不能移动的问题,不要动态创建托盘和菜单就行。


    4.单层窗口能否实现png阴影和透明效果?

    当然可以实现的,可惜的你窗口上所有控件将不再显示,使用UpdateLayeredWindow后,窗口将不再响应OnPaint, OnEraseBkgnd消息,这点就是微软的恶心,意思是你要使用UpdateLayeredWindow,那么就全部重画吧,我不管了。使用spy++时查看疼讯QQ,金山杀毒的阴影效果的窗口,也有WS_EX_LAYERED扩展状态,似乎也会用到UpdateLayeredWindow,就不知道他们是不是单层能实现了。 知识太有限,待以后研究学习。

  • 相关阅读:
    Docker启动ubuntu容器中使用sudo后报错,bash: sudo: command not found
    Redis持久化rdb&aof
    Python3中copy模块常用功能及其他几种copy方式比较
    学习笔记:tkinter模块常用参数(python3)
    Python核心编程第二版(中文).pdf 目录整理
    11、487-3279
    10、Crashing Balloon
    9、Exponentiation
    8、Fire Net
    7、Reverse Root
  • 原文地址:https://www.cnblogs.com/yuzhould/p/4454261.html
Copyright © 2011-2022 走看看