MFC对话框标题栏颜色自绘,标题栏由过渡色组成,自绘关闭按钮

一个简单的标题栏自绘
一:步骤
(1)新建一个基于对话框的MFC程序,打开对话框属性设置界面,去掉对话框的标题栏和边界BORDER(vc和vs的设置相似,这里使用的是vs2015,界面与vc稍有不同),
(2)在客户曲自绘一个标题栏和关闭按钮,需要使用到WM_PAINT消息的处理函数,使用Class WIZARD添加OnPaint()消息相应函数
(3)为了使自绘的标题栏能够用鼠标拖动窗口,并且使自绘的关闭按钮能够关闭界面,需要使用到OnNcHitTest(…)消息处理函数和OnLButtonDown(…)消息处理函数

二:函数解释:
(1)LRESULT CTest2Dlg::OnNcHitTest(CPoint point)
功能:每当鼠标移动时,框架就为包含光标(或者是用SetCapture成员函数捕获了鼠标输入的CWnd对象)的CWnd对象调用这个成员函数

参数:point,当前鼠标的坐标,相对于屏幕坐标系

返回值:表示点击位置的类型,有以下类型
HTBORDER:在不具有可变大小边框的窗口的边框上
HTBOTTOM:在窗口的水平边框的底部
HTBOTTOMLEFT:在窗口边框的左下角
HTBOTTOMRIGHT:在窗口边框的右下角
HTCAPTION:在标题条中
HTCLIENT:在客户区中
HTERROR:HTERROR 在屏幕背景或窗口之间的分隔线上(与HTNOWHERE相同,除了 Windows的DefWndProc函数产生一个系统响声以指明错误)
HTGROWBOX:在尺寸框中
HTHSCROLL:在水平滚动条上
HTLEFT:在窗口的左边框上
HTMAXBUTTON:在最大化按钮上
HTMENU:在菜单区域
HTMINBUTTON:在最小化按钮上
HTNOWHERE:在屏幕背景或窗口之间的分割线上
HTREDUCE:在最小化按钮上
HTRIGHT:在窗口的右边框上
HTSIZE:在尺寸框中(与HTGROWBOX相同)
HTSYSMENU:在控制菜单或子窗口的关闭按钮上
HTTOP:在窗口水平边框的上方
HTTOPLEFT:在窗口水平边框的左上角
HTTOPRIGHT:在窗口边框的右上角
HTTRANSPARENT:在一个被其他窗口覆盖的窗口中
HTVSCROLL:在垂直滚动条中
HTZOOM:在最大化按钮上

(2)void CTest2Dlg::OnLButtonDown(UINT nFlags, CPoint point)
功能:当鼠标点击自绘的关闭按钮时,关闭窗口
参数:nFlags,指示各种虚拟键是否按下。此参数可以是下列值的任意组合:
如果按下CTRL键,MK_CONTROL 设置。
如果鼠标左键滚动,MK_LBUTTON 设置。
如果元鼠标按钮处于按下,MK_MBUTTON 设置。
如果鼠标右键滚动,MK_RBUTTON 设置。
如果SHIFT键下降,MK_SHIFT 设置。
point
指定光标的x坐标和y坐标。这些坐标始终是相对于窗口左上角的。

(3) BOOL PtInRect( POINT point ) const throw( );
功能:检测某个点是否在某个矩形中
参数:point
包含POINT 结构或 CPoint 对象。
返回值
非零,则点在 CRect之间;否则为0。

(4)CDC::DrawText
enter description here

三:代码
Test2Dlg.h头文件,添加一个存放关闭按钮矩形位置的CRect对象m_rtBtnClose;然后使用类相对添加相关消息相应函数


// Test2Dlg.h : header file
//

#pragma once


// CTest2Dlg dialog
class CTest2Dlg : public CDialogEx
{
public:
    CRect m_rtBtnClose;

// Construction
public:
    CTest2Dlg(CWnd* pParent = NULL);    // standard constructor

// Dialog Data
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_TEST2_DIALOG };
#endif

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support


// Implementation
protected:
    HICON m_hIcon;

    // Generated message map functions
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnNcPaint();
    afx_msg LRESULT OnNcHitTest(CPoint point);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};

Test2Dlg.cpp实现


// Test2Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "Test2.h"
#include "Test2Dlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();

// Dialog Data
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_ABOUTBOX };
#endif

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CTest2Dlg dialog



CTest2Dlg::CTest2Dlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_TEST2_DIALOG, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTest2Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CTest2Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_NCPAINT()
    ON_WM_NCHITTEST()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()


// CTest2Dlg message handlers

BOOL CTest2Dlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // Add "About..." menu item to system menu.
    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here

    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTest2Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTest2Dlg::OnPaint()
{
    CPaintDC dc(this);
    CRect rect;
    CRect tmprect;
    GetClientRect(&rect);
    rect.bottom = 30;
    tmprect = rect;
    int nCount = 165 - 115 + 186 - 158 + 190 - 115;
    int nIncrecs = (rect.right - rect.left) / nCount;
    rect.left = rect.right = 0;

    for(int i=115;i<=165;i++)
        for(int j=158;j<=186;j++)
            for(int k=115;k<=190;k++)
            {
                rect.left = rect.right;
                rect.right += nIncrecs;
                dc.FillSolidRect(rect, RGB(i, j, k));
            }
//  dc.FillSolidRect(rect, RGB(0, 0, 255));
    dc.SetBkMode(TRANSPARENT);
    CString str = TEXT("欢迎使用本软件");
    dc.SetTextColor(RGB(255, 0, 0));
    dc.DrawText(str, tmprect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//水平居中和垂直居中必须和DT_SINGLELINE搭配,否则起不到效果


    //绘制关闭按钮
    CRect rtBtnClo;
    GetClientRect(&rtBtnClo);
    rtBtnClo.left = rtBtnClo.right - 30;
    rtBtnClo.right = rtBtnClo.right - 10;
    rtBtnClo.top = 5;
    rtBtnClo.bottom = 25;
    m_rtBtnClose = rtBtnClo;

    dc.Rectangle(rtBtnClo);
    dc.MoveTo(rtBtnClo.left, rtBtnClo.top);
    dc.LineTo(rtBtnClo.right, rtBtnClo.bottom);
    dc.MoveTo(rtBtnClo.right, rtBtnClo.top);
    dc.LineTo(rtBtnClo.left, rtBtnClo.bottom);

}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTest2Dlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}



void CTest2Dlg::OnNcPaint()
{

    // TODO: Add your message handler code here
    // Do not call CDialogEx::OnNcPaint() for painting messages
}


LRESULT CTest2Dlg::OnNcHitTest(CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    UINT nHitTest=CDialogEx::OnNcHitTest(point);
    CRect rect;
    GetClientRect(&rect);
    rect.bottom = 30;
    //函数参数point是相对于屏幕坐标的,需要将其转换为
    //客户区坐标才能使用PtInRect(),否则会因为坐标的不同使判断失误
    ScreenToClient(&point);
    if (rect.PtInRect(point))
    {
        if (HTCLIENT == nHitTest)
            nHitTest = HTCAPTION;
            //如果鼠标点中的是关闭按钮的位置,需要将上一步的设置还原,
            //否则鼠标点击自绘的标题栏的时候,系统无法发送WM_LBUTTONDOWN消息,也就无法处理关闭按钮
        if (m_rtBtnClose.PtInRect(point))
        {
            nHitTest = HTCLIENT;
        }
    }
    return nHitTest;
}


void CTest2Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
//  ScreenToClient(&point);
    if (m_rtBtnClose.PtInRect(point))
    {
        //AfxMessageBox(TEXT("测试关闭按钮"));
        CDialog::OnCancel();
    }
    CDialogEx::OnLButtonDown(nFlags, point);

}


void CTest2Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    /*ScreenToClient(&point);
    if (m_rtBtnClose.PtInRect(point))
    {
        AfxMessageBox(TEXT("测试关闭按钮"));
    }*/
    CDialogEx::OnLButtonUp(nFlags, point);
}
要修改MFC程序窗口的标题栏颜色,可以通过以下步骤实现: 1. 在你的 MFC 应用程序中打开资源编辑器,找到并双击你的对话框。 2. 在对话框的属性页中,找到 “Style” 属性,设置为 “Popup”。 3. 找到 “Caption” 属性,设置为你想要的标题文本。 4. 在对话框的属性页中,找到 “Background Color” 属性,选择你想要的颜色。 5. 在你的对话框的类定义文件中,添加以下代码: ```cpp BOOL CYourDialog::OnInitDialog() { CDialog::OnInitDialog(); // 设置标题栏颜色 CWnd* pWnd = GetDlgItem(IDOK); // 获取窗口句柄 if (pWnd != NULL) { CRect rc; pWnd->GetWindowRect(&rc); // 获取窗口大小和位置 ScreenToClient(&rc); // 转换为当前窗口的客户区坐标 rc.bottom = rc.top + GetSystemMetrics(SM_CYCAPTION); // 计算标题栏的高度 CBrush brush(RGB(255, 0, 0)); // 创建画刷,设置为红 CBrush* pOldBrush = (CBrush*)SelectObject(::GetDC(pWnd->GetSafeHwnd()), brush); // 选择画刷 PatBlt(::GetDC(pWnd->GetSafeHwnd()), rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY); // 绘制矩形 SelectObject(::GetDC(pWnd->GetSafeHwnd()), pOldBrush); // 恢复原来的画刷 } return TRUE; } ``` 其中,IDOK 是你的对话框中任意一个控件的 ID,用于获取窗口句柄。你也可以使用其他控件的 ID。 6. 编译并运行你的 MFC 应用程序,查看效果。 注意:这种方法只适用于普通窗口,对于 MDI 窗口和对话框,需要使用其他方法实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值