MFC 绘制标题栏 按钮

//修该窗体外形ModifyStyle(WS_BORDER|WS_THICKFRAME|WS_DLGFRAME, WS_CAPTION,  SWP_DRAWFRAME);   在WM_Create
ModifyStyle(WS_BORDER|WS_THICKFRAME|WS_DLGFRAME, WS_CAPTION,  SWP_DRAWFRAME);  //全去掉自己要做HITtest
#include<afxwin.h>
#include"resource.h"
#ifdef _UNICODE
#undef _UNICODE
#endif // _UNICODE
#define WM_USER_CLOSE WM_USER + 100
//================================================myAfx================================//
void MessageBoxPrintf(char* pszCaputre,char* Format,...)  
{  
    va_list vaList;//equal to Format + sizeof(FOrmat)  
    char szBuff[100];  
    memset(szBuff,0,sizeof(char)*100);  
    va_start(vaList,Format);  
    //vsPrintf 三个参数 buff,format,参数数组的指针,va_list类型的。这个函数  
    // 多用于实现多个参数的自定义函数   
    _vsnprintf(szBuff,100,Format,vaList);   
    va_end(vaList);  
    MessageBoxA(NULL,szBuff,pszCaputre,MB_OK);  
}      
void MyOutPutString(char* Format,...)
{  
    va_list vaList;//equal to Format + sizeof(FOrmat)  
    char szBuff[100];  
    memset(szBuff,0,sizeof(char)*100);  
    va_start(vaList,Format);  
    //vsPrintf 三个参数 buff,format,参数数组的指针,va_list类型的。这个函数  
    // 多用于实现多个参数的自定义函数   
    _vsnprintf(szBuff,100,Format,vaList);   
    va_end(vaList);  
   OutputDebugStringA(szBuff);
} 


class MyMainFrame:public CFrameWnd
{
public:
    MyMainFrame()
    {
        Create(NULL,"test",~WS_BORDER&WS_OVERLAPPEDWINDOW &~WS_MAXIMIZE&~WS_SYSMENU  ,rectDefault,NULL,NULL);

        m_hTitleBitmap = LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1));
        bitClose.LoadBitmap(IDB_BITMAP2);
        if(NULL == m_hTitleBitmap)
        {
           DWORD dwErrorCode =  GetLastError();
           MessageBoxPrintf("Error code ","%d",dwErrorCode);

        }
        GetObject(m_hTitleBitmap,sizeof(BITMAP),&m_TitileBitmap);
         bitClose.GetObject(sizeof(BITMAP),&bit);
        //=======================data init===========================//
        SetRect(&m_ClientRect,0,0,0,0);
        SetRect(&m_WindowRect,0,0,0,0);
        
        cxTitile = 0;
        cyTitile = 0;
    }
    ~MyMainFrame()
    {
        if(m_hTitleBitmap != NULL)
        {
            DeleteObject(m_hTitleBitmap);
        }
        m_hTitileComDc.DeleteDC();
    }

public: //message
   afx_msg LRESULT  MyOnPaint(WPARAM wParam,LPARAM lParam);
   afx_msg  void OnPaint();
   afx_msg  void OnOpen();
   afx_msg  void OnExit();
   afx_msg  void OnLButtonDown(UINT, CPoint);
   afx_msg  void OnNcPaint();
   afx_msg  void OnSize(UINT nType, int cx, int cy);
   afx_msg  int OnCreate(LPCREATESTRUCT lpCreateStruct);
   afx_msg  void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
   afx_msg  void OnNcMouseMove(UINT  nHitTest, CPoint posPoint);
   afx_msg  LRESULT MyOnClose(WPARAM wParam,LPARAM lParam);
   DECLARE_MESSAGE_MAP()
protected:
    HBITMAP m_hTitleBitmap;
    RECT m_ClientRect;
    RECT m_WindowRect;
    int cxTitile;
    int cyTitile;
    CDC m_hTitileComDc;
    BITMAP m_TitileBitmap;
    CBitmap btmap;
    int iBord;
    CBitmap bitClose;
    CDC m_hCloseComDc;
        BITMAP bit;
   

};
void MyMainFrame::OnNcMouseMove(UINT nHitTest, CPoint posPoint)
{
    ScreenToClient(&posPoint);//clinet pos
    MyOutPutString("%d x %d y\n",posPoint.x,posPoint.y);
    CRect re;
    re.left = m_WindowRect.right - bit.bmWidth;
    re.right = m_WindowRect.right;
    re.top = - cyTitile;
    re.bottom = 0;
    POINT pos;
    pos.x = posPoint.x;
    pos.y = posPoint.y;
    if(TRUE==re.PtInRect(pos))
    {
        SendMessage(WM_USER_CLOSE,0,0);
        OutputDebugStringA("move\n");
    }
    else
        SendMessage(WM_NCPAINT,0,0);
}
void MyMainFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
      SendMessage(WM_NCPAINT,0,0);
}
int MyMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    
    btmap.Attach(m_hTitleBitmap);
    CClientDC dc(this); 
    m_hCloseComDc.CreateCompatibleDC(&dc);
   
    m_hCloseComDc.SelectObject(bitClose);
    m_hTitileComDc.CreateCompatibleDC(&dc);
    m_hTitileComDc.SelectObject(m_hTitleBitmap);
    ReleaseDC(&dc);
    return 0;
}
void MyMainFrame::OnSize(UINT nType, int cx, int cy)
{
    //BOOL GetTitleBarInfo(          HWND hwnd,
    // PTITLEBARINFO pti

    m_ClientRect.right = cx;
    m_ClientRect.bottom = cy;
    GetWindowRect(&m_WindowRect);
    cxTitile = m_WindowRect.right - m_WindowRect.left;
    m_WindowRect.right = m_WindowRect.right - m_WindowRect.left;
    m_WindowRect.bottom = m_WindowRect.bottom - m_WindowRect.top;
    m_WindowRect.left = 0;
    m_WindowRect.top = 0;
    iBord = GetSystemMetrics(SM_CYBORDER);
    cyTitile = GetSystemMetrics(SM_CYCAPTION) + iBord;

}
void MyMainFrame::OnNcPaint()
{
    CWindowDC dc(this);
    m_hTitileComDc.SelectObject(m_hTitleBitmap);
    m_hCloseComDc.SelectObject(bitClose);
    dc.StretchBlt(m_WindowRect.left,m_WindowRect.top,cxTitile,cyTitile,&m_hTitileComDc,
                  0,0,m_TitileBitmap.bmWidth,m_TitileBitmap.bmHeight,SRCCOPY); 
    dc.StretchBlt(m_WindowRect.right - bit.bmWidth , 0 ,bit.bmWidth,bit.bmHeight,
                  &m_hCloseComDc,0,0,bit.bmWidth,
                  bit.bmHeight,SRCCOPY);
    ReleaseDC(&dc);
}
static int i =0;
void MyMainFrame::OnPaint()
{
    CPaintDC dc(this);

    //dc.StretchBlt(0,0,m_TitileBitmap.bmWidth,m_TitileBitmap.bmHeight,&m_hTitileComDc,0,0,m_TitileBitmap.bmWidth,
     //            m_TitileBitmap.bmHeight,SRCCOPY);
    ReleaseDC(&dc);
    OutputDebugStringA("onPaint\n");
   SendMessage(WM_NCPAINT,0,0);
}
void MyMainFrame::OnLButtonDown(UINT uFlag, CPoint posPoint)
{

    CString cstrPos;
    cstrPos.Format("%d %d",posPoint.x,posPoint.y);
   // MessageBox((LPCSTR)(LPCTSTR)cstrPos,"tst",MB_OKCANCEL);
}
BEGIN_MESSAGE_MAP(MyMainFrame,CFrameWnd)
   //ON_WM_PAINT(WM_PAINT,MyOnPaint)
    ON_WM_PAINT()
    ON_COMMAND(ID_MENU_EXIT,OnExit)
    ON_WM_LBUTTONDOWN()
    ON_COMMAND(ID_MENU_OPEN,OnOpen)
    ON_WM_NCPAINT()
    ON_WM_SIZE()
    ON_WM_ACTIVATE()
    ON_WM_CREATE()
    ON_WM_NCMOUSEMOVE()
    ON_MESSAGE(WM_USER_CLOSE,MyOnClose)
    
END_MESSAGE_MAP()
void MyMainFrame::OnExit()
{
    this->OnClose();
}
void MyMainFrame::OnOpen()
{
    this->MessageBox("open","test",MB_OK);
}
LRESULT MyMainFrame::MyOnPaint(WPARAM wParam,LPARAM lParam)
{
    
    CPaintDC dc(this);
    dc.Rectangle(10,10,200,200);
    ReleaseDC(&dc);

   return FALSE;
}

LRESULT MyMainFrame::MyOnClose( WPARAM wParam,LPARAM lParam )
{
    CWindowDC dc(this);
    m_hTitileComDc.SelectObject(m_hTitleBitmap);
    m_hCloseComDc.SelectObject(bitClose);
    dc.StretchBlt(m_WindowRect.left,m_WindowRect.top,cxTitile,cyTitile,&m_hTitileComDc,
        0,0,m_TitileBitmap.bmWidth,m_TitileBitmap.bmHeight,SRCCOPY); 
    dc.StretchBlt(m_WindowRect.right - bit.bmWidth , 0 ,bit.bmWidth,bit.bmHeight,
        &m_hCloseComDc,0,0,bit.bmWidth,
        bit.bmHeight,NOTSRCCOPY);
    ReleaseDC(&dc);
    return TRUE;
}
class MyWinApp:public CWinApp
{
public:

    virtual BOOL InitInstance()
    {
      
       this->m_pMainWnd = new  MyMainFrame();
       m_pMainWnd->ShowWindow(this->m_nCmdShow);
       m_pMainWnd->UpdateWindow();
       return TRUE;
    }
public:
   
};
MyWinApp theApp;

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
MFC中,可以通过自定义绘制标题的方式来实现自绘关闭按钮。 首先,需要在窗口类的OnNcCreate函数中添加以下代码,以使窗口支持非客户区的绘制: ```cpp LRESULT CMyWnd::OnNcCreate(LPCREATESTRUCT lpCreateStruct) { LRESULT lRes = CWnd::OnNcCreate(lpCreateStruct); DWORD style = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); ::SetWindowLongPtr(m_hWnd, GWL_STYLE, style | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN); DWORD exStyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE); ::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exStyle | WS_EX_CLIENTEDGE); return lRes; } ``` 接下来,在窗口类的OnNcPaint函数中自绘标题。首先调用父类的OnNcPaint函数绘制默认的标题,然后自己绘制关闭按钮: ```cpp void CMyWnd::OnNcPaint() { CWnd::OnNcPaint(); CWindowDC dc(this); CRect rect; GetClientRect(rect); CRect titleRect; GetWindowRect(titleRect); titleRect.bottom = titleRect.top + rect.top; ScreenToClient(titleRect); // 自绘关闭按钮 CRect closeRect; int btnSize = GetSystemMetrics(SM_CYSMICON); closeRect.left = titleRect.right - btnSize - 5; closeRect.top = titleRect.top + (rect.top - btnSize) / 2; closeRect.right = closeRect.left + btnSize; closeRect.bottom = closeRect.top + btnSize; dc.DrawFrameControl(closeRect, DFC_CAPTION, DFCS_CAPTIONCLOSE | (GetActiveWindow() == this ? DFCS_PUSHED : 0)); } ``` 以上代码中,计算了自绘关闭按钮的位置和大小,并调用DrawFrameControl函数来绘制关闭按钮,DFC_CAPTION表示绘制标题按钮,DFCS_CAPTIONCLOSE表示绘制关闭按钮,DFCS_PUSHED表示按钮处于按下状态。 最后,在窗口类的OnNcLButtonDown函数中处理关闭按钮的点击事件: ```cpp void CMyWnd::OnNcLButtonDown(UINT nHitTest, CPoint point) { if (nHitTest == HTCLOSE || nHitTest == HTCAPTION) { CRect rect; GetClientRect(rect); CRect titleRect; GetWindowRect(titleRect); titleRect.bottom = titleRect.top + rect.top; ScreenToClient(titleRect); int btnSize = GetSystemMetrics(SM_CYSMICON); CRect closeRect(titleRect.right - btnSize - 5, titleRect.top + (rect.top - btnSize) / 2, titleRect.right - 5, titleRect.top + (rect.top + btnSize) / 2); if (closeRect.PtInRect(point)) { PostMessage(WM_SYSCOMMAND, SC_CLOSE); return; } } CWnd::OnNcLButtonDown(nHitTest, point); } ``` 以上代码中,根据鼠标点击位置判断是否点击了关闭按钮,如果是,则发送关闭消息给窗口。 通过以上步骤,就可以在MFC中实现自绘关闭按钮

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值