1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dibpreview.cxx,v $
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 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
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>
47 #include <rtl/ustring.hxx>
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
;
63 //------------------------------------------------------------------------
65 //------------------------------------------------------------------------
67 namespace /* private */
69 const LPTSTR CURRENT_INSTANCE
= TEXT("CurrInst");
72 //------------------------------------------------------------------------
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
) :
99 RegisterDibPreviewWindowClass();
101 DWORD dwStyle
= WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
;
104 dwStyle
|= WS_VISIBLE
;
106 m_Hwnd
= CreateWindowEx(
108 PREVIEWWND_CLASS_NAME
,
113 (HMENU
)0x0, // for child windows this will
114 // be used as child window identifier
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");
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
);
155 clrRes
= GetDeviceCaps(hdc
, COLORRES
);
160 //-------------------------------
162 //-------------------------------
164 sal_Int32 SAL_CALL
CDIBPreview::getAvailableWidth() throw (RuntimeException
)
167 bool bRet
= GetClientRect(m_Hwnd
,&rect
);
177 //-------------------------------
179 //-------------------------------
181 sal_Int32 SAL_CALL
CDIBPreview::getAvailableHeight() throw (RuntimeException
)
184 bool bRet
= GetClientRect(m_Hwnd
,&rect
);
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
206 osl::ClearableMutexGuard
aGuard(m_PaintLock
);
209 m_ImageData
>>= m_Image
;
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
);
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
246 //---------------------------------------------------
248 //---------------------------------------------------
250 void SAL_CALL
CDIBPreview::onPaint(HWND hWnd
, HDC hDC
)
252 BITMAPFILEHEADER
* pbmfh
;
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
);
299 FillRect(hDC
,&rc
,(HBRUSH
)(COLOR_INACTIVEBORDER
+ 1));
303 rc
.top
= nHeight
- nY
- 1;
306 FillRect(hDC
,&rc
,(HBRUSH
)(COLOR_INACTIVEBORDER
+ 1));
315 rc
.bottom
= nHeight
- nY
;
316 FillRect(hDC
,&rc
,(HBRUSH
)(COLOR_INACTIVEBORDER
+ 1));
319 rc
.left
= nWidth
- nX
- 1;
322 rc
.bottom
= nHeight
- nY
;
323 FillRect(hDC
,&rc
,(HBRUSH
)(COLOR_INACTIVEBORDER
+ 1));
326 else // clear background
329 GetClientRect(hWnd
,&rc
);
330 FillRect(hDC
,&rc
,(HBRUSH
)(COLOR_INACTIVEBORDER
+ 1));
335 OSL_ASSERT(sal_False
);
339 //---------------------------------------------------
341 //---------------------------------------------------
343 LRESULT CALLBACK
CDIBPreview::WndProc(
344 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
351 // we connect a pointer to the current instance
352 // with a window instance via SetProp
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
);
365 // we remove the window property which connects
366 // a class instance with a window class
369 // RemoveProp returns the saved value on success
370 if (reinterpret_cast<CDIBPreview
*>(
371 RemoveProp(hWnd
, CURRENT_INSTANCE
)) == NULL
)
380 CDIBPreview
* pImpl
= reinterpret_cast<CDIBPreview
*>(
381 GetProp(hWnd
, CURRENT_INSTANCE
));
388 hDC
= BeginPaint(hWnd
,&ps
);
389 pImpl
->onPaint(hWnd
,hDC
);
394 // ignore this message in order to
395 // avoid flickering during paint
401 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
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
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
++;
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
);