cocos2D-x在windows下实现隐藏默认标题栏,并实现拖动

COCOS2D是移动端开发游戏的免费引擎,功能非常强大,由于在移动端没有标题栏不存在问题,在windows下会有默认的标题栏,如果做得游戏为了在windows下也有统一的游戏风格,修改标题栏就必不可少。

1.隐藏标题栏

CCEGLView类中有一个获取窗口句柄的接口CCEGLView::sharedOpenGLView()->getgetHWnd();所以实现去掉标题栏非常简单, LONG l_WinStyle = GetWindowLong(hWnd, GWL_STYLE); SetWindowLong(hWnd, GWL_STYLE, l_WinStyle & ~WS_CAPTION);,运行游戏会发现去掉的标题区域是黑色的没有渲染,这是由于客户区大小没有改变,可以通过如下函数修改:

void HideDefaultTitle(HWND hWnd, int nWidth, int nHeight)
{
LONG l_WinStyle = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, l_WinStyle & ~WS_CAPTION);
RECT  rectProgram, rectClient;
GetWindowRect(hWnd, &rectProgram);   //获得程序窗口位于屏幕坐标
GetClientRect(hWnd, &rectClient);      //获得客户区坐标
//非客户区宽,高
int nClientWidth = rectProgram.right - rectProgram.left - (rectClient.right - rectClient.left);
int nClientHeiht = rectProgram.bottom - rectProgram.top - (rectClient.bottom - rectClient.top);
nClientWidth += nWidth;
nClientHeiht += nHeight;
rectProgram.right = nClientWidth;
rectProgram.bottom = nClientHeiht;
int showToScreenx = GetSystemMetrics(SM_CXSCREEN) / 2 - nClientWidth / 2;    //居中处理
int showToScreeny = GetSystemMetrics(SM_CYSCREEN) / 2 - nClientHeiht / 2;
MoveWindow(hWnd, showToScreenx, showToScreeny, nWidth, nHeight, false);
}


有了这个函数我们就可以:

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);


    // create the application instance
    AppDelegate app;
//getFrameSize()获得实际屏幕的大小
CCDirector *pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
pEGLView->setViewName("Fishing");
pEGLView->setFrameSize(800, 600); 
#ifdef _WIN32
HideDefaultTitle(pEGLView->getHWnd(), 800, 600);
#endif
    return CCApplication::sharedApplication()->run();
};

再次运行游戏发现游戏非常完美的去掉了标题栏。

2.增加移动

windows窗体在不是最大化的情况下可以根据鼠标移动,前提是由标题栏,由于标题栏被我们干掉了,所以该功能就失效了。windows实现这些功能是通过WM_NCHITTEST,这个消息来实现的,如果想要模拟,就有必要截获windows窗口回调函数,我们查看CCEGLView类:

class CC_DLL CCEGLView : public CCEGLViewProtocol
{
public:
    CCEGLView();
    virtual ~CCEGLView();


    /* override functions */
    virtual bool isOpenGLReady();
    virtual void end();
    virtual void swapBuffers();
    virtual void setFrameSize(float width, float height);
virtual void setEditorFrameSize(float width, float height,HWND hWnd); 
    virtual void setIMEKeyboardState(bool bOpen);


    void setMenuResource(LPCWSTR menu);
    void setWndProc(CUSTOM_WND_PROC proc);


protected:
    virtual bool Create();
public:
    bool initGL();
    void destroyGL();


    virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);


void setHWnd(HWND hWnd);
    // win32 platform function
    HWND getHWnd();
    virtual void resize(int width, int height);

    /* 
     * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop.
     */
    void setFrameZoomFactor(float fZoomFactor);
float getFrameZoomFactor();
    virtual void centerWindow();


    typedef void (*LPFN_ACCELEROMETER_KEYHOOK)( UINT message,WPARAM wParam, LPARAM lParam );
    void setAccelerometerKeyHook( LPFN_ACCELEROMETER_KEYHOOK lpfnAccelerometerKeyHook );


    virtual void setViewPortInPoints(float x , float y , float w , float h);
    virtual void setScissorInPoints(float x , float y , float w , float h);
    
    // static function
    /**
    @brief    get the shared main open gl window
    */
    static CCEGLView* sharedOpenGLView();


protected:
static CCEGLView* s_pEglView;
    bool m_bCaptured;
    HWND m_hWnd;
    HDC  m_hDC;
    HGLRC m_hRC;
    LPFN_ACCELEROMETER_KEYHOOK m_lpfnAccelerometerKeyHook;
    bool m_bSupportTouch;


    LPCWSTR m_menu;
    CUSTOM_WND_PROC m_wndproc;


    float m_fFrameZoomFactor;
};


NS_CC_END


#endif    // end of __CC_EGLVIEW_WIN32_H__


里面有2个接口:   void setWndProc(CUSTOM_WND_PROC proc); , virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);


这个就是回调函数,说明有2种实现方式,第一种继承一个CCEGLView 类,在内部重载virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);

第二种:直接使用  void setWndProc(CUSTOM_WND_PROC proc); 来设置一个新的回调函数。


下面使用第二种方法来实现:



LRESULT winProc(UINT message, WPARAM wParam, LPARAM lParam, BOOL* pProcessed)
{
const int captionHeight = 10;
const int frameWidth = 10;
static POINTS cursor;
switch (message)
{
case WM_NCHITTEST:
{
RECT  rectClient;
GetClientRect(CCEGLView::sharedOpenGLView()->getHWnd(), &rectClient);      //获得客户区坐标
int w = rectClient.right - rectClient.left;
int h = rectClient.bottom - rectClient.top;
POINT point;
GetCursorPos(&point);
ScreenToClient(CCEGLView::sharedOpenGLView()->getHWnd(), &point);
rectClient = { frameWidth, captionHeight, w - frameWidth - frameWidth, h - captionHeight - frameWidth };
RECT rectTopLeft = { 0, 0, frameWidth, captionHeight };
RECT rectTop = { frameWidth, 0, w - frameWidth, captionHeight };
RECT rectTopRight = { w - frameWidth, 0, w, captionHeight };
RECT rectLeft = { 0, captionHeight, frameWidth, h - captionHeight - frameWidth };
RECT rectRight = { w - frameWidth, captionHeight, w, h - captionHeight - frameWidth };
RECT rectBottm = { frameWidth, h - frameWidth, w - frameWidth, h };
RECT rectBottmLeft = { 0, h - frameWidth, frameWidth, h};
RECT rectBottmRight = { w - frameWidth, h - frameWidth, w, h };


if (PtInRect(&rectClient, point))
{
OutputDebugString(L"CLicent\n");
return HTCLIENT;
}
else if (PtInRect(&rectTopLeft, point))
{
OutputDebugString(L"TopLeft\n");
return HTTOPLEFT;
}
else if (PtInRect(&rectTop, point))
{
OutputDebugString(L"Caption\n");
return HTCAPTION;
}
else if (PtInRect(&rectTopRight, point))
{
OutputDebugString(L"TopRight\n");
return HTTOPRIGHT;
}
else if (PtInRect(&rectLeft, point))
{
OutputDebugString(L"Left\n");
return HTLEFT;
}
else if (PtInRect(&rectRight, point))
{
OutputDebugString(L"Right\n");
return HTRIGHT;
}
else if (PtInRect(&rectBottm, point))
{
OutputDebugString(L"Bottom\n");
return HTBOTTOM;
}
else if (PtInRect(&rectBottmLeft, point))
{
OutputDebugString(L"BottomLeft\n");
return HTBOTTOMLEFT;
}
else if (PtInRect(&rectBottmRight, point))
{
OutputDebugString(L"BottomRight\n");
return  HTBOTTOMRIGHT;
}
}
break;
case WM_LBUTTONDOWN:   
{
OutputDebugString(L"WM_LBUTTONDOWN\n");
cursor = MAKEPOINTS(lParam);
}
break;
case WM_LBUTTONUP:
{
OutputDebugString(L"WM_LBUTTONUP\n");
POINTS pts = MAKEPOINTS(lParam);
int xDaly = pts.x - cursor.x;
int yDaly = pts.y - cursor.y;
RECT  rectClient;
GetWindowRect(CCEGLView::sharedOpenGLView()->getHWnd(), &rectClient);      //获得客户区坐标
int w = rectClient.right - rectClient.left;
int h = rectClient.bottom - rectClient.top;
MoveWindow(CCEGLView::sharedOpenGLView()->getHWnd(), rectClient.left + xDaly, rectClient.top + yDaly, w, h, true);
}
break;
default:
break;
}
return DefWindowProc(CCEGLView::sharedOpenGLView()->getHWnd(), message, wParam, lParam);
}


回调函数写好了,然后我们设置回调:

#ifdef _WIN32
HideDefaultTitle(pEGLView->getHWnd(), 800, 600);
pEGLView->setWndProc(winProc);
#endif


运行程序,已经能移动了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值