Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

570 lines
14 KiB
C++

#include "stdafx.h"
//#include "GlwGlobalVariable.h"
#include "GlwSkin.h"
#include "resource.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// extern HWND global_hwnd;
// extern bool global_bWndMoveStart;
// extern bool global_bNCLD;
namespace
{
void CreateFont(LPCTSTR name, int height, CFont &font)
{
if (font.GetSafeHandle())
font.DeleteObject();
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = height;
//lf.lfCharSet = GB2312_CHARSET;
_tcscpy(lf.lfFaceName, name);
font.CreateFontIndirect(&lf);
}
CSize GetBitMapSize(const HBITMAP& hBitmap)
{
CBitmap *p = CBitmap::FromHandle(hBitmap);
if (!p) return CSize(0, 0);
BITMAP mapinfo;
memset(&mapinfo, 0, sizeof(BITMAP));
if (!p->GetBitmap(&mapinfo)) return CSize(0, 0);
return CSize(mapinfo.bmWidth, mapinfo.bmHeight);
}
bool BitBlt( CDC &dcDest, const CPoint &ptDest, const HBITMAP& hBitmap, DWORD dwRop )
{
CDC memDC;
memDC.CreateCompatibleDC(&dcDest);
memDC.SelectObject(hBitmap);
CSize sz = GetBitMapSize(hBitmap);
BOOL bRel = ::BitBlt(dcDest.GetSafeHdc(), ptDest.x, ptDest.y, sz.cx, sz.cy,
memDC.GetSafeHdc(), 0, 0, dwRop);
memDC.DeleteDC();
return bRel ? true : false;
}
}
GlwSkin::GlwSkin() : m_hRgn(NULL), m_hBrush(NULL), m_reOldWnd(0, 0, 0, 0), m_bInit(false),
m_bActive(FALSE), m_nTopHeight(33), m_nLBorderW(3), m_nRBorderW(3), m_nBBorderW(3),
m_bSizable(false), m_bCaption(false), m_bCBtnClick(false), m_bCBtnMoveon(false),
m_bCornerTitle(false), m_szMin(150, 150), m_sTitle(_T("")),
m_dwOldLong(0), m_bNcLBDCaption(false), m_bNcLBDBorder(false),
m_bDragTrans(true), m_colorDlg(RGB(214, 214, 214))
{
CreateFont(_T("宋体"), 12, m_font);
SetLabel(false);// 此函数会设置 m_nTopHeight, 故在此调用
}
GlwSkin::~GlwSkin()
{
if (m_hRgn)
::DeleteObject(m_hRgn);
if (m_hBrush)
::DeleteObject(m_hBrush);
}
BOOL GlwSkin::Hook(CWnd *wnd)
{
if ( m_bInit )
m_bInit = FALSE;
m_bInit = TRUE;
if ( !wnd || !m_bInit ) return FALSE;
HookWindow( (HWND)NULL);
int r = HookWindow( wnd );
LONG_PTR style = ::GetWindowLongPtr( m_hWnd, GWL_STYLE );
m_bSizable = (style & WS_SIZEBOX) == 0 ? false : true;
m_bCaption = (style & WS_CAPTION) == 0 ? false : true;
if (!m_bSizable)
m_nBBorderW = 1;
style &= ~WS_MINIMIZEBOX;
style &= ~WS_MAXIMIZEBOX;
style &= ~WS_SYSMENU;
::SetWindowLongPtr( m_hWnd, GWL_STYLE, style );
if (!m_bSizable)
{
m_nLBorderW = m_nRBorderW = m_nBBorderW = 1;
}
return r;
}
LRESULT GlwSkin::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
{
if ( !IsWindow(m_hWnd) )
return 0;
if ( !m_bInit )
return Default();
switch ( msg )
{
case WM_SHOWWINDOW:
if ( wp )
SetWindowPos( m_hWnd, 0, 0, 0, 400, 400, SWP_NOSIZE|SWP_NOMOVE|SWP_FRAMECHANGED );
Default();
return 0;
break;
case WM_INITMENUPOPUP:
Default();
return 0;
case WM_SYSCOMMAND:
Default();
return 0;
case WM_SETTEXT:
return OnSetText( wp, lp );
case WM_NCPAINT:
OnNcPaint( (HRGN)wp );
return 0;
case WM_NCCALCSIZE:
OnNcCalcSize( (BOOL)wp, (NCCALCSIZE_PARAMS *)lp );
return 0;
case WM_SIZE:
OnSize( (UINT)wp, LOWORD(lp), HIWORD(lp) );
return Default();
case WM_NCACTIVATE:
return OnNcActivate( (BOOL)wp );
case WM_NCHITTEST:
return OnNcHitTest(CPoint(LOWORD(lp), HIWORD(lp)));
case WM_NCLBUTTONUP:
OnNcLButtonUp((UINT)wp, CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_NCLBUTTONDOWN:
OnNcLButtonDown((UINT)wp, CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_NCLBUTTONDBLCLK:
OnNcLButtonDblClk((UINT)wp, CPoint(LOWORD(lp), HIWORD(lp)));
Default();
case WM_NCRBUTTONUP:
Default();
return 0;
case WM_NCRBUTTONDOWN:
Default();
return 0;
case WM_NCMOUSEMOVE:
OnNcMouseMove( (UINT)wp,CPoint(LOWORD(lp), HIWORD(lp)));
return 0;
case WM_GETMINMAXINFO:
OnGetMinMaxInfo( (MINMAXINFO *)lp );
return 0;
case WM_WINDOWPOSCHANGING:
Default();
return 0;
case WM_SIZING:
Default();
return 0;
case WM_ACTIVATE:
OnActivate( (UINT)wp, CWnd::FromHandle((HWND)lp), 0 );
return 0;
case WM_COMMAND:
Default();
return 0;
case WM_CTLCOLORDLG:
return Default();
case WM_LBUTTONUP:
Default();
return 0;
default:
return Default();
}
}
void GlwSkin::OnNcPaint(HRGN rgn1)
{
if (!m_bInit) return;
if (!m_bCaption)
{
Default();
return;
}
CDC memDC, *pDC = CWnd::FromHandle(m_hWnd)->GetWindowDC();
CRect wr;
::GetWindowRect(m_hWnd, &wr);
OffsetRect(&wr, -wr.left, -wr.top);
// 生成一个 rgn 包括 title 和 border,不包含客户区
CRgn rgnBig, rgnSml, rgnRel;
rgnBig.CreateRectRgn(wr.left, wr.top, wr.right, wr.bottom);
rgnSml.CreateRectRgn(wr.left + m_nLBorderW,
wr.top + m_nTopHeight,
wr.right - m_nRBorderW,
wr.bottom - m_nBBorderW);
rgnRel.CreateRectRgn(0, 0, 0, 0);
rgnBig.CombineRgn(&rgnBig, &rgnSml, RGN_DIFF);
pDC->SelectClipRgn(&rgnBig);
CAcModuleResourceOverride vTemp;
memDC.CreateCompatibleDC( pDC );
CBitmap bit;
bit.LoadBitmap(IDB_T20_DLG_RES);
memDC.SelectObject((HBITMAP)bit);
// 标题栏左上行
pDC->BitBlt(0, 0, 4, 16, &memDC, 0, 0, SRCCOPY);
// 标题栏右上行
pDC->BitBlt(wr.right-18, 0, 18, 16, &memDC, 45, 0, SRCCOPY);
// 标题栏上行
pDC->StretchBlt(1, 0, wr.Width()-2, 16, &memDC, 1, 0, 2, 13, SRCCOPY);
pDC->BitBlt(wr.right-19, 3, 3, 10, &memDC, 44, 16, SRCCOPY);
int count = wr.Width()-(4+22);
if (count % 2) ++count;
count = (int)(count*.5);
int deltaX = 0;
for (int i = 0; i < count; ++i)
{
pDC->BitBlt(4+deltaX, 0, 2, 16, &memDC, 44, 0, SRCCOPY);
deltaX += 2;
}
// 标题栏下行
if (m_bHasName)
{
DWORD oldClr = pDC->SetTextColor((DWORD)0);
int oldMode = pDC->SetBkMode(TRANSPARENT);
CFont *pOldFont = pDC->SelectObject(&m_font);
int txtW = pDC->GetOutputTextExtent(m_sTitle).cx;
pDC->BitBlt(0, 16, 8, 17, &memDC, 0, 13, SRCCOPY);
pDC->BitBlt(8+txtW, 16, 8, 17, &memDC, 15, 13, SRCCOPY);
pDC->StretchBlt(8, 16, txtW, 17, &memDC, 1, 13, 2, 17, SRCCOPY);
pDC->TextOut(8, 16+3, m_sTitle);
pDC->SelectObject(pOldFont);
pDC->SetTextColor(oldClr);
pDC->SetBkMode(oldMode);
pDC->StretchBlt(8+txtW+8, 16, wr.Width()-(8+txtW+8)-2, 17, &memDC, 23, 13, 2, 17, SRCCOPY);
pDC->BitBlt(wr.right-2, 16, 2, 17, &memDC, 35, 13, SRCCOPY);
}
if (m_bSizable)
{
// 左边框
pDC->StretchBlt(0, m_nTopHeight, m_nLBorderW, wr.Height()-m_nTopHeight,
&memDC, 41, 12, m_nLBorderW, 1, SRCCOPY);
// 右边框
pDC->StretchBlt(wr.right-m_nRBorderW, m_nTopHeight, m_nRBorderW, wr.Height()-m_nTopHeight,
&memDC, 41, 11, m_nRBorderW, 1, SRCCOPY);
// 下边框
pDC->StretchBlt(1, wr.bottom-m_nBBorderW, wr.Width()-2, m_nBBorderW,
&memDC, 41, 13, 1, m_nBBorderW, SRCCOPY);
}
else
{
// 左边框
pDC->StretchBlt(0, m_nTopHeight, m_nLBorderW, wr.Height()-m_nTopHeight,
&memDC, 23, 7, m_nLBorderW, 1, SRCCOPY);
// 右边框
pDC->StretchBlt(wr.right-m_nRBorderW, m_nTopHeight, m_nRBorderW, wr.Height()-m_nTopHeight,
&memDC, 23, 7, m_nRBorderW, 1, SRCCOPY);
// 下边框
pDC->StretchBlt(1, wr.bottom-m_nBBorderW, wr.Width()-2, m_nBBorderW,
&memDC, 23, 7, 1, m_nBBorderW, SRCCOPY);
}
// if (m_bSizable)
// pDC->TransparentBlt(wr.right-2-6, wr.bottom-2-6, 6, 6,
// &memDC, 31, 0, 6, 6, RGB(214, 214, 214));
// 画关闭按钮
CBitmap bitYiban, bitDanji, bitJinguo;
bitYiban.LoadBitmap(IDB_T20_TITLE_CLOSE_YIBAN);
bitDanji.LoadBitmap(IDB_T20_TITLE_CLOSE_DANJI);
bitJinguo.LoadBitmap(IDB_T20_TITLE_CLOSE_JINGUO);
CRect reClose = GetCloseBtnRect(false);
BitBlt(*pDC, reClose.TopLeft(), (HBITMAP)bitYiban, SRCCOPY);
if (m_bCBtnClick)
BitBlt(*pDC, reClose.TopLeft(), (HBITMAP)bitDanji, SRCCOPY);
if (m_bCBtnMoveon)
BitBlt(*pDC, reClose.TopLeft(), (HBITMAP)bitJinguo, SRCCOPY);
pDC->SelectClipRgn(NULL);
::ReleaseDC(m_hWnd, pDC->GetSafeHdc());
memDC.DeleteDC();
rgnBig.DeleteObject();
rgnSml.DeleteObject();
}
void GlwSkin::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp)
{
if (bCalcValidRects && m_bCaption)
{
lpncsp->rgrc[0].left = lpncsp->rgrc[0].left + m_nLBorderW;
lpncsp->rgrc[0].right = lpncsp->rgrc[0].right - m_nRBorderW;
lpncsp->rgrc[0].top = lpncsp->rgrc[0].top + m_nTopHeight;
lpncsp->rgrc[0].bottom = lpncsp->rgrc[0].bottom - m_nBBorderW;
lpncsp->rgrc[1] = lpncsp->rgrc[0];
}
else
{
Default();
}
}
void GlwSkin::OnSize(UINT nType, int cx, int cy)
{
OnNcPaint(0);
::SetWindowRgn(m_hWnd, GetRegion(), TRUE);
}
HRGN GlwSkin::GetRegion()
{
CRect rect;
::GetWindowRect(m_hWnd, &rect);
OffsetRect(&rect, -rect.left, -rect.top);
if (m_bCornerTitle)
{
rect.right += 1;
if (m_hRgn)
::DeleteObject(m_hRgn);
m_hRgn = ::CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, 5, 5);
HRGN hDif = ::CreateRectRgn(rect.left, rect.bottom-3, rect.right, rect.bottom);
::CombineRgn(m_hRgn, m_hRgn, hDif, RGN_OR);
::DeleteObject(hDif);
}
else
{
if (m_hRgn)
::DeleteObject(m_hRgn);
m_hRgn = ::CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
}
return m_hRgn;
}
BOOL GlwSkin::OnNcActivate(BOOL bActive)
{
m_bActive = bActive;
OnNcPaint(0);
if ( !bActive )
return TRUE;
else
return FALSE;
}
UINT GlwSkin::OnNcHitTest(CPoint point)
{
CRect wr;
::GetWindowRect(m_hWnd, &wr);
if (GetCloseBtnRect(true).PtInRect(point))
return HTCLOSE;
CRect reTitle(wr.left+m_nLBorderW, wr.top+1, wr.right-m_nRBorderW, wr.top + m_nTopHeight);
CRect reClient(wr.left+m_nLBorderW, wr.top+m_nTopHeight, wr.right-m_nRBorderW, wr.bottom-m_nBBorderW);
CRect reLeftBar(wr.left, wr.top + m_nTopHeight, wr.left+m_nLBorderW, wr.bottom-5);
CRect reRightBar(wr.right-m_nRBorderW, wr.top + m_nTopHeight, wr.right, wr.bottom-5);
CRect reBottomBar(wr.left+5, wr.bottom-m_nBBorderW, wr.right-5, wr.bottom);
CRect reTopBar(wr.left+5, wr.top, wr.right-5, wr.top+m_nBBorderW);
CRect reTL(wr.TopLeft(), CSize(5, 5));
CRect reTR(wr.right-5, wr.top, wr.right, wr.top+5);
CRect reBL(wr.left, wr.bottom-m_nBBorderW, wr.left+m_nLBorderW, wr.bottom);
CRect reBR(wr.right-/*m_nRBorderW*/5, wr.bottom-/*m_nBBorderW*/5, wr.right, wr.bottom);
if (reTitle.PtInRect(point))
return HTCAPTION;
if (reClient.PtInRect(point))
return HTCLIENT;
if (m_bSizable)
{
if (reLeftBar.PtInRect(point))
return HTLEFT;
if (reRightBar.PtInRect(point))
return HTRIGHT;
if (reBL.PtInRect(point))
return HTBOTTOMLEFT;
if (reBR.PtInRect(point))
return HTBOTTOMRIGHT;
if (reBottomBar.PtInRect(point))
return HTBOTTOM;
// if (reTopBar.PtInRect(point))
// return HTTOP;
// if (reTL.PtInRect(point))
// return HTTOPLEFT;
// if (reTR.PtInRect(point))
// return HTTOPRIGHT;
}
return HTCLIENT;
}
void GlwSkin::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
{
CRect wr;
::GetWindowRect(m_hWnd, wr);
::OffsetRect(&wr, -wr.left, -wr.top);
HRGN hRgnWnd(NULL), hRgnDif(NULL);
hRgnWnd = ::CreateRectRgn(wr.left, wr.top, wr.right, wr.bottom);
if (!m_reOldWnd.IsRectEmpty()) // 本操作为扩展
{
hRgnDif = ::CreateRectRgn(m_reOldWnd.left, m_reOldWnd.top, m_reOldWnd.right, m_reOldWnd.bottom);
m_reOldWnd.SetRect(0, 0, 0, 0);
}
else
{
hRgnDif = ::CreateRectRgn(wr.left, wr.top+m_nTopHeight, wr.right, wr.bottom);
::CombineRgn(hRgnWnd, hRgnWnd, hRgnDif, RGN_DIFF);
m_reOldWnd = wr;
}
::SetWindowRgn(m_hWnd, hRgnWnd, TRUE);
::DeleteObject(hRgnWnd);
::DeleteObject(hRgnDif);
}
void GlwSkin::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (nHitTest == HTCLOSE)
{
m_bCBtnClick = true;
m_bCBtnMoveon = false;
OnNcPaint(0);
return;
}
else if (nHitTest == HTCAPTION)
{
m_bNcLBDCaption = true;
m_dwOldLong = GetWindowLong(m_hWnd, GWL_EXSTYLE);
if (m_bDragTrans)
{
// global_hwnd = m_hWnd;
// global_bNCLD = true;
}
//透明
// SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd,GWL_EXSTYLE)^WS_EX_LAYERED);
// ::SetLayeredWindowAttributes(m_hWnd, 0, 123, LWA_ALPHA);
}
else if (nHitTest == HTBOTTOM || nHitTest == HTLEFT || nHitTest == HTRIGHT)
{
m_bNcLBDBorder = true;
}
Default();
}
void GlwSkin::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
m_bCBtnClick = false;
if (nHitTest == HTCLOSE)
{
::SendMessage(m_hWnd, WM_CLOSE, 0, 0);
return;
}
else if (nHitTest == HTCAPTION)
{
if (m_bNcLBDCaption)
{
SetWindowLong(m_hWnd, GWL_EXSTYLE, m_dwOldLong);
m_bNcLBDCaption = false;
if (m_bDragTrans)
{
// global_bNCLD = false;
// global_hwnd = NULL;
// global_bWndMoveStart = false;
}
}
}
else if (nHitTest == HTBOTTOM || nHitTest == HTLEFT || nHitTest == HTRIGHT)
{
if (m_bNcLBDBorder)
(CWnd::FromHandle(m_hWnd))->RedrawWindow();
//::PostMessage(m_hWnd, WM_PAINT, 0, 0);
m_bNcLBDBorder = false;
}
OnNcPaint(0);
}
void GlwSkin::OnNcMouseMove(UINT nHitTest, CPoint point)
{
if (!m_bCBtnClick && nHitTest == HTCLOSE)
{
if (!m_bCBtnClick)
{
m_bCBtnMoveon = true;
OnNcPaint(0);
}
}
else
{
if (m_bCBtnMoveon)
{
m_bCBtnMoveon = false;
OnNcPaint(0);
}
Default();
}
}
void GlwSkin::OnGetMinMaxInfo(MINMAXINFO *lpMMI)
{
lpMMI->ptMinTrackSize = CPoint( m_szMin.cx, m_szMin.cy );
}
BOOL GlwSkin::OnEraseBkgnd(CDC *pDC) { return FALSE; }
void GlwSkin::OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized)
{
m_bActive = ( nState == WA_ACTIVE || nState == WA_CLICKACTIVE );
OnNcActivate(m_bActive);
Default();
}
LRESULT GlwSkin::OnSetText(WPARAM wp, LPARAM lp)
{
TCHAR *str = (TCHAR*)lp;
// Default();
m_sTitle = str;
OnNcPaint(0);
return 0;
}
CRect GlwSkin::GetCloseBtnRect(bool bScreen)
{
CRect wr;
::GetWindowRect(m_hWnd, &wr);
if (!bScreen)
OffsetRect(&wr, -wr.left, -wr.top);
//return CRect(CPoint(wr.right-2-10, wr.top+2), CSize(10, 9));
return CRect(CPoint(wr.right-2-12, wr.top+2), CSize(12, 12));//jsx 2015-4-8 14:41:12
}
HBRUSH GlwSkin::OnCtlColorDlg( HWND hwnd, CDC *pDc, HWND hDlg )
{
if (m_hBrush)
::DeleteObject(m_hBrush);
m_hBrush = ::CreateSolidBrush(m_colorDlg);
return m_hBrush;
}
void GlwSkin::SetFont( LPCTSTR name, int fHeight )
{
CreateFont(name, fHeight, m_font);
OnNcPaint(0);
}
void GlwSkin::SetLabel( bool bset )
{
m_bHasName = bset;
if (!m_bHasName)
m_nTopHeight = 16;//jsx 2015-4-8 11:12:30 原值13
else
m_nTopHeight = 33;//原值30
}
void GlwSkin::SerColorDlg(COLORREF colorDlg)
{
m_colorDlg = colorDlg;
}