CSWDialog头文件声明(CSWDialog.h)
#pragma once
#include <afxwin.h>
class CSWDialog :
public CDialog
{
DECLARE_DYNAMIC(CSWDialog)
public:
CSWDialog();
CSWDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
CSWDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
virtual ~CSWDialog();
protected:
void CommonConstruct(); // 初始化
public:
enum BackgroundLocation
{
BACKGR_TOPLEFT,
BACKGR_TOPCENTER,
BACKGR_TOPRIGHT,
BACKGR_MIDDLELEFT,
BACKGR_MIDDLECENTER,
BACKGR_MIDDLERIGHT,
BACKGR_BOTTOMLEFT,
BACKGR_BOTTOMCENTER,
BACKGR_BOTTOMRIGHT,
BACKGR_COUNT,
};
enum BackgroundShow
{
BACKGR_TILE, // 平铺
BACKGR_STRETCH, // 拉伸
BACKGR_AUTOFIT, // 自适应
};
enum SystemMenu
{
SYSMNU_MIN,
SYSMNU_MAX,
SYSMNU_CLOSE,
SYSMNU_COUNT,
};
protected:
RECT m_rcImageWindow; // 背景图片相对于源图片文件中裁剪下来的区域
RECT m_rcImageClient; // 9宫格中心客户区相对于源图片文件中的裁剪区域
Gdiplus::Bitmap* m_pBkgrBitmap;
Gdiplus::Bitmap* m_pSysMinBitmap;
Gdiplus::Bitmap* m_pSysMaxBitmap;
Gdiplus::Bitmap* m_pSysCloseBitmap;
RECT m_rcMin;
RECT m_rcMax;
RECT m_rcClose;
CSize m_sizeBkgrBitmap;
CBrush m_brBkgr;
BOOL m_bSysMnu[SYSMNU_COUNT];
BOOL m_bHasTitleBar;
int m_nSysMnuHover;
BOOL m_bTracking;
std::string m_sWindowText;
protected:
afx_msg void OnPaint();
afx_msg void OnNcPaint();
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg BOOL OnNcActivate(BOOL bActive);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp);
afx_msg LRESULT OnNcHitTest(CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnMouseLeave();
afx_msg void OnNcLButtonDblClk(UINT nHitTest, CPoint point);
afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point);
afx_msg void OnNcMouseHover(UINT nFlags, CPoint point);
afx_msg void OnNcMouseLeave();
afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
DECLARE_MESSAGE_MAP()
protected:
virtual BOOL OnInitDialog();
virtual BOOL PreTranslateMessage(MSG* pMsg);
public:
// 设置窗口背景图片
void SetBackgroundColor(COLORREF clrBkgr, BOOL bRepaint = TRUE);
/*
lpszImageName: 背景图片句柄
rcWindow: 窗口区域
rcClient:客户区区域
*/
void SetBackgroundImage(HBITMAP hBitmap, RECT* rcWindow = NULL, RECT* rcClient = NULL, BOOL bRepaint = TRUE);
/*
lpszImageName: 背景图片资源ID
rcWindow: 窗口区域
rcClient:客户区区域
*/
void SetBackgroundImage(UINT uiBmpResId, RECT* rcWindow = NULL, RECT* rcClient = NULL, BOOL bRepaint = TRUE);
/*
lpszImageName: 背景图片名称
rcWindow: 窗口区域
rcClient:客户区区域
*/
void SetBackgroundImage(LPCTSTR lpszImageName, RECT* rcWindow = NULL, RECT* rcClient = NULL, BOOL bRepaint = TRUE);
// 设置最小化、最小化、恢复、关闭按钮图标
void SetMinImage(LPCTSTR lpszImageName)
{
m_pSysMinBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(lpszImageName);
}
void SetMaxImage(LPCTSTR lpszImageName)
{
m_pSysMaxBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(lpszImageName);
}
void SetCloseImage(LPCTSTR lpszImageName)
{
m_pSysCloseBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(lpszImageName);
}
void SetBackgroundMaskImage(LPCTSTR lpszImageName);
private:
void DoPaint();
void DoNcPaint();
void DrawSysMenu(Gdiplus::Graphics& g);
void DrawWindowText(Gdiplus::Graphics& g);
};
CSWDialog源文件定义(CSWDialog.cpp):
#include "stdafx.h"
#include "CSWDialog.h"
IMPLEMENT_DYNAMIC(CSWDialog, CDialog)
CSWDialog::CSWDialog()
{
CommonConstruct();
}
CSWDialog::CSWDialog(UINT nIDTemplate, CWnd* pParentWnd/* = NULL*/)
: CDialog(nIDTemplate, pParentWnd)
{
CommonConstruct();
}
CSWDialog::CSWDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd/* = NULL*/)
: CDialog(lpszTemplateName, pParentWnd)
{
CommonConstruct();
}
CSWDialog::~CSWDialog()
{
}
#define RIGHT_EDGE 5
#define TOP_EDGE 0
#define SYSMENU_WIDTH 40
#define SYSMENU_HEIGHT 32
void CSWDialog::CommonConstruct()
{
m_pBkgrBitmap = NULL;
m_pSysMinBitmap = NULL;
m_pSysMaxBitmap = NULL;
m_pSysCloseBitmap = NULL;
m_sizeBkgrBitmap = CSize(0, 0);
m_rcImageWindow = CRect(0, 0, 0, 0);
m_rcImageClient = CRect(0, 0, 0, 0);
memset(&m_bSysMnu, 0, SYSMNU_COUNT);
m_bHasTitleBar = FALSE;
m_nSysMnuHover = -1;
m_brBkgr.CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
}
BEGIN_MESSAGE_MAP(CSWDialog, CDialog)
ON_WM_PAINT()
ON_WM_NCPAINT()
ON_WM_ACTIVATE()
ON_WM_ERASEBKGND()
ON_WM_NCACTIVATE()
ON_WM_SIZE()
ON_WM_NCCALCSIZE()
ON_WM_NCHITTEST()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_KILLFOCUS()
ON_WM_MOUSEHOVER()
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
ON_WM_NCLBUTTONDBLCLK()
ON_WM_NCLBUTTONDOWN()
ON_WM_NCLBUTTONUP()
ON_WM_NCMOUSEHOVER()
ON_WM_NCMOUSELEAVE()
ON_WM_NCMOUSEMOVE()
ON_WM_SYSCOMMAND()
ON_WM_SETCURSOR()
ON_WM_LBUTTONDBLCLK()
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()
BOOL CSWDialog::OnInitDialog()
{
DWORD dwStyle = (DWORD)GetWindowLong(m_hWnd, GWL_STYLE);;//获取样式
if (dwStyle&WS_MAXIMIZEBOX)
m_bSysMnu[SYSMNU_MAX] = TRUE;
if (dwStyle&WS_MINIMIZEBOX)
m_bSysMnu[SYSMNU_MIN] = TRUE;
if (dwStyle&WS_SYSMENU)
m_bSysMnu[SYSMNU_CLOSE] = TRUE;
//if (dwStyle&WS_CAPTION)
// m_bHasTitleBar = TRUE;
CString strText;
int nLen = ::GetWindowTextLength(m_hWnd);
::GetWindowText(m_hWnd, strText.GetBufferSetLength(nLen), nLen + 1);
strText.ReleaseBuffer(); m_sWindowText = strText;
// 去掉标题栏
ModifyStyle(WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | DS_MODALFRAME, 0);
ModifyStyleEx(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE, 0);
return CDialog::OnInitDialog();
}
void CSWDialog::OnPaint()
{
if (!IsIconic())
DoPaint();
CDialog::OnPaint();
}
void CSWDialog::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther, bMinimized);
// TODO: 在此处添加消息处理程序代码
//DoNcPaint();
}
BOOL CALLBACK EnumChildWindowsProc(HWND hWnd, LPARAM lParam)
{
//UINT nType = *(UINT*)lParam;
if (::IsWindow(hWnd))
{
CWnd* pWnd = CWnd::FromHandle(hWnd);
char szClassName[_MAX_PATH] = { 0 };
::GetClassName(hWnd, szClassName, _MAX_PATH);
std::string sClassName = pWnd->GetRuntimeClass()->m_lpszClassName;
if (sClassName == _T("CSWButton"))
{
((CSWButton*)pWnd)->NoticeBkgrRefresh();
}
else if (sClassName == _T("CSWSwitchButton"))
{
((CSWSwitchButton*)pWnd)->NoticeBkgrRefresh();
}
else if (sClassName == _T("CSWStatic"))
{
((CSWStatic*)pWnd)->NoticeBkgrRefresh();
}
else if (sClassName == _T("CSWEdit"))
{
((CSWEdit*)pWnd)->NoticeBkgrRefresh();
}
}
return TRUE;
}
void CSWDialog::SetBackgroundColor(COLORREF clrBkgr, BOOL bRepaint)
{
if (m_brBkgr.GetSafeHandle() != NULL)
{
m_brBkgr.DeleteObject();
}
if (clrBkgr != (COLORREF)-1)
{
m_brBkgr.CreateSolidBrush(clrBkgr);
}
if (bRepaint && GetSafeHwnd() != NULL)
{
Invalidate();
UpdateWindow();
EnumChildWindows(m_hWnd, EnumChildWindowsProc, NULL);
}
}
void CSWDialog::SetBackgroundImage(HBITMAP hBitmap, RECT* rcWindow, RECT* rcClient, BOOL bRepaint)
{
m_pBkgrBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(hBitmap);
m_rcImageWindow = *rcWindow;
m_rcImageClient = *rcClient;
if (m_pBkgrBitmap)
{
if (rcWindow == NULL)
m_rcImageWindow = CRect(0, 0, m_pBkgrBitmap->GetWidth(), m_pBkgrBitmap->GetHeight());
if (rcClient == NULL)
m_rcImageClient = m_rcImageWindow;
m_sizeBkgrBitmap = CSize(m_pBkgrBitmap->GetWidth(), m_pBkgrBitmap->GetHeight());
if (bRepaint && GetSafeHwnd() != NULL)
{
Invalidate();
UpdateWindow();
EnumChildWindows(m_hWnd, EnumChildWindowsProc, NULL);
}
}
}
void CSWDialog::SetBackgroundImage(UINT uiBmpResId, RECT* rcWindow, RECT* rcClient, BOOL bRepaint)
{
m_pBkgrBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(uiBmpResId, RT_BITMAP);
m_rcImageWindow = *rcWindow;
m_rcImageClient = *rcClient;
if (m_pBkgrBitmap)
{
if (rcWindow == NULL)
m_rcImageWindow = CRect(0, 0, m_pBkgrBitmap->GetWidth(), m_pBkgrBitmap->GetHeight());
if (rcClient == NULL)
m_rcImageClient = m_rcImageWindow;
m_sizeBkgrBitmap = CSize(m_pBkgrBitmap->GetWidth(), m_pBkgrBitmap->GetHeight());
if (bRepaint && GetSafeHwnd() != NULL)
{
Invalidate();
UpdateWindow();
EnumChildWindows(m_hWnd, EnumChildWindowsProc, NULL);
}
}
}
void CSWDialog::SetBackgroundImage(LPCTSTR lpszImageName, RECT* rcWindow, RECT* rcClient, BOOL bRepaint)
{
m_pBkgrBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(lpszImageName);
if (m_pBkgrBitmap)
{
m_rcImageWindow = (rcWindow == NULL) ? CRect(0, 0, m_pBkgrBitmap->GetWidth(), m_pBkgrBitmap->GetHeight()) : *rcWindow;
if (rcClient == NULL)
m_rcImageClient = m_rcImageWindow;
else
m_rcImageClient = *rcClient;
m_sizeBkgrBitmap = CSize(m_pBkgrBitmap->GetWidth(), m_pBkgrBitmap->GetHeight());
if (bRepaint && GetSafeHwnd() != NULL)
{
Invalidate();
UpdateWindow();
EnumChildWindows(m_hWnd, EnumChildWindowsProc, NULL);
}
}
}
BOOL CSWDialog::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return FALSE;
}
void CSWDialog::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnGetMinMaxInfo(lpMMI);
}
BOOL CSWDialog::OnNcActivate(BOOL bActive)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//DoNcPaint();
return TRUE;
//return CDialog::OnNcActivate(bActive);
}
void CSWDialog::OnNcPaint()
{
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialog::OnNcPaint()
//DoNcPaint();
}
void CSWDialog::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
if (m_pSysCloseBitmap && m_pSysMaxBitmap && m_pSysMinBitmap)
{
CRect rcClient; GetClientRect(rcClient);
m_rcClose.left = rcClient.right - m_pSysCloseBitmap->GetWidth() / 3 - RIGHT_EDGE;
m_rcClose.right = m_rcClose.left + m_pSysCloseBitmap->GetWidth() / 3;
m_rcClose.top = TOP_EDGE;
m_rcClose.bottom = m_rcClose.top + m_pSysCloseBitmap->GetHeight();
m_rcMax.left = m_rcClose.left - m_pSysMaxBitmap->GetWidth() / 3;
m_rcMax.right = m_rcMax.left + m_pSysMaxBitmap->GetWidth() / 3;
m_rcMax.top = TOP_EDGE;
m_rcMax.bottom = m_rcMax.top + m_pSysMaxBitmap->GetHeight() / 2;
m_rcMin.left = m_rcMax.left - m_pSysMinBitmap->GetWidth() / 3;
m_rcMin.right = m_rcMin.left + m_pSysMinBitmap->GetWidth() / 3;
m_rcMin.top = TOP_EDGE;
m_rcMin.bottom = m_rcMin.top + m_pSysMinBitmap->GetHeight();
}
else
{
CRect rcClient; GetClientRect(rcClient);
m_rcClose.left = rcClient.right - SYSMENU_WIDTH - RIGHT_EDGE;
m_rcClose.right = m_rcClose.left + SYSMENU_WIDTH;
m_rcClose.top = TOP_EDGE;
m_rcClose.bottom = m_rcClose.top + SYSMENU_HEIGHT;
m_rcMax.left = m_rcClose.left - SYSMENU_WIDTH;
m_rcMax.right = m_rcMax.left + SYSMENU_WIDTH;
m_rcMax.top = TOP_EDGE;
m_rcMax.bottom = m_rcMax.top + SYSMENU_HEIGHT;
m_rcMin.left = m_rcMax.left - SYSMENU_WIDTH;
m_rcMin.right = m_rcMin.left + SYSMENU_WIDTH;
m_rcMin.top = TOP_EDGE;
m_rcMin.bottom = m_rcMin.top + SYSMENU_HEIGHT;
}
if (nType == SIZE_MAXIMIZED || nType == SIZE_RESTORED)
{
DoNcPaint();
InvalidateRect(NULL, TRUE);
//::RedrawWindow(m_hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);// 通知窗口和所有子窗口重绘
EnumChildWindows(m_hWnd, EnumChildWindowsProc, (LPARAM)&nType);
}
}
void CSWDialog::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (m_bHasTitleBar && bCalcValidRects && !::IsRectEmpty(&m_rcImageClient) && !::IsRectEmpty(&m_rcImageWindow))
{
int cx = ::GetSystemMetrics(SM_CXFRAME);
int cy = ::GetSystemMetrics(SM_CYFRAME);
lpncsp->rgrc[0].top += m_rcImageClient.top - m_rcImageWindow.top + cy;
}
else
{
CDialog::OnNcCalcSize(bCalcValidRects, lpncsp);
}
}
#define RESIZE_REGION_SIZE 5
LRESULT CSWDialog::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
RECT rcWindow;
::GetWindowRect(m_hWnd, &rcWindow);
// 最好将四个角的判断放在前面
if (point.x <= rcWindow.left + RESIZE_REGION_SIZE && point.y <= rcWindow.top + RESIZE_REGION_SIZE)
return HTTOPLEFT;
else if (point.x >= rcWindow.right - RESIZE_REGION_SIZE && point.y <= rcWindow.top + RESIZE_REGION_SIZE)
return HTTOPRIGHT;
else if (point.x <= rcWindow.left + RESIZE_REGION_SIZE && point.y >= rcWindow.bottom - RESIZE_REGION_SIZE)
return HTBOTTOMLEFT;
else if (point.x >= rcWindow.right - RESIZE_REGION_SIZE && point.y >= rcWindow.bottom - RESIZE_REGION_SIZE)
return HTBOTTOMRIGHT;
else if (point.x <= rcWindow.left + RESIZE_REGION_SIZE)
return HTLEFT;
else if (point.x >= rcWindow.right - RESIZE_REGION_SIZE)
return HTRIGHT;
else if (point.y <= rcWindow.top + RESIZE_REGION_SIZE)
return HTTOP;
else if (point.y >= rcWindow.bottom - RESIZE_REGION_SIZE)
return HTBOTTOM;
//return HTCAPTION;
return CDialog::OnNcHitTest(point);
}
void CSWDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (!m_bHasTitleBar && m_nSysMnuHover == -1)
{
CRect rcClient;
GetClientRect(rcClient);
CRect rcDrag = CRect(0, 0, rcClient.Width(), m_rcImageClient.top - m_rcImageWindow.top);
if (rcDrag.IsRectEmpty())
rcDrag = rcClient;
ClientToScreen(rcDrag);
CPoint point; GetCursorPos(&point);
if (PtInRect(rcDrag, point))
::PostMessage(m_hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0L);
}
CDialog::OnLButtonDown(nFlags, point);
}
void CSWDialog::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (m_nSysMnuHover!=-1)
{
if (PtInRect(&m_rcMin, point))
::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
else if (PtInRect(&m_rcMax, point))
{
if (::IsZoomed(m_hWnd))
::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
else
::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
}
else if (PtInRect(&m_rcClose, point))
::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
}
CDialog::OnLButtonUp(nFlags, point);
}
void CSWDialog::OnKillFocus(CWnd* pNewWnd)
{
CDialog::OnKillFocus(pNewWnd);
// TODO: 在此处添加消息处理程序代码
}
void CSWDialog::OnMouseHover(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnMouseHover(nFlags, point);
}
void CSWDialog::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
}
int nOldSysMnuHover = m_nSysMnuHover;
if (PtInRect(&m_rcMin, point))
m_nSysMnuHover = SYSMNU_MIN;
else if (PtInRect(&m_rcMax, point))
m_nSysMnuHover = SYSMNU_MAX;
else if (PtInRect(&m_rcClose, point))
m_nSysMnuHover = SYSMNU_CLOSE;
else
m_nSysMnuHover = -1;
if (m_nSysMnuHover != nOldSysMnuHover)
{
InvalidateRect(&m_rcMin, FALSE);
InvalidateRect(&m_rcMax, FALSE);
InvalidateRect(&m_rcClose, FALSE);
}
CDialog::OnMouseMove(nFlags, point);
}
void CSWDialog::OnMouseLeave()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_bTracking = FALSE;
if (m_nSysMnuHover != -1)
{
InvalidateRect(NULL, FALSE);
m_nSysMnuHover = -1;
}
CDialog::OnMouseLeave();
}
void CSWDialog::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnNcLButtonDblClk(nHitTest, point);
}
void CSWDialog::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nHitTest)
{
case HTTOP:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y));
break;
case HTBOTTOM:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, MAKELPARAM(point.x, point.y));
break;
case HTLEFT:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, MAKELPARAM(point.x, point.y));
break;
case HTRIGHT:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, MAKELPARAM(point.x, point.y));
break;
case HTTOPLEFT:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, MAKELPARAM(point.x, point.y));
break;
case HTTOPRIGHT:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, MAKELPARAM(point.x, point.y));
break;
case HTBOTTOMLEFT:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, MAKELPARAM(point.x, point.y));
break;
case HTBOTTOMRIGHT:
SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, MAKELPARAM(point.x, point.y));
break;
default:
CDialog::OnNcLButtonDown(nHitTest, point);
}
}
void CSWDialog::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnNcLButtonUp(nHitTest, point);
}
void CSWDialog::OnNcMouseHover(UINT nFlags, CPoint point)
{
// 该功能要求使用 Windows 2000 或更高版本。
// 符号 _WIN32_WINNT 和 WINVER 必须 >= 0x0500。
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnNcMouseHover(nFlags, point);
}
void CSWDialog::OnNcMouseLeave()
{
// 该功能要求使用 Windows 2000 或更高版本。
// 符号 _WIN32_WINNT 和 WINVER 必须 >= 0x0500。
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnNcMouseLeave();
}
void CSWDialog::OnNcMouseMove(UINT nHitTest, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnNcMouseMove(nHitTest, point);
}
void CSWDialog::OnSysCommand(UINT nID, LPARAM lParam)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nID != SC_CLOSE)
DoNcPaint();
CDialog::OnSysCommand(nID, lParam);
}
BOOL CSWDialog::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (pMsg->message == WM_UNINITMENUPOPUP)
DoNcPaint();
if (pMsg->message == 0x00AE || //WM_NCUAHDRAWCAPTION
pMsg->message == 0x00AF) //WM_NCUAHDRAWFRAME)
{
DoNcPaint();
return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
void CSWDialog::DoPaint()
{
TRACE("%s::DoPaint(%d)\n", this->GetRuntimeClass()->m_lpszClassName, GetTickCount());
CPaintDC dc(this);
if (m_brBkgr.GetSafeHandle() == NULL && m_pBkgrBitmap == NULL)
return ;
CRect rcClient;
GetClientRect(rcClient);
if (m_pBkgrBitmap == NULL)
{
if (m_brBkgr.GetSafeHandle() != NULL)
dc.FillRect(rcClient, &m_brBkgr);
return;
}
ASSERT(m_sizeBkgrBitmap != CSize(0, 0));
sw::CMemDC dcMem(dc, this);
Gdiplus::Graphics g(dcMem);
// 左上
{
if (!m_bHasTitleBar)
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.right = m_rcImageClient.left;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
}
// 左中
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = m_rcImageClient.top;
rcClipImage.right = m_rcImageClient.left;
rcClipImage.bottom = m_rcImageClient.bottom;
CRect rcShowImage = rcClipImage;
if (m_bHasTitleBar)
rcShowImage.top = 0;
else
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.bottom = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 左下
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = m_rcImageClient.bottom;
rcClipImage.right = m_rcImageClient.left;
rcClipImage.bottom = m_rcImageWindow.bottom;
CRect rcShowImage = rcClipImage;
rcShowImage.top = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
rcShowImage.bottom = rcClient.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 右上
{
if (!m_bHasTitleBar)
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = 0;// m_rcImageClient.top - m_rcImageWindow.top;
rcClipImage.left = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.left = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.right = rcClient.right;
rcShowImage.bottom = m_rcImageClient.top;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
}
// 右中
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = m_rcImageClient.top;
rcClipImage.left = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.bottom;
CRect rcShowImage = rcClipImage;
if (m_bHasTitleBar)
rcShowImage.top = 0;
else
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.left = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.right = rcClient.right;
rcShowImage.bottom = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 右下
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.left = m_rcImageClient.right;
rcClipImage.top = m_rcImageClient.bottom;
rcClipImage.bottom = m_rcImageWindow.bottom;
CRect rcShowImage = rcClipImage;
rcShowImage.left = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.right = rcClient.right;
rcShowImage.top = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
rcShowImage.bottom = rcClient.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 中上
{
if (!m_bHasTitleBar)
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = 0;// m_rcImageClient.top - m_rcImageWindow.top;
rcClipImage.left = m_rcImageClient.left;
rcClipImage.right = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.right = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.bottom = m_rcImageClient.top;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
}
// 中中
{
CRect rcClipImage = m_rcImageClient;
CRect rcShowImage = rcClipImage;
if (m_bHasTitleBar)
rcShowImage.top = 0;
else
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.right = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.bottom = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 中下
{
CRect rcClipImage = m_rcImageClient;
rcClipImage.top = m_rcImageClient.bottom;
rcClipImage.bottom = m_rcImageWindow.bottom;
CRect rcShowImage = rcClipImage;
rcShowImage.right = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.top = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
rcShowImage.bottom = rcClient.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
if (!m_bHasTitleBar)
{
/*
* 绘制标题栏图标
* 绘制标题栏文本
*/
DrawWindowText(g);
DrawSysMenu(g);
}
// 平铺
for (int x = rcClient.left; x < rcClient.Width(); x += m_sizeBkgrBitmap.cx)
{
for (int y = rcClient.top; y < rcClient.Height(); y += m_sizeBkgrBitmap.cy)
{
//pDC->DrawState(CPoint(x, y), m_sizeBkgrBitmap, m_hBkgrBitmap, DSS_NORMAL);
}
}
}
void CSWDialog::DoNcPaint()
{
if ((!m_bHasTitleBar) || (m_brBkgr.GetSafeHandle() == NULL && m_pBkgrBitmap == NULL))
{
//CDialog::OnNcPaint();
return;
}
if (::IsRectEmpty(&m_rcImageClient) || ::IsRectEmpty(&m_rcImageWindow))
{
//CDialog::OnNcPaint();
return;
}
CDC* pDC = GetWindowDC();
ASSERT_VALID(pDC);
CRect rcClient;
GetClientRect(rcClient);
// 获取位置
CRect rcWindow;
GetWindowRect(&rcWindow);
rcWindow.OffsetRect(-rcWindow.left, -rcWindow.top);
// 剪除掉客户区
int cx = ::GetSystemMetrics(SM_CXFRAME);
int cy = ::GetSystemMetrics(SM_CYFRAME);
int ret = pDC->ExcludeClipRect(cx, m_rcImageClient.top - m_rcImageWindow.top, rcWindow.right - cx, rcWindow.bottom - cy);
if (m_pBkgrBitmap == NULL)
{
if (m_brBkgr.GetSafeHandle() != NULL)
{
pDC->FillRect(rcWindow, &m_brBkgr);
}
return;
}
ASSERT(m_sizeBkgrBitmap != CSize(0, 0));
sw::CMemDC dc(*pDC, rcWindow);
Gdiplus::Graphics g(dc);
// 左上
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.right = m_rcImageClient.left;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 右上
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.left = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.left = rcWindow.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.right = rcWindow.right;
rcShowImage.bottom = m_rcImageClient.top;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 中上
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.left = m_rcImageClient.left;
rcClipImage.right = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.right = rcWindow.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.bottom = m_rcImageClient.top;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 左边框
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.right = rcClipImage.left + cx;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.bottom = rcWindow.bottom + 100;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 右边框
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.left = m_rcImageWindow.right - cx;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.left = rcWindow.right - cx;
rcShowImage.bottom = rcWindow.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 下边框
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = m_rcImageWindow.bottom - cy;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.right = rcWindow.right;
rcShowImage.bottom = rcWindow.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
//
/*
* 绘制标题栏图标
*/
//
/*
* 绘制标题栏文本
*/
DrawWindowText(g);
//
/*
* 绘制系统功能按钮
*/
DrawSysMenu(g);
// 平铺
for (int x = rcWindow.left; x < rcWindow.Width(); x += m_sizeBkgrBitmap.cx)
{
for (int y = rcWindow.top; y < rcWindow.Height(); y += m_sizeBkgrBitmap.cy)
{
//pDC->DrawState(CPoint(x, y), m_sizeBkgrBitmap, m_hBkgrBitmap, DSS_NORMAL);
}
}
}
void CSWDialog::DrawSysMenu(Gdiplus::Graphics& g)
{
CRect rcClient; GetClientRect(rcClient);
g.SetSmoothingMode(Gdiplus::/*SmoothingModeAntiAlias*/SmoothingModeHighQuality);
if (m_bSysMnu[SYSMNU_CLOSE])
{
if (m_pSysCloseBitmap)
{
CRect rcClip = CRect(0, 0, m_pSysCloseBitmap->GetWidth() / 3, m_pSysCloseBitmap->GetHeight());
if (m_nSysMnuHover == SYSMNU_CLOSE)
rcClip.OffsetRect(m_pSysCloseBitmap->GetWidth() / 3, 0);
CRect rcShow(m_rcClose);
g.DrawImage(m_pSysCloseBitmap, RectF(rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height()), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), UnitPixel, NULL, NULL, NULL);
}
else
{
CRect rcShow(m_rcClose);
//
if (m_nSysMnuHover == SYSMNU_CLOSE) {
BYTE byAlpha = 128;
Color colors[] =
{
Color(byAlpha, 255, 255, 255),
Color(byAlpha, 0, 255, 0),
};
float positions[] = { 0.0f, 1.0f };
LinearGradientBrush linGrBrush(RectF(0, 0, 80, 80), Color::White, Color::Green, LinearGradientModeVertical);
//linGrBrush.SetInterpolationColors(colors, positions, 2);
g.FillRectangle(&linGrBrush, rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height());
}
{
rcShow.DeflateRect(14, 10);
g.TranslateTransform(rcShow.left, rcShow.top);
Gdiplus::Pen pen(Color(240, 0, 0, 0), 3);
pen.SetStartCap(Gdiplus::LineCapRound);
pen.SetEndCap(Gdiplus::LineCapRound);
pen.SetLineJoin(Gdiplus::LineJoinRound);
Point points[] = { Point(0, 0), Point(rcShow.Width(), rcShow.Height()), Point(0, rcShow.Height()), Point(rcShow.Width(), 0) };
g.DrawLine(&pen, points[0], points[1]);
g.DrawLine(&pen, points[2], points[3]);
g.ResetTransform();
}
//
}
}
if (m_bSysMnu[SYSMNU_MAX])
{
if (m_pSysMaxBitmap)
{
CRect rcClip = CRect(0, 0, m_pSysMaxBitmap->GetWidth() / 3, m_pSysMaxBitmap->GetHeight() / 2);
if (IsZoomed())
rcClip.OffsetRect(0, m_pSysMaxBitmap->GetHeight() / 2);
if (m_nSysMnuHover == SYSMNU_MAX)
rcClip.OffsetRect(m_pSysMaxBitmap->GetWidth() / 3, 0);
CRect rcShow(m_rcMax);
g.DrawImage(m_pSysMaxBitmap, RectF(rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height()), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), UnitPixel, NULL, NULL, NULL);
}
else
{
CRect rcShow(m_rcMax);
//
if (m_nSysMnuHover == SYSMNU_MAX) {
BYTE byAlpha = 128;
Color colors[] =
{
Color(byAlpha, 255, 255, 255),
Color(byAlpha, 0, 255, 0),
};
float positions[] = { 0.0f, 1.0f };
LinearGradientBrush linGrBrush(RectF(0, 0, 80, 80), Color::White, Color::Green, LinearGradientModeVertical);
//linGrBrush.SetInterpolationColors(colors, positions, 2);
g.FillRectangle(&linGrBrush, rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height());
}
{
rcShow.DeflateRect(14, 10);
Gdiplus::Pen pen(Color(255, 0, 0, 0), 2);
if (IsZoomed())
{
rcShow.top += 4;
rcShow.right -= 4;
g.TranslateTransform(rcShow.left, rcShow.top);
g.DrawRectangle(&pen, 0, 0, rcShow.Width(), rcShow.Height());
Point points[] = { Point(0, 2), Point(rcShow.Width(), 2) };
g.DrawLine(&pen, points[0], points[1]);
rcShow.OffsetRect(4, -4);
{
g.ResetTransform();
g.TranslateTransform(rcShow.left, rcShow.top);
g.DrawRectangle(&pen, 0, 0, rcShow.Width(), 2);
//g.DrawLine(&pen, Point(0, 0), Point(rcShow.Width(), 0));
//g.DrawLine(&pen, Point(0, 1), Point(rcShow.Width(), 1));
g.DrawLine(&pen, Point(0, 0), Point(0, rcShow.Height() - 5));
g.DrawLine(&pen, Point(rcShow.Width(), 0), Point(rcShow.Width(), rcShow.Height()));
g.DrawLine(&pen, Point(5, rcShow.Height()), Point(rcShow.Width(), rcShow.Height()));
}
}
else
{
g.TranslateTransform(rcShow.left, rcShow.top);
g.DrawRectangle(&pen, 0, 0, rcShow.Width(), rcShow.Height());
Point points[] = { Point(0, 2), Point(rcShow.Width(), 2) };
g.DrawLine(&pen, points[0], points[1]);
}
g.ResetTransform();
}
//
}
}
if (m_bSysMnu[SYSMNU_MIN])
{
if (m_pSysMinBitmap)
{
CRect rcClip = CRect(0, 0, m_pSysMinBitmap->GetWidth() / 3, m_pSysMinBitmap->GetHeight());
if (m_nSysMnuHover == SYSMNU_MIN)
rcClip.OffsetRect(m_pSysMinBitmap->GetWidth() / 3, 0);
CRect rcShow(m_rcMin);
g.DrawImage(m_pSysMinBitmap, RectF(rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height()), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), UnitPixel, NULL, NULL, NULL);
}
else
{
CRect rcShow(m_rcMin);
//
if (m_nSysMnuHover == SYSMNU_MIN) {
BYTE byAlpha = 128;
Color colors[] =
{
Color(byAlpha, 255, 255, 255),
Color(byAlpha, 0, 255, 0),
};
float positions[] = { 0.0f, 1.0f };
LinearGradientBrush linGrBrush(RectF(0, 0, 80, 80), Color::White, Color::Green, LinearGradientModeVertical);
//linGrBrush.SetInterpolationColors(colors, positions, 2);
g.FillRectangle(&linGrBrush, rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height());
}
{
rcShow.DeflateRect(14, 10);
rcShow.OffsetRect(0, 10);
g.TranslateTransform(rcShow.left, rcShow.top);
Gdiplus::SolidBrush brush(Color(255, 0, 0, 0));
g.FillRectangle(&brush, 0, 0, rcShow.Width(), 3);
g.ResetTransform();
}
//
}
}
}
BOOL CSWDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nHitTest)
{
case HTTOP:
case HTBOTTOM:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS)));
return TRUE;
case HTLEFT:
case HTRIGHT:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
return TRUE;
case HTTOPLEFT:
case HTBOTTOMRIGHT:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE)));
return TRUE;
case HTTOPRIGHT:
case HTBOTTOMLEFT:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW)));
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
void CSWDialog::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (!m_bHasTitleBar)
{
CRect rcClient;
GetClientRect(rcClient);
CRect rcDrag = CRect(0, 0, rcClient.Width(), m_rcImageClient.top - m_rcImageWindow.top);
if (rcDrag.IsRectEmpty())
rcDrag = rcClient;
ClientToScreen(rcDrag);
CPoint point; GetCursorPos(&point);
if (PtInRect(rcDrag, point))
{
if (IsZoomed())
{
::PostMessage(m_hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L);
}
else
{
if (!m_bSysMnu[SYSMNU_MAX])
return ;
::PostMessage(m_hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0L);
}
}
}
CDialog::OnLButtonDblClk(nFlags, point);
}
void CSWDialog::DrawWindowText(Gdiplus::Graphics& g)
{
int xPos = 10;
int yPos = 10;
HICON hIcon = (HICON)::SendMessage(m_hWnd, WM_GETICON, FALSE, 0);
if (hIcon)
{
Gdiplus::Bitmap* pBitmap = Gdiplus::Bitmap::FromHICON(hIcon);
g.DrawImage(pBitmap, RectF(xPos, yPos, pBitmap->GetWidth(), pBitmap->GetHeight()/*GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)*/), 0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), UnitPixel, NULL, NULL, NULL);
xPos += pBitmap->GetWidth();
xPos += 5;
delete pBitmap;
pBitmap = NULL;
}
if (m_sWindowText.size() > 0)
{
Gdiplus::Font font(L"微软雅黑", 12, FontStyleBold);
StringFormat stringFormat;
stringFormat.SetFormatFlags(StringFormatFlagsNoWrap);
stringFormat.SetAlignment(StringAlignmentNear);
stringFormat.SetLineAlignment(StringAlignmentNear);
std::wstring wsTitle = sw::CSWStrConverter::GBKToUnicode(m_sWindowText.c_str());
SolidBrush brush((ARGB)Color::White);
PointF point;
point.X = (Gdiplus::REAL)xPos;
point.Y = (Gdiplus::REAL)yPos - 4;
g.SetTextRenderingHint(TextRenderingHintAntiAlias);
g.DrawString(wsTitle.c_str(), wsTitle.size(), &font, point, &stringFormat, &brush);
}
}
HBRUSH CSWDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: 在此更改 DC 的任何特性
if (nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_BTN)
{
return HBRUSH(GetStockObject(HOLLOW_BRUSH)); //CreateSolidBrush(m_crKey);
}
if (nCtlColor == CTLCOLOR_STATIC)
{
//pDC->SetBkMode(TRANSPARENT);
//pDC->SetTextColor(RGB(0, 0, 0));
return HBRUSH(GetStockObject(HOLLOW_BRUSH));
}
// TODO: 如果默认的不是所需画笔,则返回另一个画笔
return hbr;
}
HRGN BitmapToRegion(HBITMAP hBmp, COLORREF cTransparentColor/* = 0*/, COLORREF cTolerance/* = 0x101010*/)
{
HRGN hRgn = NULL;
if (hBmp)
{
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC)
{
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
BITMAPINFOHEADER RGB32BITSBITMAPINFO = {
sizeof(BITMAPINFOHEADER), // biSize
bm.bmWidth, // biWidth;
bm.bmHeight, // biHeight;
1, // biPlanes;
32, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
};
VOID * pbits32;
HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
if (hbm32)
{
HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
{
BITMAP bm32;
GetObject(hbm32, sizeof(bm32), &bm32);
while (bm32.bmWidthBytes % 4)
bm32.bmWidthBytes++;
HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
DWORD maxRects = 200;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
BYTE lr = GetRValue(cTransparentColor);
BYTE lg = GetGValue(cTransparentColor);
BYTE lb = GetBValue(cTransparentColor);
BYTE hr = min(0xff, lr + GetRValue(cTolerance));
BYTE hg = min(0xff, lg + GetGValue(cTolerance));
BYTE hb = min(0xff, lb + GetBValue(cTolerance));
BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
for (int y = 0; y < bm.bmHeight; y++)
{
for (int x = 0; x < bm.bmWidth; x++)
{
int x0 = x;
LONG *p = (LONG *)p32 + x;
while (x < bm.bmWidth)
{
BYTE b = GetRValue(*p);
if (b >= lr && b <= hr)
{
b = GetGValue(*p);
if (b >= lg && b <= hg)
{
b = GetBValue(*p);
if (b >= lb && b <= hb)
break;
}
}
p++;
x++;
}
if (x > x0)
{
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += 200;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y + 1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y + 1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y + 1;
pData->rdh.nCount++;
if (pData->rdh.nCount == 2000)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
p32 -= bm32.bmWidthBytes;
}
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
GlobalFree(hData);
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
}
DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
}
return hRgn;
}
void CSWDialog::SetBackgroundMaskImage(LPCTSTR lpszImageName)
{
#if 1
COLORREF crAlpha = RGB(255, 0, 0);
CImage img; img.Load(lpszImageName);
if (img.IsNull())
return;
struct PixelData
{
BYTE B;
BYTE G;
BYTE R;
BYTE A;
};
HRGN hRgn = NULL;
DWORD maxRects = 200;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
for (int y = 0; y < img.GetHeight(); y++)
{
for (int x = 0; x < img.GetWidth(); x++)
{
int x0 = x;
while (x < img.GetWidth())
{
PixelData* pPixel = (PixelData*)img.GetPixelAddress(x, y);
if (pPixel->R != GetRValue(crAlpha) || pPixel->G != GetGValue(crAlpha) || pPixel->B != GetBValue(crAlpha))
//if (pPixel->A == 0)
break;
x++;
}
if (x > x0)
{
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += 200;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pRc = (RECT *)&pData->Buffer;
SetRect(&pRc[pData->rdh.nCount], x0, y, x, y + 1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y + 1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y + 1;
pData->rdh.nCount++;
if (pData->rdh.nCount == 500)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
}
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
GlobalUnlock(hData);
GlobalFree(hData);
#else
COLORREF crAlpha = RGB(255, 0, 0);
Gdiplus::Bitmap* pBkgrMaskBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(lpszImageName);
struct PixelData
{
BYTE B;
BYTE G;
BYTE R;
BYTE A;
};
HRGN hRgn = NULL;
if (pBkgrMaskBitmap)
{
//if (Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
{
Gdiplus::BitmapData bitmapData;
Gdiplus::Rect rcBitmap(0, 0, pBkgrMaskBitmap->GetWidth(), pBkgrMaskBitmap->GetHeight());
Gdiplus::Status status = pBkgrMaskBitmap->LockBits(&rcBitmap, Gdiplus::ImageLockModeRead, pBkgrMaskBitmap->GetPixelFormat(), &bitmapData);
if (status == Gdiplus::Ok)
{
#define ALLOC_UNIT 200
DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
int nBitsPixel = GetPixelFormatSize(pBkgrMaskBitmap->GetPixelFormat()) >> 3;
int nLinesize = pBkgrMaskBitmap->GetWidth() * nBitsPixel;
int nOffset = bitmapData.Stride - bitmapData.Width * nBitsPixel;
PixelData* pPixel = (PixelData*)bitmapData.Scan0;
for (int y = 0; y < bitmapData.Height; y++)
{
for (int x = 0; x < bitmapData.Width; x++)
{
int x0 = x;
while (x < bitmapData.Width)
{
//if (pPixel->R==GetRValue(crAlpha) && pPixel->G == GetGValue(crAlpha) && pPixel->B == GetBValue(crAlpha))
if (pPixel->R != GetRValue(crAlpha) || pPixel->G != GetGValue(crAlpha) || pPixel->B != GetBValue(crAlpha))
//if (pPixel->A == 0)
break;
x++;
pPixel++;
if (!Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
pPixel -= 1;
}
if (x < bitmapData.Width)
{
pPixel++;
if (!Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
pPixel -= 1;
}
if (x > x0)
{
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pRc = (RECT *)&pData->Buffer;
SetRect(&pRc[pData->rdh.nCount], x0, y, x, y + 1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y + 1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y + 1;
pData->rdh.nCount++;
if (pData->rdh.nCount == 500)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
pPixel += bitmapData.Stride - (bitmapData.Width * nBitsPixel);
}
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
GlobalUnlock(hData);
GlobalFree(hData);
pBkgrMaskBitmap->UnlockBits(&bitmapData);
}
}
}
#endif
::SetWindowRgn(m_hWnd, hRgn, TRUE);
}