added support for gcc precompiled headers
[wxWidgets.git] / src / msw / statbmp.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: statbmp.cpp
3 // Purpose: wxStaticBitmap
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "statbmp.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #if wxUSE_STATBMP
32
33 #include "wx/window.h"
34 #include "wx/msw/private.h"
35
36 #ifndef WX_PRECOMP
37 #include "wx/icon.h"
38 #include "wx/statbmp.h"
39 #endif
40
41 #include <stdio.h>
42
43 // ---------------------------------------------------------------------------
44 // macors
45 // ---------------------------------------------------------------------------
46
47 IMPLEMENT_DYNAMIC_CLASS(wxStaticBitmap, wxControl)
48
49 /*
50 TODO PROPERTIES :
51 bitmap
52 */
53
54 // ===========================================================================
55 // implementation
56 // ===========================================================================
57
58 // ---------------------------------------------------------------------------
59 // wxStaticBitmap
60 // ---------------------------------------------------------------------------
61
62 // we may have either bitmap or icon: if a bitmap with mask is passed, we
63 // will transform it to an icon ourselves because otherwise the mask will
64 // be ignored by Windows
65 // note that this function will create a new object every time
66 // it is called even if the image needs no conversion
67
68 #ifndef __WIN16__
69
70 static wxGDIImage* ConvertImage( const wxGDIImage& bitmap )
71 {
72 bool isIcon = bitmap.IsKindOf( CLASSINFO(wxIcon) );
73
74 if( !isIcon )
75 {
76 wxASSERT_MSG( wxDynamicCast(&bitmap, wxBitmap),
77 _T("not an icon and not a bitmap?") );
78
79 const wxBitmap& bmp = (const wxBitmap&)bitmap;
80 wxMask *mask = bmp.GetMask();
81 if ( mask && mask->GetMaskBitmap() )
82 {
83 wxIcon* icon = new wxIcon;
84 icon->CopyFromBitmap(bmp);
85
86 return icon;
87 }
88
89 return new wxBitmap( bmp );
90 }
91
92 // copying a bitmap is a cheap operation
93 return new wxIcon( (const wxIcon&)bitmap );
94 }
95
96 #endif
97
98 bool wxStaticBitmap::Create(wxWindow *parent,
99 wxWindowID id,
100 const wxGDIImage& bitmap,
101 const wxPoint& pos,
102 const wxSize& size,
103 long style,
104 const wxString& name)
105 {
106 if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
107 return FALSE;
108
109 // we may have either bitmap or icon: if a bitmap with mask is passed, we
110 // will transform it to an icon ourselves because otherwise the mask will
111 // be ignored by Windows
112 wxGDIImage *image = (wxGDIImage *)NULL;
113 m_isIcon = bitmap.IsKindOf(CLASSINFO(wxIcon));
114
115 #ifdef __WIN16__
116 wxASSERT_MSG( !m_isIcon, "Icons are not supported in wxStaticBitmap under WIN16." );
117 image = &bitmap;
118 #else // Win32
119 image = ConvertImage( bitmap );
120 m_isIcon = image->IsKindOf( CLASSINFO(wxIcon) );
121 #endif // Win16/32
122
123 // create the native control
124 if ( !MSWCreateControl(
125 #ifdef __WIN32__
126 _T("STATIC"),
127 #else // Win16
128 _T("BUTTON"),
129 #endif // Win32/16
130 wxEmptyString, pos, size) )
131 {
132 // control creation failed
133 return FALSE;
134 }
135
136 // no need to delete the new image
137 SetImageNoCopy(image);
138
139 return TRUE;
140 }
141
142 wxBorder wxStaticBitmap::GetDefaultBorder() const
143 {
144 return wxBORDER_NONE;
145 }
146
147 WXDWORD wxStaticBitmap::MSWGetStyle(long style, WXDWORD *exstyle) const
148 {
149 WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
150
151 #ifdef __WIN32__
152 // what kind of control are we?
153 msStyle |= m_isIcon ? SS_ICON : SS_BITMAP;
154
155 // we use SS_CENTERIMAGE to prevent the control from resizing the bitmap to
156 // fit to its size -- this is unexpected and doesn't happen in other ports
157 msStyle |= SS_CENTERIMAGE;
158 #else // Win16
159 msStyle |= BS_OWNERDRAW;
160 #endif // Win32/16
161
162 return msStyle;
163 }
164
165 bool wxStaticBitmap::ImageIsOk() const
166 {
167 return m_image && m_image->Ok();
168 }
169
170 void wxStaticBitmap::Free()
171 {
172 delete m_image;
173
174 m_image = NULL;
175 }
176
177 wxSize wxStaticBitmap::DoGetBestSize() const
178 {
179 // reuse the current size (as wxWindow does) instead of using some
180 // arbitrary default size (as wxControl, our immediate base class, does)
181 return wxWindow::DoGetBestSize();
182 }
183
184 void wxStaticBitmap::SetImage( const wxGDIImage* image )
185 {
186 wxGDIImage* convertedImage = ConvertImage( *image );
187 SetImageNoCopy( convertedImage );
188 }
189
190 void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image)
191 {
192 Free();
193
194 m_isIcon = image->IsKindOf( CLASSINFO(wxIcon) );
195 // the image has already been copied
196 m_image = image;
197
198 int x, y;
199 int w, h;
200 GetPosition(&x, &y);
201 GetSize(&w, &h);
202
203 #ifdef __WIN32__
204 HANDLE handle = (HANDLE)m_image->GetHandle();
205 LONG style = ::GetWindowLong( (HWND)GetHWND(), GWL_STYLE ) ;
206 ::SetWindowLong( (HWND)GetHWND(), GWL_STYLE, ( style & ~( SS_BITMAP|SS_ICON ) ) |
207 ( m_isIcon ? SS_ICON : SS_BITMAP ) );
208 ::SendMessage(GetHwnd(), STM_SETIMAGE,
209 m_isIcon ? IMAGE_ICON : IMAGE_BITMAP, (LPARAM)handle);
210 #endif // Win32
211
212 if ( ImageIsOk() )
213 {
214 int width = image->GetWidth(),
215 height = image->GetHeight();
216 if ( width && height )
217 {
218 w = width;
219 h = height;
220
221 ::MoveWindow(GetHwnd(), x, y, width, height, FALSE);
222 }
223 }
224
225 RECT rect;
226 rect.left = x;
227 rect.top = y;
228 rect.right = x + w;
229 rect.bottom = y + h;
230 InvalidateRect(GetHwndOf(GetParent()), &rect, TRUE);
231 }
232
233 // under Win32 we use the standard static control style for this
234 #ifdef __WIN16__
235 bool wxStaticBitmap::MSWOnDraw(WXDRAWITEMSTRUCT *item)
236 {
237 LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) item;
238
239 wxCHECK_MSG( !m_isIcon, FALSE, _T("icons not supported in wxStaticBitmap") );
240
241 wxBitmap* bitmap = (wxBitmap *)m_image;
242 if ( !bitmap->Ok() )
243 return FALSE;
244
245 HDC hDC = lpDIS->hDC;
246 HDC memDC = ::CreateCompatibleDC(hDC);
247
248 HBITMAP old = (HBITMAP) ::SelectObject(memDC, (HBITMAP) bitmap->GetHBITMAP());
249
250 if (!old)
251 return FALSE;
252
253 int x = lpDIS->rcItem.left;
254 int y = lpDIS->rcItem.top;
255 int width = lpDIS->rcItem.right - x;
256 int height = lpDIS->rcItem.bottom - y;
257
258 // Centre the bitmap in the control area
259 int x1 = (int) (x + ((width - bitmap->GetWidth()) / 2));
260 int y1 = (int) (y + ((height - bitmap->GetHeight()) / 2));
261
262 ::BitBlt(hDC, x1, y1, bitmap->GetWidth(), bitmap->GetHeight(), memDC, 0, 0, SRCCOPY);
263
264 ::SelectObject(memDC, old);
265
266 ::DeleteDC(memDC);
267
268 return TRUE;
269 }
270 #endif // Win16
271
272 // We need this or the control can never be moved e.g. in Dialog Editor.
273 long wxStaticBitmap::MSWWindowProc(WXUINT nMsg,
274 WXWPARAM wParam,
275 WXLPARAM lParam)
276 {
277 #ifndef __WXWINCE__
278 // Ensure that static items get messages. Some controls don't like this
279 // message to be intercepted (e.g. RichEdit), hence the tests.
280 if ( nMsg == WM_NCHITTEST )
281 return (long)HTCLIENT;
282 #endif
283
284 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
285 }
286
287 #endif // wxUSE_STATBMP