/*---------------------------------------------------------------------------*/ // Author : hiyohiyo // Mail : hiyohiyo@crystalmark.info // Web : https://crystalmark.info/ // License : MIT License /*---------------------------------------------------------------------------*/ #include "stdafx.h" #include "ComboBoxFx.h" #if _MSC_VER <= 1310 #define ON_WM_MOUSEHOVER() \ { 0x2A1 /*WM_MOUSEHOVER*/, 0, 0, 0, AfxSig_vwp, \ (AFX_PMSG)(AFX_PMSGW) \ (static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (OnMouseHover)) }, #define ON_WM_MOUSELEAVE() \ { 0x2A3 /*WM_MOUSELEAVE*/, 0, 0, 0, AfxSig_vv, \ (AFX_PMSG)(AFX_PMSGW) \ (static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (OnMouseLeave)) }, #endif ////------------------------------------------------ // CComboBoxFx ////------------------------------------------------ CComboBoxFx::CComboBoxFx() { // Control m_X = 0; m_Y = 0; m_ZoomRatio = 1.0; m_bHighContrast = FALSE; m_bDarkMode = FALSE; m_RenderMode = SystemDraw; m_Margin.top = 0; m_Margin.left = 0; m_Margin.bottom = 0; m_Margin.right = 0; // Alpha/Glass m_Alpha = 255; m_GlassColor = RGB(255, 255, 255); m_GlassAlpha = 255; // Image m_ImageCount = 0; m_ImagePath = _T(""); m_BkDC = NULL; m_bBkBitmapInit = FALSE; m_bBkLoad = FALSE; // Font m_TextAlign = SS_LEFT; m_TextColor = RGB(0, 0, 0); m_TextColorSelected = RGB(255, 255, 255); m_BkColor = RGB(255, 255, 255); m_BkColorSelected = RGB(230, 230, 230); m_TextColorHc = RGB(255, 255, 255); m_TextColorSelectedHc = RGB(0, 0, 0); m_BkColorHc = RGB(0, 0, 0); m_BkColorSelectedHc = RGB(0, 255, 255); m_FontHeight = 16; m_FontRender = CLEARTYPE_NATURAL_QUALITY; // Mouse m_bHover = FALSE; m_bFocas = FALSE; m_bTrackingNow = FALSE; m_bHandCursor = FALSE; } CComboBoxFx::~CComboBoxFx() { m_BkBrush.DeleteObject(); } IMPLEMENT_DYNAMIC(CComboBoxFx, CComboBox) BEGIN_MESSAGE_MAP(CComboBoxFx, CComboBox) //{{AFX_MSG_MAP(CComboBoxFx) ON_WM_CTLCOLOR() ON_WM_MOUSEMOVE() ON_WM_MOUSEHOVER() ON_WM_MOUSELEAVE() ON_WM_KILLFOCUS() ON_WM_SETFOCUS() ON_WM_SETCURSOR() //}}AFX_MSG_MAP END_MESSAGE_MAP() //------------------------------------------------ // Control //------------------------------------------------ BOOL CComboBoxFx::InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC, LPCWSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode, COLORREF bkColor, COLORREF bkColorSelected, COLORREF glassColor, BYTE glassAlpha) { m_X = (int)(x * zoomRatio); m_Y = (int)(y * zoomRatio); m_ZoomRatio = zoomRatio; m_CtrlSize.cx = (int)(width * zoomRatio); m_CtrlSize.cy = (int)(height * zoomRatio); MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy); m_BkDC = bkDC; m_ImagePath = imagePath; m_ImageCount = imageCount; m_RenderMode = renderMode; m_BkColor = bkColor; m_BkColorSelected = bkColorSelected; m_GlassColor = glassColor; m_GlassAlpha = glassAlpha; // BkBrush m_BkBrush.DeleteObject(); if (bDarkMode) { m_BkBrush.CreateSolidBrush(RGB(32, 32, 32)); } else { m_BkBrush.CreateSolidBrush(bkColor); } if (ES_LEFT <= textAlign && textAlign <= ES_RIGHT) { m_TextAlign = textAlign; ModifyStyle(0, m_TextAlign); } if (m_ToolTip.m_hWnd != NULL) { if (m_ToolTip.GetToolCount() != 0) { m_ToolTip.DelTool(this, 1); } CRect rect; GetClientRect(rect); m_ToolTip.AddTool(this, m_ToolTipText, rect, 1); } m_bHighContrast = bHighContrast; m_bDarkMode = bDarkMode; if (renderMode & SystemDraw) { #if _MSC_VER <= 1310 if (IsNT3()) { ModifyStyle(0, WS_BORDER, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); } #endif return TRUE; } else { m_ImageCount = 1; m_CtrlImage.Destroy(); m_CtrlImage.Create(m_CtrlSize.cx, m_CtrlSize.cy * m_ImageCount, 32); m_CtrlBitmap.Detach(); m_CtrlBitmap.Attach((HBITMAP)m_CtrlImage); DWORD length = m_CtrlSize.cx * m_CtrlSize.cy * m_ImageCount * 4; BYTE* bitmapBits = new BYTE[length]; m_CtrlBitmap.GetBitmapBits(length, bitmapBits); BYTE r, g, b, a; if (renderMode & OwnerDrawGlass) { r = (BYTE)GetRValue(m_GlassColor); g = (BYTE)GetGValue(m_GlassColor); b = (BYTE)GetBValue(m_GlassColor); a = m_GlassAlpha; } else // OwnerDrawTransparent { r = 0; g = 0; b = 0; a = 0; } for (int y = 0; y < (int)(m_CtrlSize.cy * m_ImageCount); y++) { for (int x = 0; x < m_CtrlSize.cx; x++) { DWORD p = (y * m_CtrlSize.cx + x) * 4; #if _MSC_VER > 1310 #pragma warning( disable : 6386 ) #endif bitmapBits[p + 0] = b; bitmapBits[p + 1] = g; bitmapBits[p + 2] = r; bitmapBits[p + 3] = a; #if _MSC_VER > 1310 #pragma warning( default : 6386 ) #endif } } m_CtrlBitmap.SetBitmapBits(length, bitmapBits); delete[] bitmapBits; } SetBkReload(); Invalidate(); return TRUE; } void CComboBoxFx::SetFontHeight(int height, double zoomRatio, double fontRatio) { m_FontHeight = (LONG)(-1 * height * zoomRatio * fontRatio); } void CComboBoxFx::SetItemHeightEx(int nIndex, int height, double zoomRatio, double fontRatio) { if (nIndex == -1) { CRect rc; GetWindowRect(&rc); CComboBox::SetItemHeight(-1, (UINT)(height * zoomRatio - rc.Height() + GetItemHeight(-1))); } else { CComboBox::SetItemHeight(nIndex, (UINT)(height * zoomRatio * fontRatio)); } } void CComboBoxFx::SetItemHeightAll(int height, double zoomRatio, double fontRatio) { m_FontHeight = (LONG)(-1 * height * zoomRatio * fontRatio); CRect rc; GetWindowRect(&rc); CComboBox::SetItemHeight(-1, (UINT)(height * zoomRatio - rc.Height() + GetItemHeight(-1))); for(int i = 0; i < this->GetCount(); i++) { CComboBox::SetItemHeight(i, (UINT)(height * zoomRatio * fontRatio)); } } void CComboBoxFx::SetMargin(int top, int left, int bottom, int right, double zoomRatio) { m_Margin.top = (int)(top * zoomRatio); m_Margin.left = (int)(left * zoomRatio); m_Margin.bottom = (int)(bottom * zoomRatio); m_Margin.right = (int)(right * zoomRatio); m_ZoomRatio = zoomRatio; } CSize CComboBoxFx::GetSize(void) { return m_CtrlSize; } void CComboBoxFx::SetGlassColor(COLORREF glassColor, BYTE glassAlpha) { m_GlassColor = glassColor; m_GlassAlpha = glassAlpha; } void CComboBoxFx::SetAlpha(BYTE alpha) { m_Alpha = alpha; } HWND CComboBoxFx::GetListHwnd() { #if _MSC_VER > 1310 COMBOBOXINFO info = { 0 }; info.cbSize = sizeof(COMBOBOXINFO); GetComboBoxInfo(&info); return info.hwndList; #else return NULL; #endif } HBRUSH CComboBoxFx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor); switch (nCtlColor) { case CTLCOLOR_EDIT: pDC->SetBkMode(TRANSPARENT); return hbr; case CTLCOLOR_LISTBOX: pDC->SetBkMode(TRANSPARENT); return m_BkBrush; default: return hbr; } } //------------------------------------------------ // Draw Control //------------------------------------------------ void CComboBoxFx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { if (lpDrawItemStruct->itemID == -1) { return; } static COLORREF textColor; static COLORREF textColorSelected; static COLORREF bkColor; static COLORREF bkColorSelected; static int count = 0; if (m_bHighContrast) { textColor = GetTextColor(lpDrawItemStruct->hDC); textColorSelected = RGB(0, 0, 0); bkColor = GetBkColor(lpDrawItemStruct->hDC); bkColorSelected = RGB(0, 255, 255); if (bkColor <= RGB(0x80, 0x80, 0x80)) { textColor = RGB(255, 255, 255); } else { textColor = RGB(0, 0, 0); } } else if (m_bDarkMode) { textColor = RGB(255, 255, 255); textColorSelected = RGB(255, 255, 255); bkColor = RGB(32, 32, 32); bkColorSelected = RGB(77, 77, 77); } else { textColor = m_TextColor; textColorSelected = m_TextColorSelected; bkColor = m_BkColor; bkColorSelected = m_BkColorSelected; } CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); LoadCtrlBk(pDC); CString title; GetLBText(lpDrawItemStruct->itemID, title); CBrush Brush; CBrush* pOldBrush; if (lpDrawItemStruct->rcItem.left != 0 && !m_bHighContrast) { DrawControl(title, pDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageNormal); Brush.CreateSolidBrush(bkColorSelected); pOldBrush = pDC->SelectObject(&Brush); if (lpDrawItemStruct->itemState & ODS_SELECTED) { RECT rc = lpDrawItemStruct->rcItem; // rc.top = (LONG)(rc.bottom - 2 * m_ZoomRatio); rc.right = (LONG)(rc.left + 3 * m_ZoomRatio); FillRect(lpDrawItemStruct->hDC, &rc, (HBRUSH)Brush); } DrawString(title, pDC, lpDrawItemStruct, textColor); #if _MSC_VER <= 1310 if (IsNT3() && IsWindowEnabled()) { DWORD oldTextAlign = m_TextAlign; m_TextAlign = ES_RIGHT; DrawString(_T("v"), pDC, lpDrawItemStruct, textColor); m_TextAlign = oldTextAlign; } #endif } else { if (lpDrawItemStruct->itemState & ODS_SELECTED) { Brush.CreateSolidBrush(bkColorSelected); pOldBrush = pDC->SelectObject(&Brush); FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)Brush); DrawString(title, pDC, lpDrawItemStruct, textColorSelected); } else { Brush.CreateSolidBrush(bkColor); pOldBrush = pDC->SelectObject(&Brush); FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)Brush); DrawString(title, pDC, lpDrawItemStruct, textColor); } } pDC->SelectObject(pOldBrush); Brush.DeleteObject(); } void CComboBoxFx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { lpMeasureItemStruct->itemHeight = abs(m_FontHeight); } void CComboBoxFx::DrawControl(CString title, CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no) { CDC* pMemDC = new CDC; CBitmap* pOldMemBitmap; pMemDC->CreateCompatibleDC(drawDC); pOldMemBitmap = pMemDC->SelectObject(&ctrlBitmap); CDC* pBkDC = new CDC; CBitmap* pOldBkBitmap; pBkDC->CreateCompatibleDC(drawDC); pOldBkBitmap = pBkDC->SelectObject(&bkBitmap); CBitmap DrawBmp; DrawBmp.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy); CDC* pDrawBmpDC = new CDC; CBitmap* pOldDrawBitmap; pDrawBmpDC->CreateCompatibleDC(drawDC); pOldDrawBitmap = pDrawBmpDC->SelectObject(&DrawBmp); int color = drawDC->GetDeviceCaps(BITSPIXEL) * drawDC->GetDeviceCaps(PLANES); if (!m_CtrlImage.IsNull()) { if (m_CtrlImage.GetBPP() == 32) { CBitmap* bk32Bitmap; CImage bk32Image; if (color == 32) { bk32Bitmap = &bkBitmap; } else { bk32Image.Create(m_CtrlSize.cx, m_CtrlSize.cy, 32); ::BitBlt(bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, *pBkDC, 0, 0, SRCCOPY); bk32Bitmap = CBitmap::FromHandle((HBITMAP)bk32Image); } BITMAP CtlBmpInfo, DstBmpInfo; bk32Bitmap->GetBitmap(&DstBmpInfo); DWORD DstLineBytes = DstBmpInfo.bmWidthBytes; DWORD DstMemSize = DstLineBytes * DstBmpInfo.bmHeight; ctrlBitmap.GetBitmap(&CtlBmpInfo); DWORD CtlLineBytes = CtlBmpInfo.bmWidthBytes; DWORD CtlMemSize = CtlLineBytes * CtlBmpInfo.bmHeight; BYTE* DstBuffer = new BYTE[DstMemSize]; bk32Bitmap->GetBitmapBits(DstMemSize, DstBuffer); BYTE* CtlBuffer = new BYTE[CtlMemSize]; ctrlBitmap.GetBitmapBits(CtlMemSize, CtlBuffer); int baseY = m_CtrlSize.cy * no; for (LONG py = 0; py < DstBmpInfo.bmHeight; py++) { int dn = py * DstLineBytes; int cn = (baseY + py) * CtlLineBytes; for (LONG px = 0; px < DstBmpInfo.bmWidth; px++) { #if _MSC_VER > 1310 #pragma warning( disable : 6385 ) #pragma warning( disable : 6386 ) #endif BYTE a = CtlBuffer[cn + 3]; BYTE na = 255 - a; DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255); DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255); DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255); dn += (DstBmpInfo.bmBitsPixel / 8); cn += (CtlBmpInfo.bmBitsPixel / 8); #if _MSC_VER > 1310 #pragma warning( default : 6386 ) #pragma warning( default : 6385 ) #endif } } if (color == 32) { DrawBmp.SetBitmapBits(DstMemSize, DstBuffer); } else { bk32Bitmap->SetBitmapBits(DstMemSize, DstBuffer); ::BitBlt(pDrawBmpDC->GetSafeHdc(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, bk32Image.GetDC(), 0, 0, SRCCOPY); bk32Image.ReleaseDC(); } drawDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, SRCCOPY); delete[] DstBuffer; delete[] CtlBuffer; } else { pDrawBmpDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pMemDC, 0, m_CtrlSize.cy * no, SRCCOPY); drawDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, SRCCOPY); } } else { pDrawBmpDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pBkDC, 0, m_CtrlSize.cy * no, SRCCOPY); drawDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, SRCCOPY); } pDrawBmpDC->SelectObject(&pOldDrawBitmap); pDrawBmpDC->DeleteDC(); delete pDrawBmpDC; pMemDC->SelectObject(&pOldMemBitmap); pMemDC->DeleteDC(); delete pMemDC; pBkDC->SelectObject(&pOldBkBitmap); pBkDC->DeleteDC(); delete pBkDC; } void CComboBoxFx::DrawString(CString title, CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, COLORREF textColor) { if (title.IsEmpty()) { return; } drawDC->SetBkMode(TRANSPARENT); CRect rect = (CRect)(lpDrawItemStruct->rcItem); rect.top += m_Margin.top; rect.left += m_Margin.left; rect.bottom -= m_Margin.bottom; rect.right -= m_Margin.right; drawDC->SetTextColor(textColor); if (m_TextAlign == ES_LEFT) { drawDC->DrawText(title, title.GetLength(), rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } else if (m_TextAlign == ES_RIGHT) { drawDC->DrawText(title, title.GetLength(), rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE); } else { drawDC->DrawText(title, title.GetLength(), rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } } //------------------------------------------------ // Image //------------------------------------------------ BOOL CComboBoxFx::LoadBitmap(LPCTSTR fileName) { if (m_bHighContrast) { return FALSE; } if (fileName == NULL) { return FALSE; } m_CtrlImage.Destroy(); m_CtrlImage.Load(fileName); if (m_CtrlImage.IsNull()) { return FALSE; } return LoadBitmap((HBITMAP)m_CtrlImage); } BOOL CComboBoxFx::LoadBitmap(HBITMAP hBitmap) { if (m_bHighContrast) { return FALSE; } m_CtrlBitmap.Detach(); m_CtrlBitmap.Attach(hBitmap); return SetBitmap(m_CtrlBitmap); } void CComboBoxFx::SetBkReload(void) { m_bBkBitmapInit = FALSE; m_bBkLoad = FALSE; } BOOL CComboBoxFx::SetBitmap(CBitmap& bitmap) { if (m_bHighContrast) { return FALSE; } BITMAP bitmapinfo; bitmap.GetBitmap(&bitmapinfo); if (m_CtrlSize.cx != bitmapinfo.bmWidth || m_CtrlSize.cy != bitmapinfo.bmHeight / m_ImageCount) { return FALSE; } else { return TRUE; } } void CComboBoxFx::LoadCtrlBk(CDC* drawDC) { if (m_bHighContrast) { SetBkReload(); return; } if (m_BkBitmap.m_hObject != NULL) { BITMAP bitmapInfo; m_BkBitmap.GetBitmap(&bitmapInfo); if (bitmapInfo.bmBitsPixel != drawDC->GetDeviceCaps(BITSPIXEL)) { SetBkReload(); } } if (&m_CtrlBitmap != NULL) { if (!m_bBkBitmapInit) { m_BkBitmap.DeleteObject(); m_BkBitmap.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy); m_bBkBitmapInit = TRUE; } if (!m_bBkLoad) { CBitmap* pOldBitmap; CDC* pMemDC = new CDC; pMemDC->CreateCompatibleDC(drawDC); pOldBitmap = pMemDC->SelectObject(&m_BkBitmap); pMemDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, m_BkDC, m_X, m_Y, SRCCOPY); pMemDC->SelectObject(pOldBitmap); pMemDC->DeleteDC(); delete pMemDC; m_bBkLoad = TRUE; } } } //------------------------------------------------ // Font //------------------------------------------------ void CComboBoxFx::SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio, COLORREF textColor, COLORREF textColorSelected, LONG fontWeight, BYTE fontRender) { LOGFONT logFont = { 0 }; logFont.lfCharSet = DEFAULT_CHARSET; logFont.lfHeight = (LONG)(-1 * size * zoomRatio * fontRatio); logFont.lfQuality = fontRender; logFont.lfWeight = fontWeight; m_FontRender = fontRender; if (face.GetLength() < 32) { wsprintf(logFont.lfFaceName, _T("%s"), (LPCTSTR)face); } else { wsprintf(logFont.lfFaceName, _T("")); } m_Font.DeleteObject(); m_Font.CreateFontIndirect(&logFont); SetFont(&m_Font); logFont.lfHeight = (LONG)(-1 * sizeToolTip * zoomRatio); m_FontToolTip.DeleteObject(); m_FontToolTip.CreateFontIndirect(&logFont); if (! m_bHighContrast) { m_TextColor = textColor; m_TextColorSelected = textColorSelected; } if (m_ToolTip.m_hWnd != NULL) { m_ToolTip.SetFont(&m_FontToolTip); } } //------------------------------------------------ // Mouse //------------------------------------------------ void CComboBoxFx::SetHandCursor(BOOL bHandCuror) { m_bHandCursor = bHandCuror; } void CComboBoxFx::OnMouseMove(UINT nFlags, CPoint point) { #if _MSC_VER <= 1310 typedef BOOL(WINAPI* Func_TrackMouseEvent)(LPTRACKMOUSEEVENT); static Func_TrackMouseEvent p_TrackMouseEvent = NULL; static BOOL bInit_TrackMouseEvent = FALSE; if (bInit_TrackMouseEvent && p_TrackMouseEvent == NULL) { return; // TrackMouseEvent is not available } else { HMODULE hModule = GetModuleHandle(_T("user32.dll")); if (hModule) { p_TrackMouseEvent = (Func_TrackMouseEvent)GetProcAddress(hModule, "TrackMouseEvent"); } } if (p_TrackMouseEvent != NULL) { TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) }; tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1; m_bTrackingNow = p_TrackMouseEvent(&tme); } bInit_TrackMouseEvent = TRUE; #else if (!m_bTrackingNow) { TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) }; tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1; m_bTrackingNow = _TrackMouseEvent(&tme); } #endif CComboBox::OnMouseMove(nFlags, point); } void CComboBoxFx::OnMouseHover(UINT nFlags, CPoint point) { #if _MSC_VER > 1310 CComboBox::OnMouseHover(nFlags, point); #endif m_bHover = TRUE; Invalidate(); } void CComboBoxFx::OnMouseLeave() { #if _MSC_VER > 1310 CComboBox::OnMouseLeave(); #endif m_bTrackingNow = FALSE; m_bHover = FALSE; Invalidate(); } void CComboBoxFx::OnSetfocus() { m_bFocas = TRUE; Invalidate(); } void CComboBoxFx::OnKillfocus() { m_bFocas = FALSE; Invalidate(); } BOOL CComboBoxFx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { HCURSOR hCursor = NULL; if (m_bHandCursor) { hCursor = AfxGetApp()->LoadStandardCursor(IDC_HAND); if (hCursor) { ::SetCursor(hCursor); } } else { hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW); if (hCursor) { ::SetCursor(hCursor); } } return TRUE; } //------------------------------------------------ // ToolTip //------------------------------------------------ void CComboBoxFx::SetToolTipText(LPCTSTR text) { if (text == NULL) { return; } InitToolTip(); m_ToolTipText = text; if (m_ToolTip.GetToolCount() == 0) { CRect rect; GetClientRect(rect); m_ToolTip.AddTool(this, m_ToolTipText, rect, 1); } else { m_ToolTip.UpdateTipText(m_ToolTipText, this, 1); } SetToolTipActivate(TRUE); } void CComboBoxFx::SetToolTipActivate(BOOL bActivate) { if (m_ToolTip.GetToolCount() == 0) { return; } m_ToolTip.Activate(bActivate); } void CComboBoxFx::SetToolTipWindowText(LPCTSTR pText) { SetToolTipText(pText); SetWindowText(pText); } CString CComboBoxFx::GetToolTipText() { return m_ToolTipText; } void CComboBoxFx::InitToolTip() { if (m_ToolTip.m_hWnd == NULL) { m_ToolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOANIMATE | TTS_NOFADE); m_ToolTip.Activate(FALSE); m_ToolTip.SetFont(&m_FontToolTip); m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 1024); m_ToolTip.SetDelayTime(TTDT_AUTOPOP, 8000); m_ToolTip.SetDelayTime(TTDT_INITIAL, 500); m_ToolTip.SetDelayTime(TTDT_RESHOW, 100); } } BOOL CComboBoxFx::PreTranslateMessage(MSG* pMsg) { InitToolTip(); m_ToolTip.RelayEvent(pMsg); return CComboBox::PreTranslateMessage(pMsg); }