Cocos win32制作异形窗口

最近利用Cocos2dx制作了异形窗口,记录下制作流程【Cocos版本3.17.2】:

1.去掉标题栏

  在cocos/platform/desktop/CCGLViewImpl-desktop.cpp文件中的initWithRect函数里添加

    glfwWindowHint(GLFW_DECORATED, GL_FALSE);

 效果图:

2.窗口背景透明 

网上搜索【异形窗口】的实现都是剔除像素的做法,也就是使用下面这个函数

    SetLayeredWindowAttributes

这个函数需要美术同学出图配合,否则边缘处会遗留锯齿状的残留颜色【最终未采用这种方式】

后续的资料查找过程中,发现下面的方法也能实现窗口背景透明

#pragma comment(lib, "dwmapi")
    DWM_BLURBEHIND bb = { 0 };
    bb.dwFlags = DWM_BB_ENABLE;
    bb.fEnable = true;
    bb.hRgnBlur = NULL;
    DwmEnableBlurBehindWindow(hwnd, &bb);

后经测试发现当前参数在Win10设备会出现一层黑色遮罩,需调整参数,调整后的代码如下【该参数在Win7平台也能正常表现】

    ::RECT rect2;
    GetWindowRect(hwnd, &rect2);

    HRGN hRgn = CreateRectRgn(rect2.left, rect2.bottom, rect2.right, rect2.bottom - rect2.top);
    DWM_BLURBEHIND bb = { 0 };
    bb.dwFlags = DWM_BB_ENABLE| DWM_BB_BLURREGION;
    bb.fEnable = true;
    bb.hRgnBlur = hRgn;
    DwmEnableBlurBehindWindow(hwnd, &bb);

调整之后编译运行,背景依然全黑,那是因为Cocos使用的OpenGL默认渲染一个黑色的画布。

3.清空OpenGL的画布

AppDelegate::applicationDidFinishLaunching函数中调用

    Director::getInstance()->setClearColor(Color4F(0, 0, 0, 0));

效果图: 

 4.实现窗口的移动

封装了一个监测鼠标事件的接口,代码如下:


#ifndef __MoveWindowNode__
#define __MoveWindowNode__

#include "cocos2d.h"
#include "ui/CocosGUI.h"

class MoveWindowNode : public cocos2d::Node
{
public:
    MoveWindowNode();
    ~MoveWindowNode();

    CREATE_FUNC(MoveWindowNode)
    virtual bool init();
protected:
    void onMouseDown(cocos2d::Event* event);
    void onMouseUp(cocos2d::Event* event);
    void onMouseMove(cocos2d::Event* event);
private:
    cocos2d::EventListenerMouse* m_mouseListener;
    bool m_isMouseDowned;
};

#endif // __MoveWindowNode__

#include "MoveWindowNode.h"


MoveWindowNode::MoveWindowNode()
 :m_mouseListener(nullptr)
 ,m_isMouseDowned(false)
{

}

MoveWindowNode::~MoveWindowNode()
{
    if (m_mouseListener)
    {
        cocos2d::Director::getInstance()->getEventDispatcher()->removeEventListener(m_mouseListener);
    }
}

bool MoveWindowNode::init()
{
    if ( !Node::init() )
    {
        return false;
    }

    m_mouseListener = cocos2d::EventListenerMouse::create();
    m_mouseListener->onMouseDown = CC_CALLBACK_1(MoveWindowNode::onMouseDown, this);
    m_mouseListener->onMouseUp = CC_CALLBACK_1(MoveWindowNode::onMouseUp, this);
    m_mouseListener->onMouseMove = CC_CALLBACK_1(MoveWindowNode::onMouseMove, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(m_mouseListener, this);
    return true;
}

static POINT pt, pe;
static RECT rt, re;
void MoveWindowNode::onMouseDown(cocos2d::Event* event)
{
    auto hwnd = cocos2d::Director::getInstance()->getOpenGLView()->getWin32Window();
    SetCapture(hwnd);   // 设置鼠标捕获(防止光标跑出窗口失去鼠标热点)       
    GetCursorPos(&pt);  // 获取鼠标光标指针当前位置      
    GetWindowRect(hwnd, &rt);   // 获取窗口位置与大小      
    re.right = rt.right - rt.left;  // 保存窗口宽度
    re.bottom = rt.bottom - rt.top; // 保存窗口高度

    m_isMouseDowned = true;
}

void MoveWindowNode::onMouseUp(cocos2d::Event* event)
{
    m_isMouseDowned = false;
    ReleaseCapture();   // 释放鼠标捕获,恢复正常状态    
}

void MoveWindowNode::onMouseMove(cocos2d::Event* event)
{
    if (m_isMouseDowned)
    {
        GetCursorPos(&pe);

        auto hwnd = cocos2d::Director::getInstance()->getOpenGLView()->getWin32Window();
        re.left = rt.left + (pe.x - pt.x);  // 窗口新的水平位置 
        re.top = rt.top + (pe.y - pt.y); // 窗口新的垂直位置 
        MoveWindow(hwnd, re.left, re.top, re.right, re.bottom, true); // 移动窗口     

        pt = pe;
        GetWindowRect(hwnd, &rt);   // 获取窗口位置与大小      
        re.right = rt.right - rt.left;  // 保存窗口宽度
        re.bottom = rt.bottom - rt.top; // 保存窗口高度
    }
}

使用方法:

   auto node = MoveWindowNode::create();
   this->addChild(node);

这样一个异形窗口便制作完成了.....

效果图:

 参考资料:

cocos Win32 程序实现背景透明效果

窗口玻璃特效,半透明窗口,使用DWM实现Aero Glass效果

猜你喜欢

转载自blog.csdn.net/auccy/article/details/120156494
今日推荐