merge the formfield patch from ooo-build
[ooovba.git] / fpicker / source / win32 / filepicker / dibpreview.cxx
bloba3e19e8179ceacacf82c59143df4419c70bde715
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dibpreview.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_fpicker.hxx"
34 //------------------------------------------------------------------------
35 // includes
36 //------------------------------------------------------------------------
38 #include <tchar.h>
39 #include "dibpreview.hxx"
40 #include <osl/diagnose.h>
42 #ifndef _COM_SUN_STAR_UI_DIALOG_FILEPREVIEWIMAGEFORMATS_HPP_
43 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
44 #endif
46 #ifndef _USTRING_HXX_
47 #include <rtl/ustring.hxx>
48 #endif
50 #include <stdexcept>
51 #include <string>
53 //------------------------------------------------------------------------
55 //------------------------------------------------------------------------
57 using ::com::sun::star::uno::Sequence;
58 using ::com::sun::star::uno::RuntimeException;
59 using ::com::sun::star::uno::Any;
60 using ::com::sun::star::lang::IllegalArgumentException;
61 using rtl::OUString;
63 //------------------------------------------------------------------------
65 //------------------------------------------------------------------------
67 namespace /* private */
69 const LPTSTR CURRENT_INSTANCE = TEXT("CurrInst");
72 //------------------------------------------------------------------------
73 // defines
74 //------------------------------------------------------------------------
76 #define PREVIEWWND_CLASS_NAME TEXT("DIBPreviewWnd###")
78 // means 3 pixel left and 3 pixel right
79 #define HORZ_BODER_SPACE 6
81 // means 3 pixel top and 3 pixel bottom
82 #define VERT_BORDER_SPACE 6
84 //---------------------------------------------------
85 // static member initialization
86 //---------------------------------------------------
88 osl::Mutex CDIBPreview::s_Mutex;
89 ATOM CDIBPreview::s_ClassAtom = 0;
90 sal_Int32 CDIBPreview::s_RegisterDibPreviewWndCount = 0;
92 //---------------------------------------------------
94 //---------------------------------------------------
96 CDIBPreview::CDIBPreview(HINSTANCE instance,HWND parent,sal_Bool bShowWindow) :
97 m_Instance(instance)
99 RegisterDibPreviewWindowClass();
101 DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
103 if (bShowWindow)
104 dwStyle |= WS_VISIBLE;
106 m_Hwnd = CreateWindowEx(
107 WS_EX_CLIENTEDGE,
108 PREVIEWWND_CLASS_NAME,
109 TEXT(""),
110 dwStyle,
111 0, 0, 0, 0,
112 parent,
113 (HMENU)0x0, // for child windows this will
114 // be used as child window identifier
115 m_Instance,
116 (LPVOID)this // pass a pointer to the current
117 // instance of this class
120 bool bSuccess = IsWindow(m_Hwnd);
122 OSL_POSTCOND(bSuccess,"Coud not create preview window");
124 if (!bSuccess)
126 UnregisterDibPreviewWindowClass();
127 throw std::runtime_error("Could not create preview window");
131 //---------------------------------------------------
133 //---------------------------------------------------
135 CDIBPreview::~CDIBPreview( )
137 // remember: we don't have to destroy the
138 // preview window because it will be destroyed
139 // by it's parent window (the FileOpen dialog)
140 // but we have to unregister the window class
141 //if ( m_bWndClassRegistered )
142 UnregisterDibPreviewWindowClass();
145 //-------------------------------
147 //-------------------------------
149 sal_Int32 SAL_CALL CDIBPreview::getTargetColorDepth() throw (RuntimeException)
151 HDC hdc = GetDC(m_Hwnd);
152 int clrRes = 0;
154 if (hdc)
155 clrRes = GetDeviceCaps(hdc, COLORRES);
157 return clrRes;
160 //-------------------------------
162 //-------------------------------
164 sal_Int32 SAL_CALL CDIBPreview::getAvailableWidth() throw (RuntimeException)
166 RECT rect;
167 bool bRet = GetClientRect(m_Hwnd,&rect);
169 sal_Int32 cx = 0;
171 if ( bRet )
172 cx = rect.right;
174 return cx;
177 //-------------------------------
179 //-------------------------------
181 sal_Int32 SAL_CALL CDIBPreview::getAvailableHeight() throw (RuntimeException)
183 RECT rect;
184 bool bRet = GetClientRect(m_Hwnd,&rect);
186 sal_Int32 cy = 0;
188 if ( bRet )
189 cy = rect.bottom;
191 return cy;
194 //-------------------------------
196 //-------------------------------
198 void SAL_CALL CDIBPreview::setImage(sal_Int16 aImageFormat, const Any& aImage)
199 throw (IllegalArgumentException, RuntimeException)
201 PreviewBase::setImage(aImageFormat,aImage);
203 // if the any has no value we have an
204 // empty Sequence which clears the
205 // preview window
206 osl::ClearableMutexGuard aGuard(m_PaintLock);
208 m_Image.realloc(0);
209 m_ImageData >>= m_Image;
211 aGuard.clear();
213 InvalidateRect(m_Hwnd,NULL,FALSE);
214 UpdateWindow(m_Hwnd);
217 //-------------------------------
219 //-------------------------------
221 sal_Bool SAL_CALL CDIBPreview::setShowState(sal_Bool bShowState) throw (RuntimeException)
223 PreviewBase::setShowState(bShowState);
224 ShowWindow(m_Hwnd, m_bShowState ? SW_SHOW : SW_HIDE);
225 return sal_True;
228 //-------------------------------
230 //-------------------------------
232 sal_Bool SAL_CALL CDIBPreview::getShowState() throw (RuntimeException)
234 return (sal_Bool)IsWindowVisible(m_Hwnd);
237 //-------------------------------
239 //-------------------------------
241 HWND SAL_CALL CDIBPreview::getWindowHandle() const
243 return m_Hwnd;
246 //---------------------------------------------------
248 //---------------------------------------------------
250 void SAL_CALL CDIBPreview::onPaint(HWND hWnd, HDC hDC)
252 BITMAPFILEHEADER* pbmfh;
253 BITMAPINFO * pbmi;
254 BYTE * pBits;
255 int cxDib;
256 int cyDib;
258 osl::MutexGuard aGuard(m_PaintLock);
262 pbmfh = reinterpret_cast<BITMAPFILEHEADER*>(m_Image.getArray());
264 if ( !IsBadReadPtr( pbmfh, sizeof(BITMAPFILEHEADER)) &&
265 (pbmfh->bfType == ('B' | ('M' << 8))) )
267 pbmi = reinterpret_cast<BITMAPINFO*>((pbmfh + 1));
268 pBits = reinterpret_cast<BYTE*>(((DWORD)pbmfh) + pbmfh->bfOffBits);
270 cxDib = pbmi->bmiHeader.biWidth;
271 cyDib = abs (pbmi->bmiHeader.biHeight);
273 SetStretchBltMode(hDC, COLORONCOLOR);
275 int nWidth = getAvailableWidth();
276 int nHeight = getAvailableHeight();
278 int nX = abs(nWidth - cxDib) / 2;
279 int nY = abs(nHeight - cyDib) / 2;
281 int GDIError = GDI_ERROR;
282 GDIError = StretchDIBits(
283 hDC, nX, nY, cxDib, cyDib,
284 0, 0, cxDib, cyDib, pBits, pbmi,
285 DIB_RGB_COLORS, SRCCOPY);
287 OSL_ASSERT(GDI_ERROR != GDIError);
289 // paint the border
290 RECT rc;
292 if (nY > 0)
294 // top
295 rc.left = 0;
296 rc.top = 0;
297 rc.right = nWidth;
298 rc.bottom = nY;
299 FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
301 // bottom
302 rc.left = 0;
303 rc.top = nHeight - nY - 1;
304 rc.right = nWidth;
305 rc.bottom = nHeight;
306 FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
309 if (nX > 0)
311 // left
312 rc.left = 0;
313 rc.top = nY;
314 rc.right = nX;
315 rc.bottom = nHeight - nY;
316 FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
318 // right
319 rc.left = nWidth - nX - 1;
320 rc.top = nY;
321 rc.right = nWidth;
322 rc.bottom = nHeight - nY;
323 FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
326 else // clear background
328 RECT rc;
329 GetClientRect(hWnd,&rc);
330 FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
333 catch(...)
335 OSL_ASSERT(sal_False);
339 //---------------------------------------------------
341 //---------------------------------------------------
343 LRESULT CALLBACK CDIBPreview::WndProc(
344 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
346 LRESULT lResult = 0;
348 switch(uMsg)
351 // we connect a pointer to the current instance
352 // with a window instance via SetProp
353 case WM_CREATE:
355 LPCREATESTRUCT lpcs =
356 reinterpret_cast< LPCREATESTRUCT >(lParam);
358 OSL_ASSERT(lpcs->lpCreateParams);
360 // connect the instance handle to the window
361 SetProp(hWnd, CURRENT_INSTANCE, lpcs->lpCreateParams);
363 break;
365 // we remove the window property which connects
366 // a class instance with a window class
367 case WM_NCDESTROY:
369 // RemoveProp returns the saved value on success
370 if (reinterpret_cast<CDIBPreview*>(
371 RemoveProp(hWnd, CURRENT_INSTANCE)) == NULL)
373 OSL_ASSERT(false);
376 break;
378 case WM_PAINT:
380 CDIBPreview* pImpl = reinterpret_cast<CDIBPreview*>(
381 GetProp(hWnd, CURRENT_INSTANCE));
383 OSL_ASSERT(pImpl);
385 HDC hDC;
386 PAINTSTRUCT ps;
388 hDC = BeginPaint(hWnd,&ps);
389 pImpl->onPaint(hWnd,hDC);
390 EndPaint(hWnd,&ps);
392 break;
394 // ignore this message in order to
395 // avoid flickering during paint
396 case WM_ERASEBKGND:
397 lResult = 1;
398 break;
400 default:
401 return DefWindowProc(hWnd, uMsg, wParam, lParam);
404 return lResult;
407 //---------------------------------------------------
409 //---------------------------------------------------
411 ATOM SAL_CALL CDIBPreview::RegisterDibPreviewWindowClass()
413 osl::MutexGuard aGuard( s_Mutex );
415 if (0 == s_ClassAtom)
417 // register the preview window class
418 WNDCLASSEX wndClsEx;
419 ZeroMemory(&wndClsEx, sizeof(wndClsEx));
421 wndClsEx.cbSize = sizeof(wndClsEx);
422 wndClsEx.style = CS_HREDRAW | CS_VREDRAW;
423 wndClsEx.lpfnWndProc = CDIBPreview::WndProc;
424 wndClsEx.hInstance = m_Instance;
425 wndClsEx.hbrBackground = (HBRUSH)(COLOR_INACTIVEBORDER + 1);
426 wndClsEx.lpszClassName = PREVIEWWND_CLASS_NAME;
428 // register the preview window class
429 // !!! Win95 - the window class will be unregistered automaticly
430 // if the dll is unloaded
431 // Win2000 - the window class must be unregistered manually
432 // if the dll is unloaded
433 s_ClassAtom = RegisterClassEx(&wndClsEx);
435 OSL_POSTCOND(s_ClassAtom,"Could not register preview window class");
437 if (0 == s_ClassAtom)
438 throw std::runtime_error("Preview window class could not be registered");
441 // increment the register class counter
442 // so that we keep track of the number
443 // of class registrations
444 //if ( 0 != s_ClassAtom )
445 s_RegisterDibPreviewWndCount++;
447 return s_ClassAtom;
450 //---------------------------------------------------
452 //---------------------------------------------------
454 void SAL_CALL CDIBPreview::UnregisterDibPreviewWindowClass()
456 osl::MutexGuard aGuard( s_Mutex );
458 OSL_ASSERT( ( (0 != s_ClassAtom) && (s_RegisterDibPreviewWndCount > 0)) ||
459 ( (0 == s_ClassAtom) && (0 == s_RegisterDibPreviewWndCount) ) );
461 // update the register class counter
462 // and unregister the window class if
463 // counter drops to zero
464 if (0 != s_ClassAtom)
466 s_RegisterDibPreviewWndCount--;
467 OSL_ASSERT(s_RegisterDibPreviewWndCount >= 0);
470 if (0 == s_RegisterDibPreviewWndCount)
472 UnregisterClass((LPCTSTR)MAKELONG(s_ClassAtom,0),m_Instance);
473 s_ClassAtom = 0;