?? cooltipctrl.cpp
字號:
/*########################################################################
Filename: cooltipctrl.cpp
----------------------------------------------------
Remarks: ...
----------------------------------------------------
Author: 成真
Email: anyou@sina.com
anyou@msn.com
Created: 23/3/2003 19:20
########################################################################*/
#include "stdafx.h"
#include "CoolTipCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TIMER_DELAY 1
#define TIMER_FADE 2
#define TIMER_PTTEST 3
/*########################################################################
-------------------------
Construction
-------------------------
########################################################################*/
CCoolTipCtrl::CCoolTipCtrl()
{
m_nSize = CSize(10, 10);
m_nFade = 0;
m_nDelayTime = 10;
m_rcRect = CRect(0, 0, 8888, 6666);
m_crBk = RGB(250, 255, 225);
m_crText = RGB(0, 0, 0);
m_crTitle = RGB(0, 0, 0);
m_hIcon = NULL;
m_szIcon = CSize(0, 0);
m_dwState = 0;
}
BOOL CCoolTipCtrl::Create(CSize size, CWnd *pParentWnd, UINT dwStyle, UINT uID)
{
m_nSize = size;
m_dwStyle = dwStyle;
return CreateEx(WS_EX_TOOLWINDOW,
::AfxRegisterWndClass(0),
"COOL_TIP_CTRL_WINDOW",
WS_POPUP,
CRect(0, 0, size.cx, size.cy),
pParentWnd,
uID);
}
CCoolTipCtrl::~CCoolTipCtrl()
{
}
/*################################################################
--------------------------------------
CoolTip control message handlers
--------------------------------------
################################################################*/
BEGIN_MESSAGE_MAP(CCoolTipCtrl, CWnd)
//{{AFX_MSG_MAP(CCoolTipCtrl)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
ON_WM_PAINT()
ON_WM_NCPAINT()
ON_WM_NCCALCSIZE()
ON_WM_NCHITTEST()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
int CCoolTipCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
{
return -1;
}
CRect rect;
GetClientRect(&rect);
CDC *pdc = GetDC();
m_MemDC.CreateCompatibleDC(pdc);
bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy);
oldbitmap = m_MemDC.SelectObject(&bitmap);
ReleaseDC(pdc);
//load dll-------------------------------------------------
hUserDll = ::LoadLibrary(_T("USER32.dll"));
//Change style to layered window style...
::SetWindowLong(m_hWnd, GWL_EXSTYLE, ::GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA );
return 0;
}
void CCoolTipCtrl::OnDestroy()
{
CWnd::OnDestroy();
KillTimer(TIMER_FADE);
KillTimer(TIMER_DELAY);
KillTimer(TIMER_PTTEST);
m_MemDC.SelectObject(oldbitmap);
bitmap.DeleteObject();
m_MemDC.DeleteDC();
}
void CCoolTipCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
Hide();
CWnd::OnLButtonUp(nFlags, point);
}
void CCoolTipCtrl::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
//Delay show=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
case TIMER_DELAY:
m_nShowTime--;
//Delay time over-----------------------------=
if (m_nShowTime <= 0)
{
//Kill this timer-----------------------
KillTimer(TIMER_DELAY);
//PtTest--------------------------------
::GetCursorPos(&m_point);
if (!m_rcRect.PtInRect(m_point))
{
KillTimer(TIMER_PTTEST);
m_dwState = TIPS_HIDE;
return;
}
//Set size------------------------------
m_point.y += 20;
if (m_dwStyle & TIPS_AUTOSIZE)
{
AutoSize();
}
//Captrue Screen for draw shadow--------
CDC dc;
dc.Attach(::GetWindowDC(NULL));
m_MemDC.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &dc, m_point.x, m_point.y, SRCCOPY);
dc.Detach();
dc.DeleteDC();
//Display tip window---------------------
SetWindowPos(&wndTopMost,
m_point.x,
m_point.y,
m_nSize.cx,
m_nSize.cy,
SWP_SHOWWINDOW | SWP_NOACTIVATE);
//Draw window memory dc------------------
OnDraw(&m_MemDC);
//fade out window------------------------
SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA );
m_dwState = TIPS_FADEOUT;
m_nFade = 0;
SetTimer(TIMER_FADE, 30, NULL);
}
break;
//Fade out or in window=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
case TIMER_FADE:
if (m_dwState == TIPS_FADEIN)
{
m_nFade -= 28; //Fade in
}
else if (m_dwState == TIPS_FADEOUT)
{
m_nFade += 28; //Fade out
}
if (m_nFade >= 230)
{
m_nFade = (m_dwStyle & 0x00000002) ? 230 : 255;
m_dwState &= TIPS_NORMAL;
KillTimer(TIMER_FADE);
SetTimer (TIMER_PTTEST, 500, NULL);
}
else if (m_nFade < 0)
{
//Hide window-----------------
m_nFade = 0;
m_dwState = TIPS_HIDE;
KillTimer(TIMER_FADE);
KillTimer(TIMER_PTTEST);
ShowWindow(SW_HIDE);
if (GetStyle() & TIPS_SHOWNEXT)
{
m_dwStyle &= ~TIPS_SHOWNEXT;
m_nShowTime = 1;
m_dwState = TIPS_DELAYSHOW;
SetTimer(TIMER_DELAY , 100, NULL);
SetTimer(TIMER_PTTEST, 500, NULL);
}
}
SetTransparent(m_hWnd, 0, m_nFade , LWA_ALPHA );
break;
case TIMER_PTTEST:
::GetCursorPos(&m_point);
if (!m_rcRect.PtInRect(m_point))
{
KillTimer(TIMER_DELAY);
KillTimer(TIMER_PTTEST);
m_dwState = TIPS_FADEIN;
SetTimer(TIMER_FADE, 30, NULL);
}
break;
default:
break;
}
CWnd::OnTimer(nIDEvent);
}
void CCoolTipCtrl::OnPaint()
{
CRect rect;
GetClientRect(&rect);
CPaintDC dc(this);
CFont font, *oldfont;
font.CreateFont(-12, 0, 0, 400, 600, 0, 0, 0, 0, 0, 0, 0, 1, "宋體");
oldfont = dc.SelectObject(&font);
dc.SetBkMode(TRANSPARENT);
//Draw background ----------------------------------
dc.FillSolidRect(rect, m_crBk);
dc.Draw3dRect(rect, RGB(140, 140, 140), RGB(99, 99, 99));
rect.InflateRect(-5, -5);
//Draw title----------------------------------------
if (m_hIcon != NULL)
{
::DrawIconEx(dc.m_hDC, rect.left, rect.top, m_hIcon,
m_szIcon.cx, m_szIcon.cy, NULL, NULL, DI_NORMAL);
rect.left += m_szIcon.cx + 5;
}
if (m_strTitle != "")
{
dc.SetTextColor(m_crTitle);
dc.DrawText(m_strTitle, rect, DT_LEFT | DT_SINGLELINE);
rect.top += 15;
}
font.DeleteObject();
font.CreateFont(-12, 0, 0, 400, 400, 0, 0, 0, 0, 0, 0, 0, 1, "宋體");
dc.SelectObject(&font);
//Draw text------------------------------------
dc.SetTextColor(m_crText);
dc.DrawText(m_strText, rect, DT_LEFT | DT_WORDBREAK);
dc.SelectObject(oldfont);
font.DeleteObject();
}
/*===============================================================
Set Transparent
=================================================================*/
BOOL CCoolTipCtrl::SetTransparent(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
{
BOOL bRet = FALSE;
typedef BOOL (WINAPI* lpfnSetTransparent)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
// Check that "USER32.dll" library has been loaded successfully...
if ( hUserDll )
{
lpfnSetTransparent pFnSetTransparent = NULL;
pFnSetTransparent = (lpfnSetTransparent)GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
if (pFnSetTransparent )
{
bRet = pFnSetTransparent(hWnd, crKey, bAlpha, dwFlags);
}
} //if( hUserDll )
return bRet;
} // End of SetTransparent function
/*################################################################
--------------------------------------
CoolTip control display handlers
--------------------------------------
################################################################*/
void CCoolTipCtrl::SetRect(const CRect& rect)
{
m_rcRect = rect;
}
void CCoolTipCtrl::SetDelayTime(int nTime)
{
m_nDelayTime = nTime;
}
/*===============================================================
display window
=================================================================*/
BOOL CCoolTipCtrl::Show(CPoint point)
{
if (IsShow() && GetState() != TIPS_DELAYSHOW)
{
if (m_dwState != TIPS_FADEIN) Hide();
m_nFade = 10;
m_dwStyle |= TIPS_SHOWNEXT;
return FALSE;
}
m_point = point;
m_nShowTime = m_nDelayTime;
m_dwState = TIPS_DELAYSHOW;
SetTimer(TIMER_DELAY , 100, NULL);
SetTimer(TIMER_PTTEST, 500, NULL);
return TRUE;
}
/*===============================================================
hide window
=================================================================*/
BOOL CCoolTipCtrl::Hide()
{
if (m_dwState == TIPS_HIDE)
{
return FALSE;
}
m_dwState = TIPS_FADEIN;
SetTimer(TIMER_FADE, 30, NULL);
return TRUE;
}
BOOL CCoolTipCtrl::IsShow()
{
return (m_dwState != TIPS_HIDE) ;
}
void CCoolTipCtrl::DrawShadow(CDC *pDC, CRect rect, COLORREF color)
{
//Draw shadow----------------------------------------->>
COLORREF oldcolor = RGB(255, 255, 255);
BYTE newPixeValR, newPixeValG, newPixeValB;
BYTE AlphaArray[6] = {140, 170, 212, 240};
BYTE AlphaArray2[] = {170, 205, 220, 240, 240, 250, 255};
BYTE Alpha = 0;
//bottom shadow-----------------------------------------
int i, j;
for (j = 0; j < 4; j++)
{
Alpha = AlphaArray[j];
for (i = 6; i <= rect.right - 5; i++)
{
oldcolor = pDC->GetPixel(i, rect.bottom - (4 - j));
newPixeValR = GetRValue(oldcolor) * Alpha / 255;
newPixeValG = GetGValue(oldcolor) * Alpha / 255;
newPixeValB = GetBValue(oldcolor) * Alpha / 255;
pDC->SetPixel(i, rect.bottom - (4 - j), RGB(newPixeValR, newPixeValG, newPixeValB));
}
}
//right shadow-----------------------------------------
Alpha = 120;
for (i = 0; i < 4; i++)
{
Alpha = AlphaArray[i];
for (j = 6; j <= rect.bottom - 5; j++)
{
oldcolor = pDC->GetPixel(rect.right - (4 - i), j);
newPixeValR = GetRValue(oldcolor) * Alpha / 255;
newPixeValG = GetGValue(oldcolor) * Alpha / 255;
newPixeValB = GetBValue(oldcolor) * Alpha / 255;
pDC->SetPixel(rect.right - (4 - i), j, RGB(newPixeValR, newPixeValG, newPixeValB));
}
}
//other------------------------------------------------
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if ((i + j) > 6) break;
Alpha = AlphaArray2[j + i];
oldcolor = pDC->GetPixel(rect.right - 4 + i, rect.bottom - 4 + j);
newPixeValR = GetRValue(oldcolor) * Alpha / 255;
newPixeValG = GetGValue(oldcolor) * Alpha / 255;
newPixeValB = GetBValue(oldcolor) * Alpha / 255;
pDC->SetPixel(rect.right - 4 + i, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB));
oldcolor = pDC->GetPixel(rect.right - 4 + i, rect.top + 5 - j);
newPixeValR = GetRValue(oldcolor) * Alpha / 255;
newPixeValG = GetGValue(oldcolor) * Alpha / 255;
newPixeValB = GetBValue(oldcolor) * Alpha / 255;
pDC->SetPixel(rect.right - 4 + i, rect.top + 5 - j, RGB(newPixeValR, newPixeValG, newPixeValB));
oldcolor = pDC->GetPixel(rect.left - i + 5, rect.bottom - 4 + j);
newPixeValR = GetRValue(oldcolor) * Alpha / 255;
newPixeValG = GetGValue(oldcolor) * Alpha / 255;
newPixeValB = GetBValue(oldcolor) * Alpha / 255;
pDC->SetPixel(rect.left - i + 5, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB));
}
}
}
void CCoolTipCtrl::OnDraw(CDC *pDC)
{
}
/*################################################################
------------------------------------
CoolTip control size handlers
------------------------------------
################################################################*/
void CCoolTipCtrl::SetSize(CSize size)
{
m_nSize = size;
CDC *pdc = GetDC();
bitmap.DeleteObject();
bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy);
m_MemDC.SelectObject(&bitmap);
ReleaseDC(pdc);
}
void CCoolTipCtrl::AutoSize()
{
int nstrLength = m_strTitle.GetLength();
nstrLength = nstrLength > 30 ? nstrLength : 30;
CSize szText = GetStringSize(m_strText, nstrLength, CSize(6, 12));
m_nSize = szText;
m_nSize.cx += 14;
m_nSize.cy += 14;
if (m_strTitle != "" )
{
if (szText.cx < 180 && szText.cx < m_strTitle.GetLength() * 7 ) m_nSize.cx += m_strTitle.GetLength() * 7;
if (m_nSize.cx > 194) m_nSize.cx = 194;
m_nSize.cy += 15;
}
m_nSize.cx += m_szIcon.cx + 5;
if (m_nSize.cy < m_szIcon.cy + 14 ) m_nSize.cy = m_szIcon.cy + 14;
SetSize(m_nSize);
}
CSize CCoolTipCtrl::GetStringSize(CString strText, int nlinecount, CSize szFont)
{
int npos = 0;
CSize sz(0,0);
while (true)
{
npos = strText.Find('\n');
if (npos >= 0)
{
if (npos > nlinecount)
{
sz.cx = nlinecount;
sz.cy += npos / nlinecount + 1;
}
else
{
sz.cx = sz.cx > npos ? sz.cx : npos;
sz.cy += 1;
}
if (npos < (strText.GetLength() - 1))
{
strText = strText.Right(strText.GetLength() - npos - 1);
continue;
}
}
else if (npos == -1)
{
if (strText.GetLength() > nlinecount)
{
sz.cx = nlinecount;
sz.cy += strText.GetLength() / nlinecount + 1;
}
else
{
sz.cx = sz.cx > strText.GetLength() ? sz.cx : strText.GetLength();
sz.cy += 1;
}
}
break;
}
sz.cx = sz.cx * szFont.cx;
sz.cy = sz.cy * szFont.cy;
return sz;
}
/*################################################################
------------------------------------
CoolTip control text handlers
------------------------------------
################################################################*/
void CCoolTipCtrl::SetText(CString strText)
{
m_strText = strText;
}
void CCoolTipCtrl::SetTitle(CString strTitle)
{
m_strTitle = strTitle;
}
/*################################################################
-------------------------------------
CoolTip control color handlers
-------------------------------------
################################################################*/
void CCoolTipCtrl::SetTextColor(COLORREF crText)
{
m_crText = crText;
}
void CCoolTipCtrl::SetBkColor(COLORREF crBk)
{
m_crBk = crBk;
}
void CCoolTipCtrl::SetTitleColor(COLORREF crTitle)
{
m_crTitle = crTitle;
}
/*################################################################
------------------------------------
CoolTip control icon handlers
------------------------------------
################################################################*/
void CCoolTipCtrl::SetIcon(HICON hIcon, CSize szIcon)
{
m_hIcon = hIcon;
m_szIcon = szIcon;
}
void CCoolTipCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp)
{
CRect rect = lpncsp->rgrc[0];
rect.DeflateRect(0, 0, 4, 4);
lpncsp->rgrc[0] = rect;
}
void CCoolTipCtrl::OnNcPaint()
{
CWindowDC dc(this);
CRect rect;
GetWindowRect(&rect);
ScreenToClient(&rect);
dc.ExcludeClipRect(&CRect(0, 0, m_nSize.cx-4, m_nSize.cy-4));
dc.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &m_MemDC, 0, 0, SRCCOPY);
DrawShadow(&dc, rect);
}
UINT CCoolTipCtrl::OnNcHitTest(CPoint point)
{
return HTCAPTION ;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -