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: PreviewCtrl.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 "PreviewCtrl.hxx"
40 #include <osl/diagnose.h>
43 #pragma warning(push, 1)
52 //------------------------------------------------------------------------
54 //------------------------------------------------------------------------
56 #define PREVIEWWND_CLASS_NAME TEXT("PreviewWnd###")
58 #define HIMETRIC_INCH 2540
60 // means 3 pixel left and 3 pixel right
61 #define HORZ_BODER_SPACE 6
63 // means 3 pixel top and 3 pixel bottom
64 #define VERT_BORDER_SPACE 6
66 //---------------------------------------------------
67 // static member initialization
68 //---------------------------------------------------
70 CFilePreview
* CFilePreview::s_FilePreviewInst
= NULL
;
71 CFilePreview::FILEPREVIEW_SINGLETON_DESTROYER_T
CFilePreview::s_SingletonDestroyer
;
73 //---------------------------------------------------
74 // some useful helper functions
75 //---------------------------------------------------
79 class CPreviewException
81 // used when registering or creation
82 // of the preview window failed
85 //------------------------------------------------------------
87 //------------------------------------------------------------
90 sal_Int32
SubDiv( sal_Int32 nNumber
, sal_Int32 nMinuend
, sal_Int32 nDenominator
)
92 return ( static_cast<sal_Int32
>( ( nNumber
- nMinuend
) / nDenominator
) );
95 //------------------------------------------------------------
96 // convert himetric to pixel
97 //------------------------------------------------------------
100 sal_Int32
Himetric2Pixel( HDC hDC
, sal_Int32 hmSize
, sal_Int32 nIndex
)
102 return MulDiv( hmSize
, GetDeviceCaps( hDC
, nIndex
), HIMETRIC_INCH
);
105 //------------------------------------------------------------
107 //------------------------------------------------------------
110 sal_uInt32
_getWidthRect( const RECT
& aRect
)
112 return ( aRect
.right
- aRect
.left
);
115 //------------------------------------------------------------
117 //------------------------------------------------------------
120 sal_uInt32
_getHeightRect( const RECT
& aRect
)
122 return ( aRect
.bottom
- aRect
.top
);
125 //------------------------------------------------------------
126 // calc the upper left corner so that a given window will be
127 // displayed centered within the given window
128 //------------------------------------------------------------
131 POINT
_calcULCorner( HWND hwnd
, const CDimension
& aPicSize
)
134 GetClientRect( hwnd
, &rect
);
136 sal_Int32 nWidthWnd
= _getWidthRect( rect
);
137 sal_Int32 nHeightWnd
= _getHeightRect( rect
);
140 ulCorner
.x
= SubDiv( nWidthWnd
, aPicSize
.m_cx
, 2 );
141 ulCorner
.y
= SubDiv( nHeightWnd
, aPicSize
.m_cy
, 2 );
146 //------------------------------------------------------------
147 // test if a picture with the given dimensions fits into an
149 // we expect the width and height to be in pixel
150 //------------------------------------------------------------
153 sal_Bool
_pictureSizeFitsWindowSize( HWND hwnd
, const CDimension
& aPicSize
)
156 GetClientRect( hwnd
, &rect
);
158 sal_Int32 nWidthWnd
= _getWidthRect( rect
);
159 sal_Int32 nHeightWnd
= _getHeightRect( rect
);
161 return ( ( ( nWidthWnd
- HORZ_BODER_SPACE
) >= aPicSize
.m_cx
) &&
162 ( ( nHeightWnd
- VERT_BORDER_SPACE
) >= aPicSize
.m_cy
) );
165 //------------------------------------------------------------
166 // calc the dimemsions so that a given picture fits into a
167 // given window, if the picture fits into the given window
168 // the original CDimension will be returned
169 //------------------------------------------------------------
172 CDimension
_scalePictureSize( HWND hwnd
, const CDimension
& aPicSize
)
174 CDimension scaledPicSize
= aPicSize
;
176 if ( !_pictureSizeFitsWindowSize( hwnd
, aPicSize
) )
179 GetClientRect( hwnd
, &rect
);
181 // the dimensions of the preview wnd are not equal
182 // that's why we equalize it
183 sal_Int32 nHeightWnd
= _getHeightRect( rect
) - VERT_BORDER_SPACE
;
184 sal_Int32 nWidthWnd
= nHeightWnd
;
186 if ( aPicSize
.m_cx
>= aPicSize
.m_cy
)
188 scaledPicSize
.m_cx
= nWidthWnd
;
190 static_cast< sal_Int32
>(
191 aPicSize
.m_cy
* nWidthWnd
/ aPicSize
.m_cx
);
196 static_cast< sal_Int32
>(
197 aPicSize
.m_cx
* nHeightWnd
/ aPicSize
.m_cy
);
198 scaledPicSize
.m_cy
= nHeightWnd
;
202 return scaledPicSize
;
208 //---------------------------------------------------
209 // to ensure only one instance (singleton)
210 //---------------------------------------------------
212 CFilePreview
* CFilePreview::createInstance(
215 const CDimension
& aSize
,
220 if ( !s_FilePreviewInst
)
224 s_FilePreviewInst
= new CFilePreview(
225 aParent
, ulCorner
, aSize
, hInstance
, bShow
, bEnabled
);
226 s_SingletonDestroyer
.reset( s_FilePreviewInst
);
228 catch( CPreviewException
& )
230 OSL_ASSERT( !s_FilePreviewInst
);
231 OSL_ENSURE( sal_False
, "Creation of the preview window failed" );
233 catch( CAutoOleInit::COleInitException
& )
235 OSL_ASSERT( !s_FilePreviewInst
);
236 OSL_ENSURE( sal_False
, "OleInitalize failed" );
240 return s_FilePreviewInst
;
243 //---------------------------------------------------
245 //---------------------------------------------------
247 CFilePreview::CFilePreview(
250 const CDimension
& aSize
,
253 sal_Bool bEnabled
) :
254 m_hInstance( hInstance
),
255 m_bEnabled( bEnabled
)
257 // register the preview window class
259 ZeroMemory(&wndClsEx
, sizeof(wndClsEx
));
261 wndClsEx
.cbSize
= sizeof(wndClsEx
);
262 wndClsEx
.style
= CS_HREDRAW
| CS_VREDRAW
;
263 wndClsEx
.lpfnWndProc
= CFilePreview::WndProc
;
264 wndClsEx
.hInstance
= m_hInstance
;
265 wndClsEx
.hbrBackground
= (HBRUSH
)( COLOR_INACTIVEBORDER
+ 1 );
266 wndClsEx
.lpszClassName
= PREVIEWWND_CLASS_NAME
;
268 // register the preview window class
269 // !!! Win95 - the window class will be unregistered automaticly
270 // if the dll is unloaded
271 // Win2000 - the window class must be unregistered manually
272 // if the dll is unloaded
273 m_atomPrevWndClass
= RegisterClassEx(&wndClsEx
);
274 if ( !m_atomPrevWndClass
)
275 throw CPreviewException( );
277 // create the preview window in invisible state
278 sal_uInt32 dwStyle
= bShow
? (WS_CHILD
| WS_VISIBLE
) : WS_CHILD
;
279 m_hwnd
= CreateWindowEx(
281 PREVIEWWND_CLASS_NAME
,
289 (HMENU
)100, // for child windows this will
290 // be used as child window identifier
293 if (!IsWindow(m_hwnd
))
294 throw CPreviewException( );
297 //---------------------------------------------------
299 //---------------------------------------------------
301 CFilePreview::~CFilePreview( )
303 // unregister preview window class
304 sal_Bool bRet
= UnregisterClass(
305 (LPCTSTR
)MAKELONG( m_atomPrevWndClass
, 0 ),
307 OSL_POSTCOND( bRet
, "Unregister preview window class failed" );
310 //---------------------------------------------------
311 // sets the size of the preview window
312 //---------------------------------------------------
314 sal_Bool SAL_CALL
CFilePreview::setSize( const CDimension
& aSize
)
316 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
318 // resize the fileopen file listbox
326 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
329 //---------------------------------------------------
330 // returns the dimension of the preview
331 //---------------------------------------------------
333 sal_Bool SAL_CALL
CFilePreview::getSize( CDimension
& theSize
) const
335 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
338 sal_Bool bRet
= GetWindowRect( m_hwnd
, &rect
);
340 theSize
.m_cx
= _getWidthRect( rect
);
341 theSize
.m_cy
= _getHeightRect( rect
);
346 //---------------------------------------------------
347 // sets the position of the upper left corner
348 // of the preview window relative to the
349 // upper left corner of the parent window
350 //---------------------------------------------------
352 sal_Bool SAL_CALL
CFilePreview::setPos( POINT ulCorner
)
354 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
356 // resize the fileopen file listbox
364 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
367 //---------------------------------------------------
368 // returns the current position of the preview
369 // relative to the upper left corner of the
371 //---------------------------------------------------
373 sal_Bool SAL_CALL
CFilePreview::getPos( POINT
& ulCorner
) const
375 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
380 sal_Bool bRet
= GetWindowRect( m_hwnd
, &rect
);
382 ulCorner
.x
= rect
.left
;
383 ulCorner
.y
= rect
.top
;
385 ScreenToClient( m_hwnd
, &ulCorner
);
390 //---------------------------------------------------
392 //---------------------------------------------------
394 void SAL_CALL
CFilePreview::enable( sal_Bool bEnable
)
396 m_bEnabled
= bEnable
;
399 InvalidateRect( m_hwnd
, NULL
, TRUE
);
400 UpdateWindow( m_hwnd
);
403 //---------------------------------------------------
404 // shows the preview window
405 // possible values see SHOW_STATE
406 // SS_SHOW - make the window visible
407 // SS_HIDE - hide the window
408 // SS_ENABLED - enable the window
409 // SS_DISABLED - disable the window
410 //---------------------------------------------------
412 sal_Bool SAL_CALL
CFilePreview::show( sal_Bool bShow
)
414 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
416 sal_Int32 showState
= bShow
? SW_SHOW
: SW_HIDE
;
417 return ShowWindow( m_hwnd
, showState
);
420 //---------------------------------------------------
421 // if the preview is shown and enabled
422 // preview of the given file will be shown
423 // returns true on success or false if an error
424 // occured (the file in not there or not accessible etc.)
425 //---------------------------------------------------
427 sal_Bool SAL_CALL
CFilePreview::update( const rtl::OUString
& aFileName
)
429 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
436 m_IPicture
.Release( );
438 loadFile( aFileName
);
440 // force a complete window redraw
441 InvalidateRect( m_hwnd
, NULL
, TRUE
);
442 UpdateWindow( m_hwnd
);
452 //---------------------------------------------------
454 //---------------------------------------------------
456 void SAL_CALL
CFilePreview::onPaint( HWND hWnd
, HDC hDC
)
458 OSL_PRECOND( IsWindow( m_hwnd
), "Preview window not initialized" );
464 // get width and height of picture
468 m_IPicture
->get_Width( &cxPicHIMETRIC
);
469 m_IPicture
->get_Height( &cyPicHIMETRIC
);
471 // convert himetric to pixels
472 int cxPicPIXEL
= Himetric2Pixel( hDC
, cxPicHIMETRIC
, LOGPIXELSX
);
473 int cyPicPIXEL
= Himetric2Pixel( hDC
, cyPicHIMETRIC
, LOGPIXELSY
);
475 // scale the picture based on the size of the preview window
477 GetClientRect(hWnd
, &rcPrevWnd
);
479 CDimension scaledPicSize
= _scalePictureSize(
480 hWnd
, CDimension( cxPicPIXEL
, cyPicPIXEL
) );
482 // calc the upper left corner so that the picture
483 // is centered within the window
484 POINT ulCorner
= _calcULCorner( hWnd
, scaledPicSize
);
486 // render the picture
487 HRESULT hr
= m_IPicture
->Render(
498 } // end if ( m_bEnabled )
505 //---------------------------------------------------
507 //---------------------------------------------------
509 sal_Bool
CFilePreview::loadFile( const rtl::OUString
& aFileName
)
517 sal_uInt32 nBytesRead
;
529 if ( INVALID_HANDLE_VALUE
== hFile
)
530 goto CLEANUP_AND_EXIT
;
533 fsize
= GetFileSize( hFile
, &fszExtra
);
535 // empty file, error or file to big
536 if ( -1 == fsize
|| 0 == fsize
|| fszExtra
)
537 goto CLEANUP_AND_EXIT
;
539 hGlobal
= GlobalAlloc( GMEM_MOVEABLE
, fsize
);
541 goto CLEANUP_AND_EXIT
;
543 pData
= GlobalLock( hGlobal
);
545 goto CLEANUP_AND_EXIT
;
548 hFile
, pData
, fsize
, &nBytesRead
, NULL
);
551 goto CLEANUP_AND_EXIT
;
553 hr
= CreateStreamOnHGlobal(
554 hGlobal
, FALSE
, &pIStream
);
556 if ( SUCCEEDED( hr
) )
559 pIStream
, fsize
, FALSE
,
560 __uuidof( IPicture
), (LPVOID
*)&m_IPicture
);
565 CloseHandle( hFile
);
568 GlobalUnlock( hGlobal
);
571 GlobalFree( hGlobal
);
573 return ( SUCCEEDED( hr
) );
576 //---------------------------------------------------
578 //---------------------------------------------------
580 LRESULT CALLBACK
CFilePreview::WndProc(
581 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
589 OSL_PRECOND( s_FilePreviewInst
, "Static member not initialized" );
594 hDC
= BeginPaint( hWnd
, &ps
);
595 s_FilePreviewInst
->onPaint( hWnd
, hDC
);
596 EndPaint( hWnd
, &ps
);
600 // under windows 95/98 the creation of the
601 // hidden target request window fails if
602 // we don't handle this message ourself
603 // because the DefWindowProc returns 0 as
604 // a result of handling WM_NCCREATE what
605 // leads to a failure of CreateWindow[Ex]!!!
611 return DefWindowProc( hWnd
, uMsg
, wParam
, lParam
);