本方法实现了MFC对话框无边框可缩放功能,用户只需新建一个对话框类继承下面的基类即可实现无边框可缩放功能。
(也可以设置不缩放通过变量设置)
XGDialog.h
#pragma once
// CXGDialog 对话框
class CXGDialog : public CDialogEx
{
DECLARE_DYNAMIC(CXGDialog)
public:
CXGDialog(UINT nIDTemplate,CWnd* pParent = NULL); // 标准构造函数
virtual ~CXGDialog();
对话框数据
//enum { IDD = IDD_XGDIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint(); //重绘背景
afx_msg BOOL OnEraseBkgnd(CDC* pDC); //擦除背景
afx_msg LRESULT OnNcHitTest(CPoint point); //鼠标放到边框显示缩放
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //鼠标左键按下拖动窗口
afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp); //计算客户区大小
//解决系统按钮在窗口激活或者拖动的时候是不是闪现在界面上,如果是在NCPAIN中进行标题头重绘用下面方法
afx_msg BOOL OnNcActivate(BOOL bActive);
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
private:
BOOL m_bExtrude;
};
XGDialog.cpp
// XGDialog.cpp : 实现文件
//
#include "stdafx.h"
#include "XGSkinUI.h"
#include "XGDialog.h"
#include "afxdialogex.h"
// CXGDialog 对话框
IMPLEMENT_DYNAMIC(CXGDialog, CDialogEx)
CXGDialog::CXGDialog(UINT nIDTemplate,CWnd* pParent /*=NULL*/)
: CDialogEx(nIDTemplate, pParent)
{
m_bExtrude = TRUE;
}
CXGDialog::~CXGDialog()
{
}
void CXGDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CXGDialog, CDialogEx)
ON_WM_ERASEBKGND()
ON_WM_NCACTIVATE()
ON_WM_NCCALCSIZE()
ON_WM_NCHITTEST()
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
END_MESSAGE_MAP()
// CXGDialog 消息处理程序
BOOL CXGDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
//设置边框WS_THICKFRAME 可拉伸模式
ModifyStyle(WS_BORDER, WS_THICKFRAME, SWP_FRAMECHANGED);
//关闭菜单功能。(只有关闭菜单功能才能缩放)
ModifyStyle(WS_SYSMENU, 0);
//父控件刷新时,子控件不刷新背景
LONG style = GetWindowLong(m_hWnd,GWL_STYLE);
style = style | WS_CLIPSIBLINGS |WS_CLIPCHILDREN ;
SetWindowLong(m_hWnd,GWL_STYLE,style);
//可调整窗口大小
::SetWindowPos(m_hWnd,NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED); //一定要加这句设置才会立即生效
return TRUE; // return TRUE unless you set the focus to a control
}
BOOL CXGDialog::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return TRUE;
return CDialogEx::OnEraseBkgnd(pDC);
}
BOOL CXGDialog::OnNcActivate(BOOL bActive)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
SendMessage(WM_NCPAINT, 0, 0);
return TRUE;
return CDialogEx::OnNcActivate(bActive);
}
LRESULT CXGDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
if(message == 0x00AE || // WM_NCUAHDRAWCAPTION
message == 0x00AF) // WM_NCUAHDRAWFRAME
{
return WM_NCPAINT;
}
return CDialogEx::WindowProc(message, wParam, lParam);
}
void CXGDialog::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//取得标题栏的位置
//SM_CXFRAME 窗口边框的边缘宽度
//SM_CYFRAME 窗口边框的边缘高度
//SM_CXSIZE 窗口标题栏宽度
//SM_CYSIZE 窗口标题栏高度
//SM_CYSIZEFRAME 可调整大小的窗口边框高度
//int a = GetSystemMetrics(SM_CYBORDER);
//int b = GetSystemMetrics(SM_CYSIZEFRAME);
//int c = GetSystemMetrics(SM_CYFRAME);
//int d = GetSystemMetrics(SM_CYSIZE);
//lpncsp->rgrc->top -= (GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZEFRAME))+GetSystemMetrics(SM_CYBORDER);
//去掉标题栏和边框
return;
//CDialogEx::OnNcCalcSize(bCalcValidRects, lpncsp);
}
//边框宽度
CONST INT BORDERWIDTH = 3;
LRESULT CXGDialog::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
// 注意:不是全屏的情况下,才可以拖拽,需要用户自己处理
if( m_bExtrude )
{
CRect rcWindow;
GetWindowRect(&rcWindow);
if ((point.x <= rcWindow.left+BORDERWIDTH) && (point.y>BORDERWIDTH) && (point.y<rcWindow.bottom-BORDERWIDTH*2) )
return HTLEFT;
else if ((point.x >= rcWindow.right-BORDERWIDTH) && (point.y>BORDERWIDTH) && (point.y<rcWindow.bottom-BORDERWIDTH*2) )
return HTRIGHT;
else if ((point.y <= rcWindow.top+BORDERWIDTH) && (point.x>BORDERWIDTH) && (point.x<rcWindow.right-BORDERWIDTH*2))
return HTTOP;
else if ((point.y >= rcWindow.bottom-BORDERWIDTH) && (point.x>BORDERWIDTH) && (point.x<rcWindow.right-BORDERWIDTH*2))
return HTBOTTOM;
else if ((point.x <= rcWindow.left+BORDERWIDTH*2) && (point.y <= rcWindow.top+BORDERWIDTH*2))
return HTTOPLEFT;
else if ((point.x >= rcWindow.right-BORDERWIDTH*2) && (point.y <= rcWindow.top+BORDERWIDTH*2))
return HTTOPRIGHT;
else if ((point.x <= rcWindow.left+BORDERWIDTH*2) && (point.y >= rcWindow.bottom-BORDERWIDTH*2))
return HTBOTTOMLEFT;
else if ((point.x >= rcWindow.right-BORDERWIDTH*2) && (point.y >= rcWindow.bottom-BORDERWIDTH*2))
return HTBOTTOMRIGHT;
else
return CWnd::OnNcHitTest(point);
}
else
{
return CDialogEx::OnNcHitTest(point);
}
}
void CXGDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
CDialogEx::OnLButtonDown(nFlags, point);
}
void CXGDialog::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialogEx::OnPaint()
//背景填充为白色,不建议这么做
CRect rect,fillrect;
CBrush brush;
brush.CreateSolidBrush(RGB(255,0,0));
this->GetClientRect(&rect);
dc.FillRect(&rect,&brush); //用FillRect成员函数利用笔刷填充指定区域
brush.DeleteObject();
}
效果图: