X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c0ed460c2e7802793d591c84f3cfdbff159c5549..8def743e8fcd51ba3e68cb6b59154d3557e18f79:/src/msw/bmpbuttn.cpp?ds=inline diff --git a/src/msw/bmpbuttn.cpp b/src/msw/bmpbuttn.cpp index f21e4ff954..4eb6795442 100644 --- a/src/msw/bmpbuttn.cpp +++ b/src/msw/bmpbuttn.cpp @@ -21,14 +21,13 @@ #endif #ifndef WX_PRECOMP -#include "wx/bmpbuttn.h" + #include "wx/bmpbuttn.h" + #include "wx/log.h" #endif #include "wx/msw/private.h" -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton) -#endif #define BUTTON_HEIGHT_FACTOR (EDIT_CONTROL_FACTOR * 1.1) @@ -40,7 +39,10 @@ bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bit { m_buttonBitmap = bitmap; SetName(name); + +#if wxUSE_VALIDATORS SetValidator(validator); +#endif // wxUSE_VALIDATORS parent->AddChild(this); @@ -72,20 +74,25 @@ bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bit if ( height == -1 && bitmap.Ok()) height = bitmap.GetHeight() + 2*m_marginY; - HWND wx_button = - CreateWindowEx(0, "BUTTON", "", BS_OWNERDRAW | WS_TABSTOP | WS_CHILD, - 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId, - wxGetInstance(), NULL); - - m_hWnd = (WXHWND)wx_button; + m_hWnd = (WXHWND)CreateWindowEx + ( + 0, + wxT("BUTTON"), + wxT(""), + WS_VISIBLE | WS_TABSTOP | WS_CHILD | BS_OWNERDRAW , + 0, 0, 0, 0, + GetWinHwnd(parent), + (HMENU)m_windowId, + wxGetInstance(), + NULL + ); // Subclass again for purposes of dialog editing mode - SubclassWin((WXHWND)wx_button); + SubclassWin(m_hWnd); SetFont(parent->GetFont()) ; SetSize(x, y, width, height); - ShowWindow(wx_button, SW_SHOW); return TRUE; } @@ -97,13 +104,10 @@ void wxBitmapButton::SetBitmapLabel(const wxBitmap& bitmap) bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item) { - long style = GetWindowLong((HWND) GetHWND(), GWL_STYLE); #if defined(__WIN95__) + long style = GetWindowLong((HWND) GetHWND(), GWL_STYLE); if (style & BS_BITMAP) { - // Should we call Default() here? -// Default(); - // Let default procedure draw the bitmap, which is defined // in the Windows resource. return FALSE; @@ -112,53 +116,126 @@ bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item) LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) item; - wxBitmap* bitmap = &m_buttonBitmap; + // choose the bitmap to use depending on the buttons state + wxBitmap* bitmap; + + UINT state = lpDIS->itemState; + bool isSelected = (state & ODS_SELECTED) != 0; + if ( isSelected && m_buttonBitmapSelected.Ok() ) + bitmap = &m_buttonBitmapSelected; + else if ((state & ODS_FOCUS) && m_buttonBitmapFocus.Ok()) + bitmap = &m_buttonBitmapFocus; + else if ((state & ODS_DISABLED) && m_buttonBitmapDisabled.Ok()) + bitmap = &m_buttonBitmapDisabled; + else + bitmap = &m_buttonBitmap; - UINT state = lpDIS->itemState; - if ((state & ODS_SELECTED) && m_buttonBitmapSelected.Ok()) - bitmap = &m_buttonBitmapSelected; - else if ((state & ODS_FOCUS) && m_buttonBitmapFocus.Ok()) - bitmap = &m_buttonBitmapFocus; - else if ((state & ODS_DISABLED) && m_buttonBitmapDisabled.Ok()) - bitmap = &m_buttonBitmapDisabled; + if ( !bitmap->Ok() ) + return FALSE; - if ( !bitmap->Ok() ) - return FALSE; + // draw it on the memory DC + HDC hDC = lpDIS->hDC; + HDC memDC = ::CreateCompatibleDC(hDC); - HDC hDC = lpDIS->hDC; - HDC memDC = ::CreateCompatibleDC(hDC); + HBITMAP old = (HBITMAP) ::SelectObject(memDC, (HBITMAP) bitmap->GetHBITMAP()); - HBITMAP old = (HBITMAP) ::SelectObject(memDC, (HBITMAP) bitmap->GetHBITMAP()); + if (!old) + { + wxLogLastError(_T("SelectObject")); - if (!old) - return FALSE; + return FALSE; + } - int x = lpDIS->rcItem.left; - int y = lpDIS->rcItem.top; - int width = lpDIS->rcItem.right - x; - int height = lpDIS->rcItem.bottom - y; + int x = lpDIS->rcItem.left; + int y = lpDIS->rcItem.top; + int width = lpDIS->rcItem.right - x; + int height = lpDIS->rcItem.bottom - y; - // Draw the face, if auto-drawing - if ( GetWindowStyleFlag() & wxBU_AUTODRAW ) - DrawFace((WXHDC) hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right, lpDIS->rcItem.bottom, - ((state & ODS_SELECTED) == ODS_SELECTED)); + int wBmp = bitmap->GetWidth(), + hBmp = bitmap->GetHeight(); + + // Draw the face, if auto-drawing + bool autoDraw = (GetWindowStyleFlag() & wxBU_AUTODRAW) != 0; + if ( autoDraw ) + { + DrawFace((WXHDC) hDC, + lpDIS->rcItem.left, lpDIS->rcItem.top, + lpDIS->rcItem.right, lpDIS->rcItem.bottom, + isSelected); + } // Centre the bitmap in the control area - int x1 = (int) (x + ((width - bitmap->GetWidth()) / 2)); - int y1 = (int) (y + ((height - bitmap->GetHeight()) / 2)); + int x1 = x + (width - wBmp) / 2; + int y1 = y + (height - hBmp) / 2; - if ( (state & ODS_SELECTED) && (GetWindowStyleFlag() & wxBU_AUTODRAW) ) + if ( isSelected && autoDraw ) { - x1 ++; - y1 ++; + x1++; + y1++; } - ::BitBlt(hDC, x1, y1, bitmap->GetWidth(), bitmap->GetHeight(), memDC, 0, 0, SRCCOPY); + BOOL ok; - if ( (state & ODS_DISABLED) && (GetWindowStyleFlag() & wxBU_AUTODRAW) ) - DrawButtonDisable( (WXHDC) hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right, lpDIS->rcItem.bottom, TRUE ) ; - else if ( (state & ODS_FOCUS) && (GetWindowStyleFlag() & wxBU_AUTODRAW) ) - DrawButtonFocus( (WXHDC) hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right, lpDIS->rcItem.bottom, ((state & ODS_SELECTED) == ODS_SELECTED)); + // no MaskBlt() under Win16 +#ifdef __WIN32__ + wxMask *mask = bitmap->GetMask(); + if ( mask ) + { + // the fg ROP is applied for the pixels of the mask bitmap which are 1 + // (for a wxMask this means that this is a non transparent pixel), the + // bg ROP is applied for all the others + + HBRUSH hbrBackground = + ::CreateSolidBrush(wxColourToRGB(GetBackgroundColour())); + HBRUSH hbrOld = (HBRUSH)::SelectObject(hDC, hbrBackground); + + ok = ::MaskBlt( + hDC, x1, y1, wBmp, hBmp, // dst + memDC, 0, 0, // src + (HBITMAP)mask->GetMaskBitmap(), 0, 0, // mask + MAKEROP4(SRCCOPY, // fg ROP + PATCOPY) // bg ROP + ); + + ::SelectObject(hDC, hbrOld); + ::DeleteObject(hbrBackground); + } + else + { + // this will make the check below fail and BitBlt() will be used if + // MaskBlt() is not supported (for example, under Win95) + ok = FALSE; + } + + if ( !ok ) +#endif // Win32 + { + ok = ::BitBlt(hDC, x1, y1, wBmp, hBmp, // dst + memDC, 0, 0, // src + SRCCOPY); // ROP + } + + if ( !ok ) + { + wxLogLastError(_T("Mask/BitBlt()")); + } + + if ( (state & ODS_DISABLED) && autoDraw ) + { + DrawButtonDisable((WXHDC) hDC, + lpDIS->rcItem.left, lpDIS->rcItem.top, + lpDIS->rcItem.right, lpDIS->rcItem.bottom, + TRUE); + } + else if ( (state & ODS_FOCUS) && autoDraw ) + { + DrawButtonFocus((WXHDC) hDC, + lpDIS->rcItem.left, + lpDIS->rcItem.top, + lpDIS->rcItem.right, + lpDIS->rcItem.bottom, + isSelected); + } ::SelectObject(memDC, old); @@ -169,14 +246,14 @@ bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item) void wxBitmapButton::DrawFace( WXHDC dc, int left, int top, int right, int bottom, bool sel ) { - HPEN oldp; - HBRUSH oldb ; + HPEN oldp; + HBRUSH oldb ; - HPEN penBorder; - HPEN penLight; - HPEN penShadow; - HBRUSH brushFace; - COLORREF ms_color; + HPEN penBorder; + HPEN penLight; + HPEN penShadow; + HBRUSH brushFace; + COLORREF ms_color; ms_color = GetSysColor(COLOR_WINDOWFRAME) ; penBorder = CreatePen(PS_SOLID,0,ms_color) ; @@ -194,10 +271,10 @@ void wxBitmapButton::DrawFace( WXHDC dc, int left, int top, int right, int botto oldb = (HBRUSH) SelectObject( (HDC) dc, brushFace ) ; Rectangle( (HDC) dc, left, top, right, bottom ) ; SelectObject( (HDC) dc, penBorder) ; - MoveToEx((HDC) dc,left+1,top,NULL);LineTo((HDC) dc,right-1,top); - MoveToEx((HDC) dc,left,top+1,NULL);LineTo((HDC) dc,left,bottom-1); - MoveToEx((HDC) dc,left+1,bottom-1,NULL);LineTo((HDC) dc,right-1,bottom-1); - MoveToEx((HDC) dc,right-1,top+1,NULL);LineTo((HDC) dc,right-1,bottom-1); + MoveToEx((HDC) dc,left+1,top,NULL);LineTo((HDC) dc,right-1,top); + MoveToEx((HDC) dc,left,top+1,NULL);LineTo((HDC) dc,left,bottom-1); + MoveToEx((HDC) dc,left+1,bottom-1,NULL);LineTo((HDC) dc,right-1,bottom-1); + MoveToEx((HDC) dc,right-1,top+1,NULL);LineTo((HDC) dc,right-1,bottom-1); SelectObject( (HDC) dc, penShadow) ; if (sel) @@ -224,13 +301,14 @@ void wxBitmapButton::DrawFace( WXHDC dc, int left, int top, int right, int botto SelectObject((HDC) dc,oldp) ; SelectObject((HDC) dc,oldb) ; - DeleteObject(penBorder); - DeleteObject(penLight); - DeleteObject(penShadow); - DeleteObject(brushFace); + DeleteObject(penBorder); + DeleteObject(penLight); + DeleteObject(penShadow); + DeleteObject(brushFace); } -#define FOCUS_MARGIN 6 +// VZ: should be at the very least less than wxDEFAULT_BUTTON_MARGIN +#define FOCUS_MARGIN 3 void wxBitmapButton::DrawButtonFocus( WXHDC dc, int left, int top, int right, int bottom, bool sel ) { @@ -250,12 +328,27 @@ void wxBitmapButton::DrawButtonDisable( WXHDC dc, int left, int top, int right, { HBRUSH old = (HBRUSH) SelectObject( (HDC) dc, wxDisableButtonBrush ) ; + // VZ: what's this?? there is no such ROP AFAIK +#ifdef __SALFORDC__ + DWORD dwRop = 0xFA0089L; +#else + DWORD dwRop = 0xFA0089UL; +#endif + if ( with_marg ) - ::PatBlt( (HDC) dc, left + m_marginX, top + m_marginY, - right - 2 * m_marginX, bottom - 2 * m_marginY, - 0xfa0089ul ) ; - else ::PatBlt( (HDC) dc, left, top, right, bottom, 0xfa0089ul ) ; + { + left += m_marginX; + top += m_marginY; + right -= 2 * m_marginX; + bottom -= 2 * m_marginY; + } + + ::PatBlt( (HDC) dc, left, top, right, bottom, dwRop); ::SelectObject( (HDC) dc, old ) ; } +void wxBitmapButton::SetDefault() +{ + wxButton::SetDefault(); +}