This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
306 lines
8.9 KiB
C++
306 lines
8.9 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/msw/statbmp.cpp
|
|
// Purpose: wxStaticBitmap
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 04/01/98
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ===========================================================================
|
|
// declarations
|
|
// ===========================================================================
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// headers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_STATBMP
|
|
|
|
#include "wx/statbmp.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/app.h"
|
|
#include "wx/window.h"
|
|
#include "wx/icon.h"
|
|
#include "wx/dcclient.h"
|
|
#endif
|
|
|
|
#include "wx/msw/private.h"
|
|
|
|
#include "wx/sysopt.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// macros
|
|
// ---------------------------------------------------------------------------
|
|
|
|
wxBEGIN_EVENT_TABLE(wxStaticBitmap, wxStaticBitmapBase)
|
|
EVT_SIZE(wxStaticBitmap::WXHandleSize)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
// ===========================================================================
|
|
// implementation
|
|
// ===========================================================================
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// wxStaticBitmap
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// we may have either bitmap or icon: if a bitmap with mask is passed, we
|
|
// will transform it to an icon ourselves because otherwise the mask will
|
|
// be ignored by Windows
|
|
// note that this function will create a new object every time
|
|
// it is called even if the image needs no conversion
|
|
|
|
static wxGDIImage* ConvertImage( const wxGDIImage& bitmap )
|
|
{
|
|
bool isIcon = bitmap.IsKindOf( wxCLASSINFO(wxIcon) );
|
|
|
|
if( !isIcon )
|
|
{
|
|
wxASSERT_MSG( wxDynamicCast(&bitmap, wxBitmap),
|
|
wxT("not an icon and not a bitmap?") );
|
|
|
|
const wxBitmap& bmp = (const wxBitmap&)bitmap;
|
|
wxMask *mask = bmp.GetMask();
|
|
if ( mask && mask->GetMaskBitmap() )
|
|
{
|
|
wxIcon* icon = new wxIcon;
|
|
icon->CopyFromBitmap(bmp);
|
|
|
|
return icon;
|
|
}
|
|
|
|
return new wxBitmap( bmp );
|
|
}
|
|
|
|
// copying a bitmap is a cheap operation
|
|
return new wxIcon( (const wxIcon&)bitmap );
|
|
}
|
|
|
|
bool wxStaticBitmap::Create(wxWindow *parent,
|
|
wxWindowID id,
|
|
const wxGDIImage& bitmap,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style,
|
|
const wxString& name)
|
|
{
|
|
if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
|
|
return false;
|
|
|
|
// we may have either bitmap or icon: if a bitmap with mask is passed, we
|
|
// will transform it to an icon ourselves because otherwise the mask will
|
|
// be ignored by Windows
|
|
m_isIcon = bitmap.IsKindOf(wxCLASSINFO(wxIcon));
|
|
|
|
wxGDIImage *image = ConvertImage( bitmap );
|
|
m_isIcon = image->IsKindOf( wxCLASSINFO(wxIcon) );
|
|
|
|
// create the native control
|
|
if ( !MSWCreateControl(wxT("STATIC"), wxEmptyString, pos, size) )
|
|
{
|
|
// control creation failed
|
|
return false;
|
|
}
|
|
|
|
// no need to delete the new image
|
|
SetImageNoCopy(image);
|
|
|
|
// GetBestSize will work properly now, so set the best size if needed
|
|
SetInitialSize(size);
|
|
|
|
// painting manually is reported not to work under Windows CE (see #10093),
|
|
// so don't do it there even if this probably means that alpha is not
|
|
// supported there -- but at least bitmaps without alpha appear correctly
|
|
#ifndef __WXWINCE__
|
|
// Windows versions before XP (and even XP if the application has no
|
|
// manifest and so the old comctl32.dll is used) don't draw correctly the
|
|
// images with alpha channel so we need to draw them ourselves and it's
|
|
// easier to just always do it rather than check if we have an image with
|
|
// alpha or not
|
|
if ( wxTheApp->GetComCtl32Version() < 600 )
|
|
{
|
|
Connect(wxEVT_PAINT, wxPaintEventHandler(wxStaticBitmap::DoPaintManually));
|
|
}
|
|
#endif // !__WXWINCE__
|
|
|
|
return true;
|
|
}
|
|
|
|
WXDWORD wxStaticBitmap::MSWGetStyle(long style, WXDWORD *exstyle) const
|
|
{
|
|
WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
|
|
|
|
// what kind of control are we?
|
|
msStyle |= m_isIcon ? SS_ICON : SS_BITMAP;
|
|
|
|
// we use SS_CENTERIMAGE to prevent the control from resizing the bitmap to
|
|
// fit to its size -- this is unexpected and doesn't happen in other ports
|
|
//
|
|
// and SS_NOTIFY is necessary to receive mouse events
|
|
msStyle |= SS_CENTERIMAGE | SS_NOTIFY;
|
|
|
|
return msStyle;
|
|
}
|
|
|
|
bool wxStaticBitmap::ImageIsOk() const
|
|
{
|
|
return m_image && m_image->IsOk();
|
|
}
|
|
|
|
wxIcon wxStaticBitmap::GetIcon() const
|
|
{
|
|
wxCHECK_MSG( m_image, wxIcon(), wxT("no image in wxStaticBitmap") );
|
|
|
|
// we can't ask for an icon if all we have is a bitmap
|
|
wxCHECK_MSG( m_isIcon, wxIcon(), wxT("no icon in this wxStaticBitmap") );
|
|
|
|
return *(wxIcon *)m_image;
|
|
}
|
|
|
|
wxBitmap wxStaticBitmap::GetBitmap() const
|
|
{
|
|
if ( m_isIcon )
|
|
{
|
|
// don't fail because we might have replaced the bitmap with icon
|
|
// ourselves internally in ConvertImage() to keep the transparency but
|
|
// the user code doesn't know about it so it still can use GetBitmap()
|
|
// to retrieve the bitmap
|
|
return wxBitmap(GetIcon());
|
|
}
|
|
else // we have a bitmap
|
|
{
|
|
wxCHECK_MSG( m_image, wxBitmap(), wxT("no image in wxStaticBitmap") );
|
|
|
|
return *(wxBitmap *)m_image;
|
|
}
|
|
}
|
|
|
|
void wxStaticBitmap::Free()
|
|
{
|
|
wxDELETE(m_image);
|
|
}
|
|
|
|
wxSize wxStaticBitmap::DoGetBestClientSize() const
|
|
{
|
|
wxSize size;
|
|
if ( ImageIsOk() )
|
|
{
|
|
size = m_image->GetSize();
|
|
}
|
|
else // No image yet
|
|
{
|
|
// this is completely arbitrary
|
|
size.x =
|
|
size.y = 16;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
void wxStaticBitmap::WXHandleSize(wxSizeEvent& event)
|
|
{
|
|
// Invalidate everything when our size changes as the image position (it's
|
|
// drawn centred in the window client area) changes.
|
|
Refresh();
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
#ifndef __WXWINCE__
|
|
|
|
void wxStaticBitmap::DoPaintManually(wxPaintEvent& WXUNUSED(event))
|
|
{
|
|
wxPaintDC dc(this);
|
|
|
|
const wxSize size(GetSize());
|
|
const wxBitmap bmp(GetBitmap());
|
|
|
|
// Clear the background: notice that we're supposed to be transparent, so
|
|
// use the parent background colour if we don't have our own instead of
|
|
// falling back to the default
|
|
const wxWindow *win = UseBgCol() ? this : GetParent();
|
|
dc.SetBrush(win->GetBackgroundColour());
|
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
|
dc.DrawRectangle(0, 0, size.GetWidth(), size.GetHeight());
|
|
|
|
// Draw the image in the middle
|
|
dc.DrawBitmap(bmp,
|
|
(size.GetWidth() - bmp.GetWidth()) / 2,
|
|
(size.GetHeight() - bmp.GetHeight()) / 2,
|
|
true /* use mask */);
|
|
}
|
|
|
|
#endif // !__WXWINCE__
|
|
|
|
void wxStaticBitmap::SetImage( const wxGDIImage* image )
|
|
{
|
|
wxGDIImage* convertedImage = ConvertImage( *image );
|
|
SetImageNoCopy( convertedImage );
|
|
}
|
|
|
|
void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image)
|
|
{
|
|
Free();
|
|
InvalidateBestSize();
|
|
|
|
m_isIcon = image->IsKindOf( wxCLASSINFO(wxIcon) );
|
|
// the image has already been copied
|
|
m_image = image;
|
|
|
|
int x, y;
|
|
int w, h;
|
|
GetPosition(&x, &y);
|
|
GetSize(&w, &h);
|
|
|
|
#ifdef __WIN32__
|
|
HANDLE handle = (HANDLE)m_image->GetHandle();
|
|
LONG style = ::GetWindowLong( (HWND)GetHWND(), GWL_STYLE ) ;
|
|
::SetWindowLong( (HWND)GetHWND(), GWL_STYLE, ( style & ~( SS_BITMAP|SS_ICON ) ) |
|
|
( m_isIcon ? SS_ICON : SS_BITMAP ) );
|
|
HGDIOBJ oldHandle = (HGDIOBJ)::SendMessage(GetHwnd(), STM_SETIMAGE,
|
|
m_isIcon ? IMAGE_ICON : IMAGE_BITMAP, (LPARAM)handle);
|
|
// detect if this is still the handle we passed before or
|
|
// if the static-control made a copy of the bitmap!
|
|
if (m_currentHandle != 0 && oldHandle != (HGDIOBJ) m_currentHandle)
|
|
{
|
|
// the static control made a copy and we are responsible for deleting it
|
|
DeleteObject((HGDIOBJ) oldHandle);
|
|
}
|
|
m_currentHandle = (WXHANDLE)handle;
|
|
#endif // Win32
|
|
|
|
if ( ImageIsOk() )
|
|
{
|
|
int width = image->GetWidth(),
|
|
height = image->GetHeight();
|
|
if ( width && height )
|
|
{
|
|
w = width;
|
|
h = height;
|
|
|
|
::MoveWindow(GetHwnd(), x, y, width, height, FALSE);
|
|
}
|
|
}
|
|
|
|
RECT rect;
|
|
rect.left = x;
|
|
rect.top = y;
|
|
rect.right = x + w;
|
|
rect.bottom = y + h;
|
|
::InvalidateRect(GetHwndOf(GetParent()), &rect, TRUE);
|
|
}
|
|
|
|
#endif // wxUSE_STATBMP
|