1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_fpicker.hxx"
31 //------------------------------------------------------------------------
33 //------------------------------------------------------------------------
36 #include "PreviewCtrl.hxx"
37 #include <osl/diagnose.h>
40 #pragma warning(push, 1)
49 //------------------------------------------------------------------------
51 //------------------------------------------------------------------------
53 #define PREVIEWWND_CLASS_NAME TEXT("PreviewWnd###")
55 #define HIMETRIC_INCH 2540
57 // means 3 pixel left and 3 pixel right
58 #define HORZ_BODER_SPACE 6
60 // means 3 pixel top and 3 pixel bottom
61 #define VERT_BORDER_SPACE 6
63 //---------------------------------------------------
64 // static member initialization
65 //---------------------------------------------------
67 CFilePreview
* CFilePreview::s_FilePreviewInst
= NULL
;
68 CFilePreview::FILEPREVIEW_SINGLETON_DESTROYER_T
CFilePreview::s_SingletonDestroyer
;
70 //---------------------------------------------------
71 // some useful helper functions
72 //---------------------------------------------------
76 class CPreviewException
78 // used when registering or creation
79 // of the preview window failed
82 //------------------------------------------------------------
84 //------------------------------------------------------------
87 sal_Int32
SubDiv( sal_Int32 nNumber
, sal_Int32 nMinuend
, sal_Int32 nDenominator
)
89 return ( static_cast<sal_Int32
>( ( nNumber
- nMinuend
) / nDenominator
) );
92 //------------------------------------------------------------
93 // convert himetric to pixel
94 //------------------------------------------------------------
97 sal_Int32
Himetric2Pixel( HDC hDC
, sal_Int32 hmSize
, sal_Int32 nIndex
)
99 return MulDiv( hmSize
, GetDeviceCaps( hDC
, nIndex
), HIMETRIC_INCH
);
102 //------------------------------------------------------------
104 //------------------------------------------------------------
107 sal_uInt32
_getWidthRect( const RECT
& aRect
)
109 return ( aRect
.right
- aRect
.left
);
112 //------------------------------------------------------------
114 //------------------------------------------------------------
117 sal_uInt32
_getHeightRect( const RECT
& aRect
)
119 return ( aRect
.bottom
- aRect
.top
);
122 //------------------------------------------------------------
123 // calc the upper left corner so that a given window will be
124 // displayed centered within the given window
125 //------------------------------------------------------------
128 POINT
_calcULCorner( HWND hwnd
, const CDimension
& aPicSize
)
131 GetClientRect( hwnd
, &rect
);
133 sal_Int32 nWidthWnd
= _getWidthRect( rect
);
134 sal_Int32 nHeightWnd
= _getHeightRect( rect
);
137 ulCorner
.x
= SubDiv( nWidthWnd
, aPicSize
.m_cx
, 2 );
138 ulCorner
.y
= SubDiv( nHeightWnd
, aPicSize
.m_cy
, 2 );
143 //------------------------------------------------------------
144 // test if a picture with the given dimensions fits into an
146 // we expect the width and height to be in pixel
147 //------------------------------------------------------------
150 sal_Bool
_pictureSizeFitsWindowSize( HWND hwnd
, const CDimension
& aPicSize
)
153 GetClientRect( hwnd
, &rect
);
155 sal_Int32 nWidthWnd
= _getWidthRect( rect
);
156 sal_Int32 nHeightWnd
= _getHeightRect( rect
);
158 return ( ( ( nWidthWnd
- HORZ_BODER_SPACE
) >= aPicSize
.m_cx
) &&
159 ( ( nHeightWnd
- VERT_BORDER_SPACE
) >= aPicSize
.m_cy
) );
162 //------------------------------------------------------------
163 // calc the dimemsions so that a given picture fits into a
164 // given window, if the picture fits into the given window
165 // the original CDimension will be returned
166 //------------------------------------------------------------
169 CDimension
_scalePictureSize( HWND hwnd
, const CDimension
& aPicSize
)
171 CDimension scaledPicSize
= aPicSize
;
173 if ( !_pictureSizeFitsWindowSize( hwnd
, aPicSize
) )
176 GetClientRect( hwnd
, &rect
);
178 // the dimensions of the preview wnd are not equal
179 // that's why we equalize it
180 sal_Int32 nHeightWnd
= _getHeightRect( rect
) - VERT_BORDER_SPACE
;
181 sal_Int32 nWidthWnd
= nHeightWnd
;
183 if ( aPicSize
.m_cx
>= aPicSize
.m_cy
)
185 scaledPicSize
.m_cx
= nWidthWnd
;
187 static_cast< sal_Int32
>(
188 aPicSize
.m_cy
* nWidthWnd
/ aPicSize
.m_cx
);
193 static_cast< sal_Int32
>(
194 aPicSize
.m_cx
* nHeightWnd
/ aPicSize
.m_cy
);
195 scaledPicSize
.m_cy
= nHeightWnd
;
199 return scaledPicSize
;
205 //---------------------------------------------------
206 // to ensure only one instance (singleton)
207 //---------------------------------------------------
209 CFilePreview
* CFilePreview::createInstance(
212 const CDimension
& aSize
,
217 if ( !s_FilePreviewInst
)
221 s_FilePreviewInst
= new CFilePreview(
222 aParent
, ulCorner
, aSize
, hInstance
, bShow
, bEnabled
);
223 s_SingletonDestroyer
.reset( s_FilePreviewInst
);
225 catch( CPreviewException
& )
227 OSL_ASSERT( !s_FilePreviewInst
);
228 OSL_ENSURE( sal_False
, "Creation of the preview window failed" );
230 catch( CAutoOleInit::COleInitException
& )
232 OSL_ASSERT( !s_FilePreviewInst
);
233 OSL_ENSURE( sal_False
, "OleInitalize failed" );
237 return s_FilePreviewInst
;
240 //---------------------------------------------------
242 //---------------------------------------------------
244 CFilePreview::CFilePreview(
247 const CDimension
& aSize
,
250 sal_Bool bEnabled
) :
251 m_hInstance( hInstance
),
252 m_bEnabled( bEnabled
)
254 // register the preview window class
256 ZeroMemory(&wndClsEx
, sizeof(wndClsEx
));
258 wndClsEx
.cbSize
= sizeof(wndClsEx
);
259 wndClsEx
.style
= CS_HREDRAW
| CS_VREDRAW
;
260 wndClsEx
.lpfnWndProc
= CFilePreview::WndProc
;
261 wndClsEx
.hInstance
= m_hInstance
;
262 wndClsEx
.hbrBackground
= (HBRUSH
)( COLOR_INACTIVEBORDER
+ 1 );
263 wndClsEx
.lpszClassName
= PREVIEWWND_CLASS_NAME
;
265 // register the preview window class
266 // !!! Win95 - the window class will be unregistered automaticly
267 // if the dll is unloaded
268 // Win2000 - the window class must be unregistered manually
269 // if the dll is unloaded
270 m_atomPrevWndClass
= RegisterClassEx(&wndClsEx
);
271 if ( !m_atomPrevWndClass
)
272 throw CPreviewException( );
274 // create the preview window in invisible state
275 sal_uInt32 dwStyle
= bShow
? (WS_CHILD
| WS_VISIBLE
) : WS_CHILD
;
276 m_hwnd
= CreateWindowEx(
278 PREVIEWWND_CLASS_NAME
,
286 (HMENU
)100, // for child windows this will
287 // be used as child window identifier
290 if (!IsWindow(m_hwnd
))
291 throw CPreviewException( );
294 //---------------------------------------------------
296 //---------------------------------------------------
298 CFilePreview::~CFilePreview( )
300 // unregister preview window class
301 sal_Bool bRet
= UnregisterClass(
302 (LPCTSTR
)MAKELONG( m_atomPrevWndClass
, 0 ),
304 OSL_POSTCOND( bRet
, "Unregister preview window class failed" );
307 //---------------------------------------------------
308 // sets the size of the preview window
309 //---------------------------------------------------
311 sal_Bool SAL_CALL
CFilePreview::setSize( const CDimension
& aSize
)
313 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
315 // resize the fileopen file listbox
323 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
326 //---------------------------------------------------
327 // returns the dimension of the preview
328 //---------------------------------------------------
330 sal_Bool SAL_CALL
CFilePreview::getSize( CDimension
& theSize
) const
332 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
335 sal_Bool bRet
= GetWindowRect( m_hwnd
, &rect
);
337 theSize
.m_cx
= _getWidthRect( rect
);
338 theSize
.m_cy
= _getHeightRect( rect
);
343 //---------------------------------------------------
344 // sets the position of the upper left corner
345 // of the preview window relative to the
346 // upper left corner of the parent window
347 //---------------------------------------------------
349 sal_Bool SAL_CALL
CFilePreview::setPos( POINT ulCorner
)
351 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
353 // resize the fileopen file listbox
361 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
364 //---------------------------------------------------
365 // returns the current position of the preview
366 // relative to the upper left corner of the
368 //---------------------------------------------------
370 sal_Bool SAL_CALL
CFilePreview::getPos( POINT
& ulCorner
) const
372 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
377 sal_Bool bRet
= GetWindowRect( m_hwnd
, &rect
);
379 ulCorner
.x
= rect
.left
;
380 ulCorner
.y
= rect
.top
;
382 ScreenToClient( m_hwnd
, &ulCorner
);
387 //---------------------------------------------------
389 //---------------------------------------------------
391 void SAL_CALL
CFilePreview::enable( sal_Bool bEnable
)
393 m_bEnabled
= bEnable
;
396 InvalidateRect( m_hwnd
, NULL
, sal_True
);
397 UpdateWindow( m_hwnd
);
400 //---------------------------------------------------
401 // shows the preview window
402 // possible values see SHOW_STATE
403 // SS_SHOW - make the window visible
404 // SS_HIDE - hide the window
405 // SS_ENABLED - enable the window
406 // SS_DISABLED - disable the window
407 //---------------------------------------------------
409 sal_Bool SAL_CALL
CFilePreview::show( sal_Bool bShow
)
411 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
413 sal_Int32 showState
= bShow
? SW_SHOW
: SW_HIDE
;
414 return ShowWindow( m_hwnd
, showState
);
417 //---------------------------------------------------
418 // if the preview is shown and enabled
419 // preview of the given file will be shown
420 // returns true on success or false if an error
421 // occured (the file in not there or not accessible etc.)
422 //---------------------------------------------------
424 sal_Bool SAL_CALL
CFilePreview::update( const rtl::OUString
& aFileName
)
426 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
433 m_IPicture
.Release( );
435 loadFile( aFileName
);
437 // force a complete window redraw
438 InvalidateRect( m_hwnd
, NULL
, sal_True
);
439 UpdateWindow( m_hwnd
);
449 //---------------------------------------------------
451 //---------------------------------------------------
453 void SAL_CALL
CFilePreview::onPaint( HWND hWnd
, HDC hDC
)
455 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
461 // get width and height of picture
465 m_IPicture
->get_Width( &cxPicHIMETRIC
);
466 m_IPicture
->get_Height( &cyPicHIMETRIC
);
468 // convert himetric to pixels
469 int cxPicPIXEL
= Himetric2Pixel( hDC
, cxPicHIMETRIC
, LOGPIXELSX
);
470 int cyPicPIXEL
= Himetric2Pixel( hDC
, cyPicHIMETRIC
, LOGPIXELSY
);
472 // scale the picture based on the size of the preview window
474 GetClientRect(hWnd
, &rcPrevWnd
);
476 CDimension scaledPicSize
= _scalePictureSize(
477 hWnd
, CDimension( cxPicPIXEL
, cyPicPIXEL
) );
479 // calc the upper left corner so that the picture
480 // is centered within the window
481 POINT ulCorner
= _calcULCorner( hWnd
, scaledPicSize
);
483 // render the picture
484 HRESULT hr
= m_IPicture
->Render(
495 } // end if ( m_bEnabled )
502 //---------------------------------------------------
504 //---------------------------------------------------
506 sal_Bool
CFilePreview::loadFile( const rtl::OUString
& aFileName
)
514 sal_uInt32 nBytesRead
;
526 if ( INVALID_HANDLE_VALUE
== hFile
)
527 goto CLEANUP_AND_EXIT
;
530 fsize
= GetFileSize( hFile
, &fszExtra
);
532 // empty file, error or file to big
533 if ( -1 == fsize
|| 0 == fsize
|| fszExtra
)
534 goto CLEANUP_AND_EXIT
;
536 hGlobal
= GlobalAlloc( GMEM_MOVEABLE
, fsize
);
538 goto CLEANUP_AND_EXIT
;
540 pData
= GlobalLock( hGlobal
);
542 goto CLEANUP_AND_EXIT
;
545 hFile
, pData
, fsize
, &nBytesRead
, NULL
);
548 goto CLEANUP_AND_EXIT
;
550 hr
= CreateStreamOnHGlobal(
551 hGlobal
, sal_False
, &pIStream
);
553 if ( SUCCEEDED( hr
) )
556 pIStream
, fsize
, sal_False
,
557 __uuidof( IPicture
), (LPVOID
*)&m_IPicture
);
562 CloseHandle( hFile
);
565 GlobalUnlock( hGlobal
);
568 GlobalFree( hGlobal
);
570 return ( SUCCEEDED( hr
) );
573 //---------------------------------------------------
575 //---------------------------------------------------
577 LRESULT CALLBACK
CFilePreview::WndProc(
578 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
586 OSL_PRECOND( s_FilePreviewInst
, "Static member not initialized" );
591 hDC
= BeginPaint( hWnd
, &ps
);
592 s_FilePreviewInst
->onPaint( hWnd
, hDC
);
593 EndPaint( hWnd
, &ps
);
597 // under windows 95/98 the creation of the
598 // hidden target request window fails if
599 // we don't handle this message ourself
600 // because the DefWindowProc returns 0 as
601 // a result of handling WM_NCCREATE what
602 // leads to a failure of CreateWindow[Ex]!!!
608 return DefWindowProc( hWnd
, uMsg
, wParam
, lParam
);