使用MFC制作windows悬浮球

上周入手一个二手windows平板(目的只是为了玩),发现习惯使用手机悬浮球后,再转到winpad上操作极为不便,比如想显示桌面都要小心翼翼点,切换任务也比较麻烦(本人不习惯开启平板模式,使用的是常规桌面),只能抽空实现一个再windows上运行悬浮球了。

既然是球,那肯定是个圆的,好多年没碰MFC,依稀记得有一个API可以实现指定窗口透明色,然后达到异形窗口的目的,这就是SetLayeredWindowAttributes,一波操作下来,窗口确实能实现圆球形了,但是圆周边有很多毛边和锯齿,如图:

 东西能用,但就是丑,然后继续网上找资料,大致锁定实现策略:

1、制作边缘柔化的PNG图,画布为透明色

2、使用GDI+加载PNG

3、调用UpdateLayeredWindow接口进行透明化窗口

最终效果如下:

最后增加个时钟,实现悬浮球自动贴边、隐藏等功能,回头再看看,终于满足我的审美和要求了,放在平板上运行,一切良好。下面贴出关键代码:

// 加载PNG资源
static Gdiplus::Bitmap* LoadPngRes(HINSTANCE hinst, const wchar_t* name)
{
    auto hres = FindResourceW(hinst, name, L"PNG");
    if (!hres)
        return nullptr;//resource not found

    if (auto size = SizeofResource(hinst, hres))
    {
        if (auto data = LockResource(LoadResource(hinst, hres)))
        {
            if (auto stream = SHCreateMemStream((const BYTE*)data, size))
            {
                auto* bmp = new Gdiplus::Bitmap(stream);
                if (!bmp)
                {
                    //wrong input, or gdiplus was not initialized
                }
                stream->Release();
                return bmp;
            }
        }
    }

    return nullptr;
}

BOOL CMyGraphics::CreatePng(DWORD dwResID)
{
    if (m_pMemDC != NULL)
    {
        m_pMemDC->SelectObject(m_pOldBmpPng);
        m_pMemDC->DeleteDC();
        delete m_pMemDC;
        m_pMemDC = NULL;
    }

    m_pMemDC = new CDC;
    if (!m_pMemDC->CreateCompatibleDC(NULL))
    {
        return FALSE;
    }

    m_pPng = LoadPngRes(AfxGetInstanceHandle(), MAKEINTRESOURCEW(dwResID));

    Gdiplus::Color color;
    HBITMAP hBitmap;
    m_pPng->GetHBITMAP(color, &hBitmap);
    m_pOldBmpPng = (HBITMAP)m_pMemDC->SelectObject(hBitmap);

    m_nWidth = m_pPng->GetWidth();
    m_nHeight = m_pPng->GetHeight();

    return TRUE;
}
// 在OnPain事件中调用此接口进行贴图并透明化窗口
void CMyGraphics::DrawPng(HWND hWnd, BYTE bAlpha/* = 128*/)
{
    CDC* pDestDC = CWnd::FromHandle(hWnd)->GetDC();

    BLENDFUNCTION _Blend;
    _Blend.BlendOp = 0;
    _Blend.BlendFlags = 0;
    _Blend.AlphaFormat = 1;
    _Blend.SourceConstantAlpha = bAlpha;

    CRect rcClient;
    GetWindowRect(hWnd, &rcClient);

    auto ptTL = CPoint(rcClient.left, rcClient.top);
    SIZE sz = { m_nWidth, m_nHeight };

    if (!m_fSetStyle)
    {
        DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
        if ((dwExStyle & WS_EX_LAYERED) != WS_EX_LAYERED)
        {
            SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle | WS_EX_LAYERED);
        }
        m_fSetStyle = true;
    }

    UpdateLayeredWindow(hWnd, pDestDC->GetSafeHdc(), &ptTL, &sz, m_pMemDC->GetSafeHdc(), &CPoint(0, 0), 0, &_Blend, ULW_ALPHA);
}

编译好的EXE也已上传(请先安装VC++2015运行库): windows平板悬浮球-桌面系统文档类资源-CSDN下载

补充源码下载:

https://download.csdn.net/download/hgreminem/86505578

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MFC悬浮窗口是指使用Microsoft Foundation Class(MFC)库开发的一种用户界面设计模式,窗口以悬浮的形式显示在屏幕上,并且可以随意移动和调整大小。 悬浮窗口提供了一种便捷的界面操作方式,用户可以通过鼠标将悬浮窗口拖动到屏幕的任意位置,也可以通过拖动边框来调整悬浮窗口的大小。这种设计模式可以用于全局快速访问特定功能或信息,例如快速启动应用程序、提供实时系统状态信息等。 在MFC中实现悬浮窗口,需要使用相关的窗口类和函数进行开发。首先,应创建一个继承自CWnd类的自定义窗口类,并重写相应的消息处理函数。在自定义窗口类中,可以绘制悬浮的外观,响应鼠标事件,实现拖拽和调整大小的功能。 接下来,在主窗口的创建过程中,创建并显示悬浮窗口对象。可以使用Create函数创建悬浮窗口,并设置窗口样式、位置和大小等属性。然后,使用ShowWindow函数将悬浮窗口显示在屏幕上。 为了实现悬浮窗口的移动和调整大小功能,可以在自定义窗口类的消息处理函数中,捕获鼠标事件并相应地更新窗口的位置和大小。通过使用相关的窗口函数,例如SetWindowPos函数,可以实现窗口的移动和大小调整。 通过以上的方式,我们可以实现在MFC中创建和操作悬浮窗口。这种设计模式可以提高用户界面的灵活性和易用性,给用户带来更好的使用体验。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值