www.pudn.com > CCePngButtonST_Test.rar > CePngBtnST.cpp
#include "stdafx.h" #include "CePngBtnST.h" #include#include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // Mask for control's type #ifndef WM_MOUSELEAVE #define WM_MOUSELEAVE 0x02A3 #endif #ifndef DestroyCursor #define DestroyCursor DestroyIcon #endif #define BS_TYPEMASK 0x0000000FL HBRUSH GetBkBrush( HWND hWnd, UINT nID, HBITMAP hBmBk ); CCePngButtonST::CCePngButtonST() { m_bIsPressed = FALSE; m_bIsFocused = FALSE; m_bIsDisabled = FALSE; m_bMouseOnButton = FALSE; FreeResources(FALSE); // Default type is "flat" button m_bIsFlat = TRUE; // Button will be tracked also if when the window is inactive (like Internet Explorer) m_bAlwaysTrack = TRUE; // By default draw border in "flat" button m_bDrawBorder = TRUE; // By default icon is aligned horizontally m_byAlign = ST_ALIGN_HORIZ; // By default, for "flat" button, don't draw the focus rect m_bDrawFlatFocus = FALSE; // By default the button is not the default button m_bIsDefault = FALSE; // Invalid value, since type still unknown m_nTypeStyle = BS_TYPEMASK; // By default the button is not a checkbox m_bIsCheckBox = FALSE; m_nCheck = 0; // Set default colors SetDefaultColors(FALSE); // No URL defined SetURL(NULL); // No cursor defined m_hCursor = NULL; m_hOldCursor = NULL; // No timer defined m_nTimerId = 0; // No associated menu m_hMenu = NULL; m_hParentWndMenu = NULL; m_bMenuDisplayed = FALSE; // transp CRef m_transpCREF = RGB(255,255,255); //IImagingFactory *pIImgFactory; pIImgFactory = NULL; } CCePngButtonST::~CCePngButtonST() { FreeResources(); // Restore old cursor (if any) if (m_hOldCursor) ::SetCursor(m_hOldCursor); // Destroy the cursor (if any) if (m_hCursor) ::DestroyCursor(m_hCursor); // Destroy the menu (if any) if (m_hMenu) ::DestroyMenu(m_hMenu); //free(pIImgFactory); } BEGIN_MESSAGE_MAP(CCePngButtonST, CButton) //{{AFX_MSG_MAP(CCeButtonST) ON_WM_MOUSEMOVE() ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked) ON_WM_ENABLE() ON_WM_GETDLGCODE() ON_WM_CTLCOLOR() ON_WM_DESTROY() ON_WM_KILLFOCUS() ON_WM_ACTIVATE() ON_WM_CANCELMODE() ON_WM_DRAWITEM() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP //ON_WM_CAPTURECHANGED() ON_WM_SETCURSOR() ON_MESSAGE(BM_SETSTYLE, OnSetStyle) ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) END_MESSAGE_MAP() void CCePngButtonST::FreeResources(BOOL bCheckForNULL) { if (bCheckForNULL) { // Destroy icons // Note: the following lines MUST be here! even if // BoundChecker says they are unnecessary! if (m_csIcons[0].hIcon) ::DestroyIcon(m_csIcons[0].hIcon); if (m_csIcons[1].hIcon) ::DestroyIcon(m_csIcons[1].hIcon); if (m_csIcons[2].hIcon) ::DestroyIcon(m_csIcons[2].hIcon); } // if memset(&m_csIcons, 0, sizeof(m_csIcons)); memset(&m_csBitmaps, 0, sizeof(m_csBitmaps)); memset(&m_csImages, 0, sizeof(m_csImages)); } // End of FreeResources void CCePngButtonST::PreSubclassWindow() { UINT nBS; nBS = GetButtonStyle(); // Set initial control type m_nTypeStyle = nBS & BS_TYPEMASK; // Check if this is a checkbox if (nBS & BS_CHECKBOX) m_bIsCheckBox = TRUE; // Set initial default state flag if (m_nTypeStyle == BS_DEFPUSHBUTTON) { // Set default state for a default button m_bIsDefault = TRUE; // Adjust style for default button m_nTypeStyle = BS_PUSHBUTTON; } // If // You should not set the Owner Draw before this call // (don't use the resource editor "Owner Draw" or // ModifyStyle(0, BS_OWNERDRAW) before calling PreSubclassWindow() ) ASSERT(m_nTypeStyle != BS_OWNERDRAW); // Switch to owner-draw ModifyStyle(BS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED); CButton::PreSubclassWindow(); } // End of PreSubclassWindow void CCePngButtonST::OnDestroy() { // Kill timer if (m_nTimerId) KillTimer(m_nTimerId); m_nTimerId = 0; CButton::OnDestroy(); } // End of OnDestroy UINT CCePngButtonST::OnGetDlgCode() { UINT nCode = CButton::OnGetDlgCode(); // tell the system if we want default state handling // (losing default state always allowed) nCode |= (m_bIsDefault ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON); return nCode; } // End of OnGetDlgCode LRESULT CCePngButtonST::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_LBUTTONDBLCLK) { message = WM_LBUTTONDOWN; } // if return CButton::DefWindowProc(message, wParam, lParam); } // End of DefWindowProc HBRUSH CCePngButtonST::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { return (HBRUSH)::GetStockObject(NULL_BRUSH); } // End of CtlColor LRESULT CCePngButtonST::OnSetStyle(WPARAM wParam, LPARAM lParam) { UINT nNewType = (wParam & BS_TYPEMASK); // Update default state flag if (nNewType == BS_DEFPUSHBUTTON) { m_bIsDefault = TRUE; } // if else if (nNewType == BS_PUSHBUTTON) { // Losing default state always allowed m_bIsDefault = FALSE; } // if // Can't change control type after owner-draw is set. // Let the system process changes to other style bits // and redrawing, while keeping owner-draw style return DefWindowProc(BM_SETSTYLE, (wParam & ~BS_TYPEMASK) | BS_OWNERDRAW, lParam); } // End of OnSetStyle void CCePngButtonST::OnEnable(BOOL bEnable) { CButton::OnEnable(bEnable); if (bEnable == FALSE) { CWnd* pWnd = GetParent()->GetNextDlgTabItem(this); if (pWnd) pWnd->SetFocus(); else GetParent()->SetFocus(); CancelHover(); } // if } // End of OnEnable void CCePngButtonST::OnKillFocus(CWnd* pNewWnd) { CButton::OnKillFocus(pNewWnd); CancelHover(); } // End of OnKillFocus void CCePngButtonST::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CButton::OnActivate(nState, pWndOther, bMinimized); if (nState == WA_INACTIVE) CancelHover(); } // End of OnActivate void CCePngButtonST::OnCancelMode() { CButton::OnCancelMode(); CancelHover(); } // End of OnCancelMode void CCePngButtonST::OnLButtonDown(UINT nFlags, CPoint point) { SetState(TRUE); #if defined(_WIN32_WCE_PSPC) && (_WIN32_WCE >= 300) SHRecognizeGesture(point); #endif // _WIN32_WCE_PSPC Default(); //CButton::OnLButtonDown(nFlags, point); } // End of OnLButtonDown void CCePngButtonST::CancelHover() { // Only for flat buttons if (m_bIsFlat) { // Kill timer (if active) if (m_nTimerId) KillTimer(m_nTimerId); m_nTimerId = 0; if (m_bMouseOnButton) { // Restore old cursor (if any) if (m_hOldCursor) { ::SetCursor(m_hOldCursor); m_hOldCursor = NULL; } // if m_bMouseOnButton = FALSE; Invalidate(); } // if } // if } // End of CancelHover void CCePngButtonST::OnMouseMove(UINT nFlags, CPoint point) { CWnd* wndUnderMouse = NULL; CWnd* wndActive = this; CButton::OnMouseMove(nFlags, point); ClientToScreen(&point); wndUnderMouse = WindowFromPoint(point); // If the mouse enter the button with the left button pressed then do nothing if (nFlags & MK_LBUTTON && m_bMouseOnButton == FALSE) return; // If our button is not flat then do nothing if (m_bIsFlat == FALSE) return; if (m_bAlwaysTrack == FALSE) wndActive = GetActiveWindow(); if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive) { if (!m_bMouseOnButton) { m_bMouseOnButton = TRUE; Invalidate(); ASSERT(m_nTimerId == 0); m_nTimerId = SetTimer(1, 50, TimerProc); } // if } //else CancelHover(); } // End of OnMouseMove // Handler for WM_MOUSELEAVE LRESULT CCePngButtonST::OnMouseLeave(WPARAM wParam, LPARAM lParam) { CancelHover(); return 0; } // End of OnMouseLeave BOOL CCePngButtonST::OnClicked() { if (m_bIsCheckBox) { m_nCheck = !m_nCheck; Invalidate(); } // if else { // Handle the menu (if any) if (m_hMenu) { HMENU hSubMenu = NULL; CRect rWnd; hSubMenu = ::GetSubMenu(m_hMenu, 0); GetWindowRect(rWnd); m_bMenuDisplayed = TRUE; Invalidate(); ::TrackPopupMenuEx( hSubMenu, #ifdef UNDER_CE TPM_LEFTALIGN, #else TPM_LEFTALIGN | TPM_LEFTBUTTON, #endif rWnd.left, rWnd.bottom, m_hParentWndMenu, NULL); m_bMenuDisplayed = FALSE; Invalidate(); } // if else { // Handle the URL (if any) if (_tcslen(m_szURL) > 0) { SHELLEXECUTEINFO csSEI; memset(&csSEI, 0, sizeof(csSEI)); csSEI.cbSize = sizeof(SHELLEXECUTEINFO); csSEI.fMask = SEE_MASK_FLAG_NO_UI; csSEI.lpVerb = _T("open"); csSEI.lpFile = m_szURL; csSEI.nShow = SW_SHOWMAXIMIZED; ::ShellExecuteEx(&csSEI); } // if } // else } // else return FALSE; } // End of OnClicked void CCePngButtonST::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CDC* pDC = CDC::FromHandle(lpDIS->hDC); // Checkbox? if (m_bIsCheckBox) { m_bIsPressed = (lpDIS->itemState & ODS_SELECTED) || (m_nCheck != 0); } // if else // Normal button OR other button style ... { m_bIsPressed = (lpDIS->itemState & ODS_SELECTED); // If there is a menu and it's displayed, draw the button as pressed if (m_hMenu && m_bMenuDisplayed) m_bIsPressed = TRUE; } // else m_bIsFocused = (lpDIS->itemState & ODS_FOCUS); m_bIsDisabled = (lpDIS->itemState & ODS_DISABLED); CRect itemRect = lpDIS->rcItem; pDC->SetBkMode(TRANSPARENT); if (m_bIsFlat == FALSE) { if (m_bIsFocused || m_bIsDefault) { CBrush br(RGB(0,0,0)); pDC->FrameRect(&itemRect, &br); itemRect.DeflateRect(1, 1); } // if } // if // Prepare draw... paint button background OnDrawBackground(pDC, &itemRect); // Paint button border //if (!m_bIsFlat || (m_bIsFlat && m_bDrawBorder)) // OnDrawBorder(pDC, &itemRect); // Read the button's title TCHAR szTitle[256]; GetWindowText(szTitle, sizeof(szTitle)/sizeof(TCHAR)); CRect captionRect = lpDIS->rcItem; /* Draw the icon if (m_csIcons[0].hIcon) { DrawTheIcon(pDC, _tcslen(szTitle), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled); } // Draw the bitmap if (m_csBitmaps[0].hBitmap) { DrawTheBitmap(lpDIS->hDC, _tcslen(szTitle), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled); } */ // Draw the image if (m_csImages[0].pIImage) { DrawTheImage(lpDIS->hDC, _tcslen(szTitle), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled); } // Write the button title (if any) if (_tcslen(szTitle)) { // Draw the button's title // If button is pressed then "press" title also if (m_bIsPressed && m_bIsCheckBox == FALSE && m_byAlign != ST_ALIGN_CENTER )//add && m_byAlign != ST_ALIGN_CENTER for press static button not move captionRect.OffsetRect(1, 1); // ONLY FOR DEBUG //CBrush brBtnShadow(RGB(255, 0, 0)); //pDC->FrameRect(&captionRect, &brBtnShadow); // Center text CRect centerRect = captionRect; pDC->DrawText(szTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT); captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2); /* RFU captionRect.OffsetRect(0, (centerRect.Height() - captionRect.Height())/2); captionRect.OffsetRect((centerRect.Width() - captionRect.Width())-4, (centerRect.Height() - captionRect.Height())/2); */ pDC->SetBkMode(TRANSPARENT); /* pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), szTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), TRUE, 0, (CBrush*)NULL); */ if (m_bIsDisabled) { captionRect.OffsetRect(1, 1); pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT)); pDC->DrawText(szTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER); captionRect.OffsetRect(-1, -1); pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW)); //pDC->SetTextColor(RGB(0,0,0));//modify and add : use this disable button for static text. pDC->DrawText(szTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER); } // if else { if (m_bMouseOnButton || m_bIsPressed) { pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_IN]); pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_IN]); } // if else { pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_OUT]); pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_OUT]); } // else pDC->DrawText(szTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER); } // if } // if if (m_bIsFlat == FALSE || (m_bIsFlat && m_bDrawFlatFocus)) { // Draw the focus rect if (m_bIsFocused) { CRect focusRect = itemRect; focusRect.DeflateRect(3, 3); pDC->DrawFocusRect(&focusRect); } // if } // if } // End of DrawItem // // Parameters: // [IN] bHasTitle // TRUE if the button has a text // [IN] rpItem // A pointer to a RECT structure indicating the allowed paint area // [IN/OUT]rpTitle // A pointer to a CRect object indicating the paint area reserved for the // text. This structure will be modified if necessary. // [IN] bIsPressed // TRUE if the button is currently pressed // [IN] dwWidth // Width of the image (icon or bitmap) // [IN] dwHeight // Height of the image (icon or bitmap) // [OUT] rpImage // A pointer to a CRect object that will receive the area available to the image // void CCePngButtonST::PrepareImageRect(BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, CRect* rpImage) { CRect rBtn; rpImage->CopyRect(rpItem); switch (m_byAlign) { case ST_ALIGN_HORIZ: if (bHasTitle == FALSE) { // Center image horizontally rpImage->left += ((rpImage->Width() - dwWidth)/2); } else { // Image must be placed just inside the focus rect rpImage->left += 3; rpTitle->left += dwWidth + 3; } // Center image vertically rpImage->top += ((rpImage->Height() - dwHeight)/2); break; case ST_ALIGN_HORIZ_RIGHT: GetClientRect(&rBtn); if (bHasTitle == FALSE) { // Center image horizontally rpImage->left += ((rpImage->Width() - dwWidth)/2); } else { // Image must be placed just inside the focus rect rpTitle->right = rpTitle->Width() - dwWidth - 3; rpTitle->left = 3; rpImage->left = rBtn.right - dwWidth - 3; // Center image vertically rpImage->top += ((rpImage->Height() - dwHeight)/2); } break; case ST_ALIGN_VERT: // Center image horizontally rpImage->left += ((rpImage->Width() - dwWidth)/2); if (bHasTitle == FALSE) { // Center image vertically rpImage->top += ((rpImage->Height() - dwHeight)/2); } else { rpImage->top = 0;//modify from 3 rpTitle->top += dwHeight-14;//modify form dwHeight } break; case ST_ALIGN_CENTER: // Center image horizontally rpImage->left += ((rpImage->Width() - dwWidth)/2); if (bHasTitle == FALSE) { // Center image vertically rpImage->top += ((rpImage->Height() - dwHeight)/2); } else { rpImage->top = 0;//modify from 3 rpTitle->top += 0;//modify form dwHeight } break; } //add by fuxing 2008-7-26 rpImage->right = rpImage->left + dwWidth; rpImage->bottom = rpImage->top + dwHeight; // If button is pressed then press image also if (bIsPressed && m_bIsCheckBox == FALSE && m_byAlign != ST_ALIGN_CENTER)//add && m_byAlign != ST_ALIGN_CENTER for press static button not move rpImage->OffsetRect(1, 1); //rpImage->DeflateRect(1,1); } // End of PrepareImageRect void CCePngButtonST::DrawTheIcon(CDC* pDC, BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, BOOL bIsDisabled) { BYTE byIndex = 0; // Select the icon to use if (bIsDisabled) byIndex = (m_csIcons[2].hIcon == NULL ? 0 : 2); else { if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton))) byIndex = 0; else byIndex = (m_csIcons[1].hIcon == NULL ? 0 : 1); } // else CRect rImage; PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csIcons[byIndex].dwWidth, m_csIcons[byIndex].dwHeight, &rImage); // Ole'! pDC->DrawIcon(rImage.TopLeft(), m_csIcons[byIndex].hIcon); } // End of DrawTheIcon void CCePngButtonST::DrawTheBitmap(HDC h_destDC, BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, BOOL bIsDisabled) { BYTE byIndex = 0; CRect rImage; BITMAP bmp; HBITMAP hBmp; HDC hDC; // Select the icon to use // Select the icon to use if (bIsDisabled) byIndex = (m_csBitmaps[2].hBitmap == NULL ? 0 : 2); else { if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton))) byIndex = 0; else byIndex = (m_csBitmaps[1].hBitmap == NULL ? 0 : 1); } // else //GetClientRect(&cltRect); //hBmp = ::LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(byIndex)); hBmp = m_csBitmaps[byIndex].hBitmap; ::GetObject(hBmp, sizeof(bmp), &bmp); hDC = ::CreateCompatibleDC(NULL); SelectObject(hDC, hBmp); PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, &rImage); ::TransparentImage(h_destDC, rImage.left, rImage.top, rImage.Width(), rImage.Height(), hDC, 0, 0, rImage.Width(), rImage.Height(), m_transpCREF); //BLENDFUNCTION bf; //bf.AlphaFormat=0; //bf.BlendFlags=0; //bf.BlendOp=AC_SRC_OVER; //bf.SourceConstantAlpha=255;//ΝΈΓχΆΘ0~255 //::AlphaBlend(h_destDC, rImage.left, rImage.top, rImage.Width(), rImage.Height(), hDC, 0, 0, rImage.Width(), rImage.Height(), bf); ::DeleteObject(hBmp); ::DeleteDC(hDC); } // End of DrawTheBitmap void CCePngButtonST::DrawTheImage(HDC h_destDC, BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, BOOL bIsDisabled) { BYTE byIndex = 0; CRect rImage; // Select the image to use if (bIsDisabled) byIndex = (m_csImages[2].pIImage == NULL ? 1 : 2); else { if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed)))//|| m_bMouseOnButton byIndex = 0; else byIndex = (m_csImages[1].pIImage == NULL ? 0 : 1); } PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csImages[byIndex].dwWidth, m_csImages[byIndex].dwHeight, &rImage); m_csImages[byIndex].pIImage->Draw(h_destDC, rImage, NULL); } // End of DrawTheImage BOOL CCePngButtonST::ImageFromIDResource(UINT nID, LPCTSTR sTR, IImage** pIImage) { HINSTANCE hInst = AfxGetResourceHandle(); HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type if (!hRsrc) return FALSE; // load resource into memory DWORD len = SizeofResource(hInst, hRsrc); BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc); if (!lpRsrc) return FALSE; // Allocate global memory on which to create stream HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len); BYTE* pmem = (BYTE*)GlobalLock(m_hMem); memcpy(pmem,lpRsrc,len); IStream* pStream; CreateStreamOnHGlobal(m_hMem,FALSE,&pStream); // load from stream pIImgFactory->CreateImageFromStream(pStream, pIImage); // free/release stuff GlobalUnlock(m_hMem); pStream->Release(); FreeResource(lpRsrc); if(!pIImage) return FALSE; return TRUE; } // This function assigns icons to the button. // Any previous icon will be removed. // // Parameters: // [IN] nIconIn // ID number of the icon resource to show when the mouse is over the button. // Pass NULL to remove any icon from the button. // [IN] sizeIn // Size of the icon. // [IN] nIconOut // ID number of the icon resource to show when the mouse is outside the button. // Can be NULL. // [IN] sizeOut // Size of the icon. // [IN] nIconDis // ID number of the icon resource to show when the button is disabled. // Can be NULL. // [IN] sizeDis // Size of the icon. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetIcon(int nIconIn, CSize sizeIn, int nIconOut, CSize sizeOut, int nIconDis, CSize sizeDis) { HICON hIconIn = NULL; HICON hIconOut = NULL; HICON hIconDis = NULL; HINSTANCE hInstResource = NULL; // Find correct resource handle hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconIn), RT_GROUP_ICON); // Set icon when the mouse is IN the button hIconIn = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconIn), IMAGE_ICON, 0, 0, 0); // Set icon when the mouse is OUT the button if (nIconOut) hIconOut = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconOut), IMAGE_ICON, 0, 0, 0); // Set icon when the mouse is DISABLED if (nIconDis) hIconDis = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconDis), IMAGE_ICON, 0, 0, 0); return SetIcon(hIconIn, sizeIn, hIconOut, sizeOut, hIconDis, sizeDis); } // End of SetIcon // This function assigns icons to the button. // Any previous icon or bitmap will be removed. // // Parameters: // [IN] hIconIn // Handle fo the icon to show when the mouse is over the button. // Pass NULL to remove any icon from the button. // [IN] sizeIn // Size of the icon. // [IN] hIconOut // Handle to the icon to show when the mouse is outside the button. // Can be NULL. // [IN] sizeOut // Size of the icon. // [IN] hIconDis // ID number of the icon resource to show when the button is disabled. // Can be NULL. // [IN] sizeDis // Size of the icon. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetIcon(HICON hIconIn, CSize sizeIn, HICON hIconOut, CSize sizeOut, HICON hIconDis, CSize sizeDis) { // Free any loaded resource FreeResources(); if (hIconIn) { // Icon when mouse over button? m_csIcons[0].hIcon = hIconIn; // Get icon dimension m_csIcons[0].dwWidth = (DWORD)sizeIn.cx; m_csIcons[0].dwHeight = (DWORD)sizeIn.cy; // Icon when mouse outside button? if (hIconOut) { m_csIcons[1].hIcon = hIconOut; // Get icon dimension m_csIcons[1].dwWidth = (DWORD)sizeOut.cx; m_csIcons[1].dwHeight = (DWORD)sizeOut.cy; } // if // Icon when button disabled? if (hIconDis) { m_csIcons[2].hIcon = hIconDis; // Get icon dimension m_csIcons[2].dwWidth = (DWORD)sizeDis.cx; m_csIcons[2].dwHeight = (DWORD)sizeDis.cy; } // if } // if Invalidate(); return BTNST_OK; } // End of SetIcon // This function assigns bitmaps to the button. // Any previous bitmap will be removed. // // Parameters: // [IN] nBitmapIn // ID number of the icon resource to show when the mouse is over the button. // Pass NULL to remove any icon from the button. // [IN] sizeIn // Size of the icon. // [IN] nBitmapOut // ID number of the icon resource to show when the mouse is outside the button. // Can be NULL. // [IN] sizeOut // Size of the icon. // [IN] nBitmapDis // ID number of the icon resource to show when the button is disabled. // Can be NULL. // [IN] sizeDis // Size of the icon. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetBitmap(int nBitmapIn, CSize sizeIn, int nBitmapOut, CSize sizeOut, int nBitmapDis, CSize sizeDis) { HBITMAP hBitmapIn = NULL; HBITMAP hBitmapOut = NULL; HBITMAP hBitmapDis = NULL; HINSTANCE hInstResource = NULL; // Find correct resource handle hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmapIn), RT_BITMAP); // Set icon when the mouse is IN the button hBitmapIn = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapIn), IMAGE_BITMAP, 0, 0, 0); // Set icon when the mouse is OUT the button if (nBitmapOut) hBitmapOut = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapOut), IMAGE_BITMAP, 0, 0, 0); // Set icon when the mouse is DISABLED if (nBitmapDis) hBitmapDis = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapDis), IMAGE_BITMAP, 0, 0, 0); return SetBitmap(hBitmapIn, sizeIn, hBitmapOut, sizeOut, hBitmapDis, sizeDis); } // End of SetIcon // This function assigns icons to the button. // Any previous icon or bitmap will be removed. // // Parameters: // [IN] hBitmapIn // Handle fo the icon to show when the mouse is over the button. // Pass NULL to remove any icon from the button. // [IN] sizeIn // Size of the bitmap. // [IN] hBitmapOut // Handle to the icon to show when the mouse is outside the button. // Can be NULL. // [IN] sizeOut // Size of the bitmap. // [IN] hBitmapDis // ID number of the icon resource to show when the button is disabled. // Can be NULL. // [IN] sizeDis // Size of the bitmap. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetBitmap(HBITMAP hBitmapIn, CSize sizeIn, HBITMAP hBitmapOut, CSize sizeOut, HBITMAP hBitmapDis, CSize sizeDis) { // Free any loaded resource FreeResources(); if (hBitmapIn) { // Icon when mouse over button? m_csBitmaps[0].hBitmap = hBitmapIn; // Get icon dimension m_csBitmaps[0].dwWidth = (DWORD)sizeIn.cx; m_csBitmaps[0].dwHeight = (DWORD)sizeIn.cy; // Icon when mouse outside button? if (hBitmapOut) { m_csBitmaps[1].hBitmap = hBitmapOut; // Get icon dimension m_csBitmaps[1].dwWidth = (DWORD)sizeOut.cx; m_csBitmaps[1].dwHeight = (DWORD)sizeOut.cy; } // if // Icon when button disabled? if (hBitmapDis) { m_csBitmaps[2].hBitmap = hBitmapDis; // Get icon dimension m_csBitmaps[2].dwWidth = (DWORD)sizeDis.cx; m_csBitmaps[2].dwHeight = (DWORD)sizeDis.cy; } // if } // if Invalidate(); return BTNST_OK; } // End of SetBitmap DWORD CCePngButtonST::SetImage(int nBkgndID, int nImageIn, CSize sizeIn, int nImageOut, CSize sizeOut, int nImageDis, CSize sizeDis) { IImage* pImageIn = NULL; IImage* pImageOut = NULL; IImage* pImageDis = NULL; nBkgndImageID = nBkgndID; CoInitializeEx(NULL,COINIT_MULTITHREADED); //initialize com if(!SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory,(void **)&pIImgFactory))) { return BTNST_FAILEDMASK; } // Set image when the mouse is IN the button ImageFromIDResource(nImageIn, L"PNG", &pImageIn); // Set image when the mouse is OUT the button if (nImageOut) ImageFromIDResource(nImageOut, L"PNG", &pImageOut); // Set image when the mouse is DISABLED if (nImageDis) ImageFromIDResource(nImageDis, L"PNG", &pImageDis); return SetImage(pImageIn, sizeIn, pImageOut, sizeOut, pImageDis, sizeDis); } // End of SetImage DWORD CCePngButtonST::SetImage(IImage* pIImageIn, CSize sizeIn, IImage* pIImageOut, CSize sizeOut, IImage* pIImageDis, CSize sizeDis) { // Free any loaded resource FreeResources(); if (pIImageIn) { // Image when mouse over button? m_csImages[0].pIImage = pIImageIn; // Get image dimension m_csImages[0].dwWidth = (DWORD)sizeIn.cx; m_csImages[0].dwHeight = (DWORD)sizeIn.cy; // Image when mouse outside button? if (pIImageOut) { m_csImages[1].pIImage = pIImageOut; // Get image dimension m_csImages[1].dwWidth = (DWORD)sizeOut.cx; m_csImages[1].dwHeight = (DWORD)sizeOut.cy; } // if // Image when button disabled? if (pIImageDis) { m_csImages[2].pIImage = pIImageDis; // Get icon dimension m_csImages[2].dwWidth = (DWORD)sizeDis.cx; m_csImages[2].dwHeight = (DWORD)sizeDis.cy; } // if } // if Invalidate(); return BTNST_OK; } // End of SetImage // This functions sets the button to have a standard or flat style. // // Parameters: // [IN] bFlat // If TRUE the button will have a flat style, else // will have a standard style. // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetFlat(BOOL bFlat, BOOL bRepaint) { m_bIsFlat = bFlat; if (bRepaint) Invalidate(); return BTNST_OK; } // End of SetFlat // This function sets the alignment type between icon/bitmap and text. // // Parameters: // [IN] byAlign // Alignment type. Can be one of the following values: // ST_ALIGN_HORIZ Icon/bitmap on the left, text on the right // ST_ALIGN_VERT Icon/bitmap on the top, text on the bottom // ST_ALIGN_HORIZ_RIGHT Icon/bitmap on the right, text on the left // By default, CButtonST buttons have ST_ALIGN_HORIZ alignment. // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // BTNST_INVALIDALIGN // Alignment type not supported. // DWORD CCePngButtonST::SetAlign(BYTE byAlign, BOOL bRepaint) { switch (byAlign) { case ST_ALIGN_HORIZ: case ST_ALIGN_HORIZ_RIGHT: case ST_ALIGN_VERT: case ST_ALIGN_CENTER: m_byAlign = byAlign; if (bRepaint) Invalidate(); return BTNST_OK; break; } // switch return BTNST_INVALIDALIGN; } // End of SetAlign // This function sets the state of the checkbox. // If the button is not a checkbox, this function has no meaning. // // Parameters: // [IN] nCheck // 1 to check the checkbox. // 0 to un-check the checkbox. // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetCheck(int nCheck, BOOL bRepaint) { if (m_bIsCheckBox) { if (nCheck == 0) m_nCheck = 0; else m_nCheck = 1; if (bRepaint) Invalidate(); } // if return BTNST_OK; } // End of SetCheck // This function returns the current state of the checkbox. // If the button is not a checkbox, this function has no meaning. // // Return value: // The current state of the checkbox. // 1 if checked. // 0 if not checked or the button is not a checkbox. // int CCePngButtonST::GetCheck() { return m_nCheck; } // End of GetCheck // This function sets all colors to a default value. // // Parameters: // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetDefaultColors(BOOL bRepaint) { m_crColors[BTNST_COLOR_BK_IN] = ::GetSysColor(COLOR_BTNFACE); m_crColors[BTNST_COLOR_FG_IN] = ::GetSysColor(COLOR_BTNTEXT); m_crColors[BTNST_COLOR_BK_OUT] = ::GetSysColor(COLOR_BTNFACE); m_crColors[BTNST_COLOR_FG_OUT] = ::GetSysColor(COLOR_BTNTEXT); m_crColors[BTNST_COLOR_BK_FOCUS] = ::GetSysColor(COLOR_BTNFACE); m_crColors[BTNST_COLOR_FG_FOCUS] = ::GetSysColor(COLOR_BTNTEXT); if (bRepaint) Invalidate(); return BTNST_OK; } // End of SetDefaultColors // This function sets the color to use for a particular state. // // Parameters: // [IN] byColorIndex // Index of the color to set. Can be one of the following values: // BTNST_COLOR_BK_IN Background color when mouse is over the button // BTNST_COLOR_FG_IN Text color when mouse is over the button // BTNST_COLOR_BK_OUT Background color when mouse is outside the button // BTNST_COLOR_FG_OUT Text color when mouse is outside the button // BTNST_COLOR_BK_FOCUS Background color when the button is focused // BTNST_COLOR_FG_FOCUS Text color when the button is focused // [IN] crColor // New color. // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // BTNST_INVALIDINDEX // Invalid color index. // DWORD CCePngButtonST::SetColor(BYTE byColorIndex, COLORREF crColor, BOOL bRepaint) { if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX; // Set new color m_crColors[byColorIndex] = crColor; if (bRepaint) Invalidate(); return BTNST_OK; } // End of SetColor // This functions returns the color used for a particular state. // // Parameters: // [IN] byColorIndex // Index of the color to get. Can be one of the following values: // BTNST_COLOR_BK_IN Background color when mouse is over the button // BTNST_COLOR_FG_IN Text color when mouse is over the button // BTNST_COLOR_BK_OUT Background color when mouse is outside the button // BTNST_COLOR_FG_OUT Text color when mouse is outside the button // BTNST_COLOR_BK_FOCUS Background color when the button is focused // BTNST_COLOR_FG_FOCUS Text color when the button is focused // [OUT] crpColor // A pointer to a COLORREF that will receive the color. // // Return value: // BTNST_OK // Function executed successfully. // BTNST_INVALIDINDEX // Invalid color index. // DWORD CCePngButtonST::GetColor(BYTE byColorIndex, COLORREF* crpColor) { if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX; // Get color *crpColor = m_crColors[byColorIndex]; return BTNST_OK; } // End of GetColor // This function sets the hilight logic for the button. // Applies only to flat buttons. // // Parameters: // [IN] bAlwaysTrack // If TRUE the button will be hilighted even if the window that owns it, is // not the active window. // If FALSE the button will be hilighted only if the window that owns it, // is the active window. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetAlwaysTrack(BOOL bAlwaysTrack) { m_bAlwaysTrack = bAlwaysTrack; return BTNST_OK; } // End of SetAlwaysTrack // This function sets the cursor to be used when the mouse is over the button. // // Parameters: // [IN] nCursorId // ID number of the cursor resource. // Pass NULL to remove a previously loaded cursor. // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // BTNST_INVALIDRESOURCE // Failed loading the specified resource. // DWORD CCePngButtonST::SetBtnCursor(int nCursorId, BOOL bRepaint) { HINSTANCE hInstResource = NULL; // Restore old cursor (if any) if (m_hOldCursor) ::SetCursor(m_hOldCursor); // Destroy the cursor (if any) if (m_hCursor) ::DestroyCursor(m_hCursor); m_hCursor = NULL; m_hOldCursor = NULL; // Load cursor if (nCursorId) { hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId), RT_GROUP_CURSOR); // Load cursor resource m_hCursor = (HCURSOR)::LoadImage(hInstResource, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0); // Repaint the button if (bRepaint) Invalidate(); // If something wrong if (m_hCursor == NULL) return BTNST_INVALIDRESOURCE; } // if return BTNST_OK; } // End of SetBtnCursor // This function sets if the button border must be drawn. // Applies only to flat buttons. // // Parameters: // [IN] bDrawBorder // If TRUE the border will be drawn. // [IN] bRepaint // If TRUE the button will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::DrawBorder(BOOL bDrawBorder, BOOL bRepaint) { m_bDrawBorder = bDrawBorder; // Repaint the button if (bRepaint) Invalidate(); return BTNST_OK; } // End of DrawBorder // This function sets if the focus rectangle must be drawn for flat buttons. // // Parameters: // [IN] bDrawFlatFocus // If TRUE the focus rectangle will be drawn also for flat buttons. // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::DrawFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint) { m_bDrawFlatFocus = bDrawFlatFocus; // Repaint the button if (bRepaint) Invalidate(); return BTNST_OK; } // End of DrawFlatFocus // This function returns if the button is the default button. // // Return value: // TRUE // The button is the default button. // FALSE // The button is not the default button. // BOOL CCePngButtonST::GetDefault() { return m_bIsDefault; } // End of GetDefault // This function sets the URL that will be opened when the button is clicked. // // Parameters: // [IN] lpszURL // Pointer to a null-terminated string that contains the URL. // Pass NULL to remove any previously specified URL. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::SetURL(LPCTSTR lpszURL) { // Remove any existing URL memset(m_szURL, 0, sizeof(m_szURL)); if (lpszURL) { // Store the URL _tcsncpy(m_szURL, lpszURL, _MAX_PATH); } // if return BTNST_OK; } // End of SetURL BOOL CCePngButtonST::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { HCURSOR hOldCursor; // If a cursor was specified then use it! if (m_hCursor != NULL) { hOldCursor = ::SetCursor(m_hCursor); // Store old cursor if (!m_hOldCursor) m_hOldCursor = hOldCursor; return TRUE; } // if return CButton::OnSetCursor(pWnd, nHitTest, message); } // End of OnSetCursor // This function associates a menu to the button. // The menu will be displayed clicking the button. // // Parameters: // [IN] nMenu // ID number of the menu resource. // Pass NULL to remove any menu from the button. // [IN] hParentWnd // Handle to the window that owns the menu. // This window receives all messages from the menu. // [IN] bRepaint // If TRUE the control will be repainted. // // Return value: // BTNST_OK // Function executed successfully. // BTNST_INVALIDRESOURCE // Failed loading the specified resource. // DWORD CCePngButtonST::SetMenu(UINT nMenu, HWND hParentWnd, BOOL bRepaint) { HINSTANCE hInstResource = NULL; // Destroy any previous menu if (m_hMenu) { ::DestroyMenu(m_hMenu); m_hMenu = NULL; m_hParentWndMenu = NULL; m_bMenuDisplayed = FALSE; } // if // Load menu if (nMenu) { // Find correct resource handle hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nMenu), RT_MENU); // Load menu resource m_hMenu = ::LoadMenu(hInstResource, MAKEINTRESOURCE(nMenu)); m_hParentWndMenu = hParentWnd; // If something wrong if (m_hMenu == NULL) return BTNST_INVALIDRESOURCE; } // if // Repaint the button if (bRepaint) Invalidate(); return BTNST_OK; } // End of SetMenu // This function is called every time the button background needs to be painted. // // Parameters: // [IN] pDC // Pointer to a CDC object that indicates the device context. // [IN] pRect // Pointer to a CRect object that indicates the bounds of the // area to be painted. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::OnDrawBackground(CDC* pDC, LPCRECT pRect) { /* COLORREF crColor; if (m_bMouseOnButton || m_bIsPressed) crColor = m_crColors[BTNST_COLOR_BK_IN]; else { if (m_bIsFocused) crColor = m_crColors[BTNST_COLOR_BK_FOCUS]; else crColor = m_crColors[BTNST_COLOR_BK_OUT]; } // else CBrush brBackground(crColor); pDC->FillRect(pRect, &brBackground); */ //modify by starefu 2008-7-25 HINSTANCE hBgInstResource = NULL; hBgInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBkgndImageID), RT_BITMAP); HBITMAP m_hBmBkgnd = ::LoadBitmap(hBgInstResource, MAKEINTRESOURCE(nBkgndImageID)); UINT nCtlID = ::GetDlgCtrlID(this->m_hWnd); HBRUSH m_hBrushCtl = GetBkBrush( this->GetParent()->m_hWnd, nCtlID, m_hBmBkgnd ); pDC->FillRect(pRect,CBrush::FromHandle(m_hBrushCtl)); return BTNST_OK; } // End of OnDrawBackground // This function is called every time the button border needs to be painted. // // Parameters: // [IN] pDC // Pointer to a CDC object that indicates the device context. // [IN] pRect // Pointer to a CRect object that indicates the bounds of the // area to be painted. // // Return value: // BTNST_OK // Function executed successfully. // DWORD CCePngButtonST::OnDrawBorder(CDC* pDC, LPCRECT pRect) { if (m_bIsPressed) pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHIGHLIGHT)); else if (m_bIsFlat == FALSE || (m_bIsFlat && m_bMouseOnButton)) pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW)); return BTNST_OK; } // End of OnDrawBorder void CALLBACK CCePngButtonST::TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { POINT csPos; RECT csRect; ::GetCursorPos(&csPos); ::ScreenToClient(hwnd, &csPos); ::GetClientRect(hwnd, &csRect); if (!::PtInRect(&csRect, csPos)) { ::PostMessage(hwnd, WM_MOUSELEAVE, 0, 0); //m_bMouseOnButton = FALSE; //Invalidate(); } // if } // End of TimerProc #undef BS_TYPEMASK #undef WM_MOUSELEAVE /* void CCePngButtonST::OnCaptureChanged(CWnd *pWnd) { if (m_bMouseOnButton) { ReleaseCapture(); Invalidate(); } // if CButton::OnCaptureChanged(pWnd); } // End of OnCaptureChanged */ //add by starefu or fuxing to transparent the button bkgnd 2008-7-26 #define _X(x) (x.left) #define _Y(x) (x.top) #define _W(x) (x.right - x.left) #define _H(x) (x.bottom - x.top) //************************************************************************************** // // GetBkBrush( HWND hWnd, UINT nID, HBITMAP hBmBk ) // // Creates Background brush for the control specified by nID // according to its position in the parent dialog window. // // hWnd [in]: Handle to the parent window // nID [in]: Control ID // hBmBk [in]: Bitmap handle of the parent dialog's background image // // //************************************************************************************** HBRUSH GetBkBrush( HWND hWnd, UINT nID, HBITMAP hBmBk ) { HWND hWndCtrl; hWndCtrl = ::GetDlgItem( hWnd, nID ); HBRUSH hBrushCtrl = NULL; if( NULL != hWndCtrl ) { RECT rcCtrl; ::GetWindowRect( hWndCtrl, &rcCtrl ); ::ScreenToClient(hWnd, (LPPOINT)&rcCtrl); ::ScreenToClient(hWnd, ((LPPOINT)&rcCtrl)+1); HDC hDC = ::GetDC(hWnd); HDC hMemDCBk = CreateCompatibleDC( hDC ); HDC hMemDCCtrl = CreateCompatibleDC( hDC ); HBITMAP hBmCtrl = CreateCompatibleBitmap( hDC, _W(rcCtrl), _H(rcCtrl) ); HBITMAP hBmOldBk; HBITMAP hBmOldCtrl; hBmOldBk = (HBITMAP) ::SelectObject( hMemDCBk, hBmBk ); hBmOldCtrl = (HBITMAP) ::SelectObject( hMemDCCtrl, hBmCtrl ); ::BitBlt( hMemDCCtrl, 0, 0, _W(rcCtrl), _H(rcCtrl), hMemDCBk, _X(rcCtrl), _Y(rcCtrl), SRCCOPY ); ::SelectObject(hMemDCCtrl, hBmOldCtrl ); ::SelectObject(hMemDCBk, hBmOldBk ); hBrushCtrl = ::CreatePatternBrush( hBmCtrl ); DeleteObject( hBmCtrl ); ::DeleteDC( hMemDCBk ); ::DeleteDC( hMemDCCtrl ); ::ReleaseDC( hWnd, hDC ); } return hBrushCtrl; }