📄 zgtools.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// Tools.cpp : implementation file
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ZgTools.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma comment(lib,"msimg32.lib")
#pragma message("Automatically linking with msimg32.lib")
//////////////////////////////////////////////////////////////////////////
//在指定的位置绘制阴影
#define SM_CXSHADOW 2
void DrawShadow (HDC hDCIn, HDC hDCOut, RECT& rc)
{
for ( int x = 0; x < rc.right-1; x++ )
{
int nEnd = ( x > rc.right-SM_CXSHADOW*2 ) ? rc.right-SM_CXSHADOW-x : SM_CXSHADOW;
for ( int y = ( x < 2 ) ? 2-x : x > rc.right-SM_CXSHADOW-3 ? x-rc.right+SM_CXSHADOW+3 : 0; y < nEnd; y++ )
{
int nMakeSpec = 78+(3-(x==0?0:(x==1?(y<2?0:1):(x==2?(y<2?y:2):y))))*5;
COLORREF cr = GetPixel (hDCIn, x+SM_CXSHADOW, rc.bottom-y-1);
COLORREF cr2 = RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
((nMakeSpec * int(GetGValue(cr))) / 100),
((nMakeSpec * int(GetBValue(cr))) / 100));
SetPixel (hDCOut, x+SM_CXSHADOW, rc.bottom-y-1, cr2);
}
}
for ( x = 0; x < SM_CXSHADOW; x++ )
{
for ( int y = rc.top ; y < rc.bottom-x-SM_CXSHADOW-((x>0)?1:2); y++ )
{
int nMakeSpec = 78+(3-(y==0?0:(y==1?(x<2?0:1):(y==2?(x<2?x:2):x))))*5;
COLORREF cr = GetPixel (hDCIn, rc.right-x-1, y+SM_CXSHADOW);
COLORREF cr2 = RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
((nMakeSpec * int(GetGValue(cr))) / 100),
((nMakeSpec * int(GetBValue(cr))) / 100));
SetPixel (hDCOut, rc.right-x-1, y+SM_CXSHADOW, cr2);
}
}
}
//////////////////////////////////////////////////////////////////////////
//渐变填充指定范围
void GradientFillRect(HDC hDC, CRect &rcFill, ULONG nMode, COLORREF crLeftTop, COLORREF crRightBottom)
{
COLOR16 r = (COLOR16) ((crLeftTop & 0x000000FF)<<8);
COLOR16 g = (COLOR16) (crLeftTop & 0x0000FF00);
COLOR16 b = (COLOR16) ((crLeftTop & 0x00FF0000)>>8);
TRIVERTEX vert[2] ;
GRADIENT_RECT gRect;
vert [0] .x = rcFill.left;
vert [0] .y = rcFill.top;
vert [0] .Red = r;
vert [0] .Green = g;
vert [0] .Blue = b;
vert [0] .Alpha = 0x0000;
r = (COLOR16) ((crRightBottom & 0x000000FF)<<8);
g = (COLOR16) (crRightBottom & 0x0000FF00);
b = (COLOR16) ((crRightBottom & 0x00FF0000)>>8);
vert [1] .x = rcFill.right;
vert [1] .y = rcFill.bottom;
vert [1] .Red = r;
vert [1] .Green = g;
vert [1] .Blue = b;
vert [1] .Alpha = 0x0000;
gRect.UpperLeft = 0;
gRect.LowerRight = 1;
GradientFill(hDC, vert, 2, &gRect,1, nMode);
}
///////////////////////////////////////////////////////////////////////////////
//获取当前系统的版本
WinVer WINAPI GetWinVersion ()
{
static WinVer s_wvVal = wvUndefined;
if ( s_wvVal != wvUndefined )
{
return s_wvVal;
}
OSVERSIONINFO osvi;
ZeroMemory (&osvi, sizeof OSVERSIONINFO);
osvi.dwOSVersionInfoSize = sizeof OSVERSIONINFO;
if ( !GetVersionEx (&osvi) )
{
return s_wvVal = wvUndefined;
}
if ( osvi.dwPlatformId == VER_PLATFORM_WIN32s )
{
return s_wvVal = wvWin32s;
}
if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
if ( osvi.dwMajorVersion == 4L )
{
return s_wvVal = wvWinNT4;
}
if ( osvi.dwMajorVersion == 5L && osvi.dwMinorVersion == 0L )
{
return s_wvVal = wvWin2000;
}
if ( osvi.dwMajorVersion == 5L && osvi.dwMinorVersion == 1L )
{
return s_wvVal = wvWinXP;
}
return s_wvVal = wvWinNT3;
}
ASSERT(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
if ( osvi.dwMajorVersion == 4L && osvi.dwMinorVersion == 10L )
{
return s_wvVal = wvWin98;
}
if ( osvi.dwMajorVersion == 4L && osvi.dwMinorVersion == 90L )
{
return s_wvVal = wvWinME;
}
return s_wvVal = wvWin95;
}
///////////////////////////////////////////////////////////////////////////////
//
HLSCOLOR RGB2HLS (COLORREF rgb)
{
unsigned char minval = min(GetRValue(rgb), min(GetGValue(rgb), GetBValue(rgb)));
unsigned char maxval = max(GetRValue(rgb), max(GetGValue(rgb), GetBValue(rgb)));
float mdiff = float(maxval) - float(minval);
float msum = float(maxval) + float(minval);
float luminance = msum / 510.0f;
float saturation = 0.0f;
float hue = 0.0f;
if ( maxval != minval )
{
float rnorm = (maxval - GetRValue(rgb) ) / mdiff;
float gnorm = (maxval - GetGValue(rgb)) / mdiff;
float bnorm = (maxval - GetBValue(rgb) ) / mdiff;
saturation = (luminance <= 0.5f) ? (mdiff / msum) : (mdiff / (510.0f - msum));
if (GetRValue(rgb) == maxval) hue = 60.0f * (6.0f + bnorm - gnorm);
if (GetGValue(rgb) == maxval) hue = 60.0f * (2.0f + rnorm - bnorm);
if (GetBValue(rgb) == maxval) hue = 60.0f * (4.0f + gnorm - rnorm);
if (hue > 360.0f) hue = hue - 360.0f;
}
return HLS ((hue*255)/360, luminance*255, saturation*255);
}
///////////////////////////////////////////////////////////////////////////////
//
static BYTE _ToRGB (float rm1, float rm2, float rh)
{
if (rh > 360.0f) rh -= 360.0f;
else if (rh < 0.0f) rh += 360.0f;
if (rh < 60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;
else if (rh < 180.0f) rm1 = rm2;
else if (rh < 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;
return (BYTE)(rm1 * 255);
}
///////////////////////////////////////////////////////////////////////////////
//
COLORREF HLS2RGB (HLSCOLOR hls)
{
float hue = ((int)HLS_H(hls)*360)/255.0f;
float luminance = HLS_L(hls)/255.0f;
float saturation = HLS_S(hls)/255.0f;
if ( saturation == 0.0f )
{
return RGB (HLS_L(hls), HLS_L(hls), HLS_L(hls));
}
float rm1, rm2;
if ( luminance <= 0.5f ) rm2 = luminance + luminance * saturation;
else rm2 = luminance + saturation - luminance * saturation;
rm1 = 2.0f * luminance - rm2;
BYTE red = _ToRGB (rm1, rm2, hue + 120.0f);
BYTE green = _ToRGB (rm1, rm2, hue);
BYTE blue = _ToRGB (rm1, rm2, hue - 120.0f);
return RGB (red, green, blue);
}
///////////////////////////////////////////////////////////////////////////////
//
COLORREF HLS_TRANSFORM (COLORREF rgb, int percent_L, int percent_S)
{
HLSCOLOR hls = RGB2HLS (rgb);
BYTE h = HLS_H(hls);
BYTE l = HLS_L(hls);
BYTE s = HLS_S(hls);
if ( percent_L > 0 )
{
l = BYTE(l + ((255 - l) * percent_L) / 100);
}
else if ( percent_L < 0 )
{
l = BYTE((l * (100+percent_L)) / 100);
}
if ( percent_S > 0 )
{
s = BYTE(s + ((255 - s) * percent_S) / 100);
}
else if ( percent_S < 0 )
{
s = BYTE((s * (100+percent_S)) / 100);
}
return HLS2RGB (HLS(h, l, s));
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
const int HIMETRIC_INCH = 2540;
CZgBitmap::CZgBitmap()
{
}
CZgBitmap::~CZgBitmap()
{
}
BOOL CZgBitmap::LoadImage(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst, COLORREF crBack)
{
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
if (m_hObject != NULL)
return FALSE;
BYTE* pBuff = NULL;
int nSize = 0;
BOOL bResult = FALSE;
// first call is to get buffer size
if (GetResource(MAKEINTRESOURCE(uIDRes), szResourceType, hInst, 0, nSize))
{
if (nSize > 0)
{
pBuff = new BYTE[nSize];
// this loads it
if (GetResource(MAKEINTRESOURCE(uIDRes), szResourceType, hInst, pBuff, nSize))
{
IPicture* pPicture = LoadFromBuffer(pBuff, nSize);
if (pPicture)
{
bResult = Attach(pPicture, crBack);
pPicture->Release();
}
}
delete [] pBuff;
}
}
return bResult;
}
BOOL CZgBitmap::LoadImage(LPCTSTR szImagePath, COLORREF crBack)
{
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
if (m_hObject != NULL)
return FALSE;
BOOL bResult = FALSE;
CFile cFile;
CFileException e;
if (cFile.Open(szImagePath, CFile::modeRead | CFile::typeBinary, &e))
{
int nSize = cFile.GetLength();
BYTE* pBuff = new BYTE[nSize];
if (cFile.Read(pBuff, nSize) > 0)
{
IPicture* pPicture = LoadFromBuffer(pBuff, nSize);
if (pPicture)
{
bResult = Attach(pPicture, crBack);
pPicture->Release();
}
}
delete [] pBuff;
}
return bResult;
}
IPicture* CZgBitmap::LoadFromBuffer(BYTE* pBuff, int nSize)
{
bool bResult = false;
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize);
void* pData = GlobalLock(hGlobal);
memcpy(pData, pBuff, nSize);
GlobalUnlock(hGlobal);
IStream* pStream = NULL;
IPicture* pPicture = NULL;
if (CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK)
{
HRESULT hr = OleLoadPicture(pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&pPicture);
pStream->Release();
}
return pPicture; // caller releases
}
BOOL CZgBitmap::GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize)
{
HRSRC hResInfo;
HANDLE hRes;
LPSTR lpRes = NULL;
int nLen = 0;
bool bResult = FALSE;
// Find the resource
hResInfo = FindResource(hInst, lpName, lpType);
if (hResInfo == NULL)
return false;
// Load the resource
hRes = LoadResource(hInst, hResInfo);
if (hRes == NULL)
return false;
// Lock the resource
lpRes = (char*)LockResource(hRes);
if (lpRes != NULL)
{
if (pResource == NULL)
{
nBufSize = SizeofResource(hInst, hResInfo);
bResult = true;
}
else
{
if (nBufSize >= (int)SizeofResource(hInst, hResInfo))
{
memcpy(pResource, lpRes, nBufSize);
bResult = true;
}
}
UnlockResource(hRes);
}
// Free the resource
FreeResource(hRes);
return bResult;
}
BOOL CZgBitmap::Attach(IPicture* pPicture, COLORREF crBack)
{
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
if (m_hObject != NULL)
return FALSE;
ASSERT(pPicture);
if (!pPicture)
return FALSE;
BOOL bResult = FALSE;
CDC dcMem;
CDC* pDC = CWnd::GetDesktopWindow()->GetDC();
if (dcMem.CreateCompatibleDC(pDC))
{
long hmWidth;
long hmHeight;
pPicture->get_Width(&hmWidth);
pPicture->get_Height(&hmHeight);
int nWidth = MulDiv(hmWidth, pDC->GetDeviceCaps(LOGPIXELSX), HIMETRIC_INCH);
int nHeight = MulDiv(hmHeight, pDC->GetDeviceCaps(LOGPIXELSY), HIMETRIC_INCH);
CBitmap bmMem;
if (bmMem.CreateCompatibleBitmap(pDC, nWidth, nHeight))
{
CBitmap* pOldBM = dcMem.SelectObject(&bmMem);
if (crBack != -1)
dcMem.FillSolidRect(0, 0, nWidth, nHeight, crBack);
HRESULT hr = pPicture->Render(dcMem, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, NULL);
dcMem.SelectObject(pOldBM);
if (hr == S_OK)
bResult = CBitmap::Attach(bmMem.Detach());
}
}
CWnd::GetDesktopWindow()->ReleaseDC(pDC);
return bResult;
}
HRGN CZgBitmap::CreateRgnFromFile(COLORREF color)
{
if (!GetSafeHandle())
return FALSE;
HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
// get image properties
BITMAP bmp = { 0 };
::GetObject( hBmp, sizeof(BITMAP), &bmp );
// allocate memory for extended image information
LPBITMAPINFO bi = (LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
memset( bi, 0, sizeof(BITMAPINFO) + 8 );
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// set window size
int m_dwWidth = bmp.bmWidth; // bitmap width
int m_dwHeight = bmp.bmHeight; // bitmap height
// create temporary dc
HDC dc = CreateIC( "DISPLAY",NULL,NULL,NULL );
// get extended information about image (length, compression, length of color table if exist, ...)
DWORD res = GetDIBits( dc, hBmp, 0, bmp.bmHeight, 0, bi, DIB_RGB_COLORS );
// allocate memory for image data (colors)
LPBYTE pBits = new BYTE[ bi->bmiHeader.biSizeImage + 4 ];
// allocate memory for color table
if ( bi->bmiHeader.biBitCount == 8 )
{
// actually color table should be appended to this header(BITMAPINFO),
// so we have to reallocate and copy it
LPBITMAPINFO old_bi = bi;
// 255 - because there is one in BITMAPINFOHEADER
bi = (LPBITMAPINFO)new char[ sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD) ];
memcpy( bi, old_bi, sizeof(BITMAPINFO) );
// release old header
delete old_bi;
}
// get bitmap info header
BITMAPINFOHEADER& bih = bi->bmiHeader;
// get color table (for 256 color mode contains 256 entries of RGBQUAD(=DWORD))
LPDWORD clr_tbl = (LPDWORD)&bi->bmiColors;
// fill bits buffer
res = GetDIBits( dc, hBmp, 0, bih.biHeight, pBits, bi, DIB_RGB_COLORS );
DeleteDC( dc );
BITMAP bm;
::GetObject( hBmp, sizeof(BITMAP), &bm );
// shift bits and byte per pixel (for comparing colors)
LPBYTE pClr = (LPBYTE)&color;
// swap red and blue components
BYTE tmp = pClr[0]; pClr[0] = pClr[2]; pClr[2] = tmp;
// convert color if curent DC is 16-bit (5:6:5) or 15-bit (5:5:5)
if ( bih.biBitCount == 16 )
{
// for 16 bit
color = ((DWORD)(pClr[0] & 0xf8) >> 3) |
((DWORD)(pClr[1] & 0xfc) << 3) |
((DWORD)(pClr[2] & 0xf8) << 8);
// for 15 bit
// color = ((DWORD)(pClr[0] & 0xf8) >> 3) |
// ((DWORD)(pClr[1] & 0xf8) << 2) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -