1b557fc96SAndrew Rist /**************************************************************
2*535d1d4aSmseidel  *
3b557fc96SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b557fc96SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b557fc96SAndrew Rist  * distributed with this work for additional information
6b557fc96SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b557fc96SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b557fc96SAndrew Rist  * "License"); you may not use this file except in compliance
9b557fc96SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*535d1d4aSmseidel  *
11b557fc96SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*535d1d4aSmseidel  *
13b557fc96SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b557fc96SAndrew Rist  * software distributed under the License is distributed on an
15b557fc96SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b557fc96SAndrew Rist  * KIND, either express or implied.  See the License for the
17b557fc96SAndrew Rist  * specific language governing permissions and limitations
18b557fc96SAndrew Rist  * under the License.
19*535d1d4aSmseidel  *
20b557fc96SAndrew Rist  *************************************************************/
21b557fc96SAndrew Rist 
22b557fc96SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_fpicker.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //------------------------------------------------------------------------
28cdf0e10cSrcweir // includes
29cdf0e10cSrcweir //------------------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <tchar.h>
32cdf0e10cSrcweir #include "PreviewCtrl.hxx"
33cdf0e10cSrcweir #include <osl/diagnose.h>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #if defined _MSC_VER
36cdf0e10cSrcweir #pragma warning(push, 1)
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir #include <windows.h>
39cdf0e10cSrcweir #if defined _MSC_VER
40cdf0e10cSrcweir #pragma warning(pop)
41cdf0e10cSrcweir #endif
42cdf0e10cSrcweir #include <ocidl.h>
43cdf0e10cSrcweir #include <olectl.h>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir //------------------------------------------------------------------------
46cdf0e10cSrcweir // defines
47cdf0e10cSrcweir //------------------------------------------------------------------------
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #define PREVIEWWND_CLASS_NAME TEXT("PreviewWnd###")
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #define HIMETRIC_INCH 2540
52cdf0e10cSrcweir 
53cdf0e10cSrcweir // means 3 pixel left and 3 pixel right
54*535d1d4aSmseidel #define HORZ_BORDER_SPACE	6
55cdf0e10cSrcweir 
56cdf0e10cSrcweir // means 3 pixel top and 3 pixel bottom
57*535d1d4aSmseidel #define VERT_BORDER_SPACE	6
58cdf0e10cSrcweir 
59cdf0e10cSrcweir //---------------------------------------------------
60cdf0e10cSrcweir // static member initialization
61cdf0e10cSrcweir //---------------------------------------------------
62cdf0e10cSrcweir 
63cdf0e10cSrcweir CFilePreview* CFilePreview::s_FilePreviewInst = NULL;
64cdf0e10cSrcweir CFilePreview::FILEPREVIEW_SINGLETON_DESTROYER_T CFilePreview::s_SingletonDestroyer;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir //---------------------------------------------------
67cdf0e10cSrcweir // some useful helper functions
68cdf0e10cSrcweir //---------------------------------------------------
69cdf0e10cSrcweir 
70cdf0e10cSrcweir namespace // private
71cdf0e10cSrcweir {
72*535d1d4aSmseidel 	class CPreviewException
73*535d1d4aSmseidel 	{
74*535d1d4aSmseidel 		// used when registering or creation
75*535d1d4aSmseidel 		// of the preview window failed
76*535d1d4aSmseidel 	};
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 	//------------------------------------------------------------
79cdf0e10cSrcweir 	//
80cdf0e10cSrcweir 	//------------------------------------------------------------
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 	inline
SubDiv(sal_Int32 nNumber,sal_Int32 nMinuend,sal_Int32 nDenominator)83cdf0e10cSrcweir 	sal_Int32 SubDiv( sal_Int32	nNumber, sal_Int32 nMinuend, sal_Int32 nDenominator )
84cdf0e10cSrcweir 	{
85cdf0e10cSrcweir 		return ( static_cast<sal_Int32>( ( nNumber - nMinuend ) / nDenominator ) );
86cdf0e10cSrcweir 	}
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	//------------------------------------------------------------
89cdf0e10cSrcweir 	// convert himetric to pixel
90cdf0e10cSrcweir 	//------------------------------------------------------------
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 	inline
Himetric2Pixel(HDC hDC,sal_Int32 hmSize,sal_Int32 nIndex)93cdf0e10cSrcweir 	sal_Int32 Himetric2Pixel( HDC hDC, sal_Int32 hmSize, sal_Int32 nIndex )
94cdf0e10cSrcweir 	{
95cdf0e10cSrcweir 		return MulDiv( hmSize, GetDeviceCaps( hDC, nIndex), HIMETRIC_INCH );
96cdf0e10cSrcweir 	}
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 	//------------------------------------------------------------
99cdf0e10cSrcweir 	//
100cdf0e10cSrcweir 	//------------------------------------------------------------
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	inline
_getWidthRect(const RECT & aRect)103cdf0e10cSrcweir 	sal_uInt32 _getWidthRect( const RECT& aRect )
104cdf0e10cSrcweir 	{
105cdf0e10cSrcweir 		return ( aRect.right - aRect.left );
106cdf0e10cSrcweir 	}
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 	//------------------------------------------------------------
109cdf0e10cSrcweir 	//
110cdf0e10cSrcweir 	//------------------------------------------------------------
111cdf0e10cSrcweir 
112*535d1d4aSmseidel 	inline
_getHeightRect(const RECT & aRect)113cdf0e10cSrcweir 	sal_uInt32 _getHeightRect( const RECT& aRect )
114cdf0e10cSrcweir 	{
115cdf0e10cSrcweir 		return ( aRect.bottom - aRect.top );
116cdf0e10cSrcweir 	}
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 	//------------------------------------------------------------
119cdf0e10cSrcweir 	// calc the upper left corner so that a given window will be
120cdf0e10cSrcweir 	// displayed centered within the given window
121cdf0e10cSrcweir 	//------------------------------------------------------------
122cdf0e10cSrcweir 
123*535d1d4aSmseidel 	inline
_calcULCorner(HWND hwnd,const CDimension & aPicSize)124cdf0e10cSrcweir 	POINT _calcULCorner( HWND hwnd, const CDimension& aPicSize )
125cdf0e10cSrcweir 	{
126cdf0e10cSrcweir 		RECT rect;
127cdf0e10cSrcweir 		GetClientRect( hwnd, &rect );
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 		sal_Int32 nWidthWnd  = _getWidthRect( rect );
130cdf0e10cSrcweir 		sal_Int32 nHeightWnd = _getHeightRect( rect );
131*535d1d4aSmseidel 
132cdf0e10cSrcweir 		POINT ulCorner;
133cdf0e10cSrcweir 		ulCorner.x = SubDiv( nWidthWnd,  aPicSize.m_cx, 2 );
134cdf0e10cSrcweir 		ulCorner.y = SubDiv( nHeightWnd, aPicSize.m_cy, 2 );
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 		return ulCorner;
137cdf0e10cSrcweir 	}
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 	//------------------------------------------------------------
140cdf0e10cSrcweir 	// test if a picture with the given dimensions fits into an
141cdf0e10cSrcweir 	// arbitrary window
142cdf0e10cSrcweir 	// we expect the width and height to be in pixel
143cdf0e10cSrcweir 	//------------------------------------------------------------
144*535d1d4aSmseidel 
145cdf0e10cSrcweir 	inline
_pictureSizeFitsWindowSize(HWND hwnd,const CDimension & aPicSize)146cdf0e10cSrcweir 	sal_Bool _pictureSizeFitsWindowSize( HWND hwnd, const CDimension& aPicSize )
147cdf0e10cSrcweir 	{
148cdf0e10cSrcweir 		RECT rect;
149cdf0e10cSrcweir 		GetClientRect( hwnd, &rect );
150*535d1d4aSmseidel 
151cdf0e10cSrcweir 		sal_Int32 nWidthWnd  = _getWidthRect( rect );
152cdf0e10cSrcweir 		sal_Int32 nHeightWnd = _getHeightRect( rect );
153cdf0e10cSrcweir 
154*535d1d4aSmseidel 		return ( ( ( nWidthWnd  - HORZ_BORDER_SPACE ) >= aPicSize.m_cx ) &&
155cdf0e10cSrcweir 				 ( ( nHeightWnd - VERT_BORDER_SPACE ) >= aPicSize.m_cy ) );
156cdf0e10cSrcweir 	}
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 	//------------------------------------------------------------
159*535d1d4aSmseidel 	// calc the dimensions so that a given picture fits into a
160cdf0e10cSrcweir 	// given window, if the picture fits into the given window
161cdf0e10cSrcweir 	// the original CDimension will be returned
162cdf0e10cSrcweir 	//------------------------------------------------------------
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 	inline
_scalePictureSize(HWND hwnd,const CDimension & aPicSize)165cdf0e10cSrcweir 	CDimension _scalePictureSize( HWND hwnd, const CDimension& aPicSize )
166cdf0e10cSrcweir 	{
167cdf0e10cSrcweir 		CDimension scaledPicSize = aPicSize;
168*535d1d4aSmseidel 
169cdf0e10cSrcweir 		if ( !_pictureSizeFitsWindowSize( hwnd, aPicSize ) )
170cdf0e10cSrcweir 		{
171cdf0e10cSrcweir 			RECT rect;
172cdf0e10cSrcweir 			GetClientRect( hwnd, &rect );
173*535d1d4aSmseidel 
174*535d1d4aSmseidel 			// the dimensions of the preview wnd are not equal
175cdf0e10cSrcweir 			// that's why we equalize it
176cdf0e10cSrcweir 			sal_Int32 nHeightWnd = _getHeightRect( rect ) - VERT_BORDER_SPACE;
177cdf0e10cSrcweir 			sal_Int32 nWidthWnd  = nHeightWnd;
178cdf0e10cSrcweir 
179cdf0e10cSrcweir 			if ( aPicSize.m_cx >= aPicSize.m_cy )
180cdf0e10cSrcweir 			{
181cdf0e10cSrcweir 				scaledPicSize.m_cx = nWidthWnd;
182*535d1d4aSmseidel 				scaledPicSize.m_cy =
183*535d1d4aSmseidel 					static_cast< sal_Int32 >(
184*535d1d4aSmseidel                         aPicSize.m_cy * nWidthWnd / aPicSize.m_cx );
185cdf0e10cSrcweir 			}
186cdf0e10cSrcweir 			else
187cdf0e10cSrcweir 			{
188*535d1d4aSmseidel 				scaledPicSize.m_cx =
189*535d1d4aSmseidel 					static_cast< sal_Int32 >(
190cdf0e10cSrcweir                         aPicSize.m_cx * nHeightWnd / aPicSize.m_cy );
191cdf0e10cSrcweir 				scaledPicSize.m_cy = nHeightWnd;
192cdf0e10cSrcweir 			}
193cdf0e10cSrcweir 		}
194cdf0e10cSrcweir 
195cdf0e10cSrcweir 		return scaledPicSize;
196cdf0e10cSrcweir 	}
197cdf0e10cSrcweir 
198cdf0e10cSrcweir } // end namespace
199cdf0e10cSrcweir 
200*535d1d4aSmseidel 
201cdf0e10cSrcweir //---------------------------------------------------
202cdf0e10cSrcweir // to ensure only one instance (singleton)
203cdf0e10cSrcweir //---------------------------------------------------
204cdf0e10cSrcweir 
createInstance(HWND aParent,POINT ulCorner,const CDimension & aSize,HINSTANCE hInstance,sal_Bool bShow,sal_Bool bEnabled)205*535d1d4aSmseidel CFilePreview* CFilePreview::createInstance(
206*535d1d4aSmseidel 	HWND aParent,
207*535d1d4aSmseidel 	POINT ulCorner,
208*535d1d4aSmseidel 	const CDimension& aSize,
209*535d1d4aSmseidel 	HINSTANCE hInstance,
210*535d1d4aSmseidel 	sal_Bool bShow,
211*535d1d4aSmseidel 	sal_Bool bEnabled )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir 	if ( !s_FilePreviewInst )
214cdf0e10cSrcweir 	{
215cdf0e10cSrcweir         try
216cdf0e10cSrcweir         {
217*535d1d4aSmseidel 		    s_FilePreviewInst = new CFilePreview(
218cdf0e10cSrcweir 			    aParent, ulCorner, aSize, hInstance, bShow, bEnabled );
219cdf0e10cSrcweir 		    s_SingletonDestroyer.reset( s_FilePreviewInst );
220cdf0e10cSrcweir         }
221cdf0e10cSrcweir         catch( CPreviewException& )
222cdf0e10cSrcweir         {
223cdf0e10cSrcweir             OSL_ASSERT( !s_FilePreviewInst );
224cdf0e10cSrcweir             OSL_ENSURE( sal_False, "Creation of the preview window failed" );
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir         catch( CAutoOleInit::COleInitException& )
227cdf0e10cSrcweir         {
228cdf0e10cSrcweir             OSL_ASSERT( !s_FilePreviewInst );
229437a6594Smseidel             OSL_ENSURE( sal_False, "OleInitialize failed" );
230cdf0e10cSrcweir         }
231cdf0e10cSrcweir 	}
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 	return s_FilePreviewInst;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir //---------------------------------------------------
237cdf0e10cSrcweir //
238cdf0e10cSrcweir //---------------------------------------------------
239cdf0e10cSrcweir 
CFilePreview(HWND aParent,POINT ulCorner,const CDimension & aSize,HINSTANCE hInstance,sal_Bool bShow,sal_Bool bEnabled)240*535d1d4aSmseidel CFilePreview::CFilePreview(
241*535d1d4aSmseidel 	HWND aParent,
242*535d1d4aSmseidel 	POINT ulCorner,
243*535d1d4aSmseidel 	const CDimension& aSize,
244*535d1d4aSmseidel 	HINSTANCE hInstance,
245*535d1d4aSmseidel 	sal_Bool bShow,
246*535d1d4aSmseidel 	sal_Bool bEnabled ) :
247cdf0e10cSrcweir 	m_hInstance( hInstance ),
248cdf0e10cSrcweir 	m_bEnabled( bEnabled )
249cdf0e10cSrcweir {
250*535d1d4aSmseidel 	// register the preview window class
251*535d1d4aSmseidel 	WNDCLASSEX wndClsEx;
252cdf0e10cSrcweir 	ZeroMemory(&wndClsEx, sizeof(wndClsEx));
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 	wndClsEx.cbSize        = sizeof(wndClsEx);
255cdf0e10cSrcweir 	wndClsEx.style		   = CS_HREDRAW | CS_VREDRAW;
256cdf0e10cSrcweir 	wndClsEx.lpfnWndProc   = CFilePreview::WndProc;
257cdf0e10cSrcweir 	wndClsEx.hInstance     = m_hInstance;
258cdf0e10cSrcweir 	wndClsEx.hbrBackground = (HBRUSH)( COLOR_INACTIVEBORDER + 1 );
259cdf0e10cSrcweir 	wndClsEx.lpszClassName = PREVIEWWND_CLASS_NAME;
260*535d1d4aSmseidel 
261cdf0e10cSrcweir 	// register the preview window class
262*535d1d4aSmseidel 	// !!! Win95 -   the window class will be unregistered automatically
263cdf0e10cSrcweir 	//			     if the dll is unloaded
264cdf0e10cSrcweir 	//     Win2000 - the window class must be unregistered manually
265cdf0e10cSrcweir 	//				 if the dll is unloaded
266cdf0e10cSrcweir 	m_atomPrevWndClass = RegisterClassEx(&wndClsEx);
267cdf0e10cSrcweir     if ( !m_atomPrevWndClass )
268cdf0e10cSrcweir         throw CPreviewException( );
269*535d1d4aSmseidel 
270cdf0e10cSrcweir 	// create the preview window in invisible state
271cdf0e10cSrcweir 	sal_uInt32 dwStyle = bShow ? (WS_CHILD | WS_VISIBLE) : WS_CHILD;
272*535d1d4aSmseidel 	m_hwnd = CreateWindowEx(
273*535d1d4aSmseidel 		WS_EX_CLIENTEDGE,
274*535d1d4aSmseidel 		PREVIEWWND_CLASS_NAME,
275cdf0e10cSrcweir 		TEXT(""),
276cdf0e10cSrcweir 		dwStyle,
277cdf0e10cSrcweir 		ulCorner.x,
278cdf0e10cSrcweir 		ulCorner.y,
279cdf0e10cSrcweir 		aSize.m_cx,
280cdf0e10cSrcweir 		aSize.m_cy,
281cdf0e10cSrcweir 		aParent,
282*535d1d4aSmseidel 		(HMENU)100, // for child windows this will
283cdf0e10cSrcweir 					// be used as child window identifier
284cdf0e10cSrcweir 		m_hInstance,
285cdf0e10cSrcweir 		0 );
286cdf0e10cSrcweir     if (!IsWindow(m_hwnd))
287cdf0e10cSrcweir         throw CPreviewException( );
288cdf0e10cSrcweir }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir //---------------------------------------------------
291cdf0e10cSrcweir //
292cdf0e10cSrcweir //---------------------------------------------------
293cdf0e10cSrcweir 
~CFilePreview()294cdf0e10cSrcweir CFilePreview::~CFilePreview( )
295*535d1d4aSmseidel {
296cdf0e10cSrcweir 	// unregister preview window class
297*535d1d4aSmseidel 	sal_Bool bRet = UnregisterClass(
298cdf0e10cSrcweir 		(LPCTSTR)MAKELONG( m_atomPrevWndClass, 0 ),
299cdf0e10cSrcweir 		m_hInstance );
300*535d1d4aSmseidel 	OSL_POSTCOND( bRet, "Unregister preview window class failed" );
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir //---------------------------------------------------
304cdf0e10cSrcweir // sets the size of the preview window
305cdf0e10cSrcweir //---------------------------------------------------
306cdf0e10cSrcweir 
setSize(const CDimension & aSize)307cdf0e10cSrcweir sal_Bool SAL_CALL CFilePreview::setSize( const CDimension& aSize )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir 	OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" );
310*535d1d4aSmseidel 
311cdf0e10cSrcweir 	// resize the fileopen file listbox
312*535d1d4aSmseidel 	return SetWindowPos(
313*535d1d4aSmseidel 		m_hwnd,
314*535d1d4aSmseidel 		NULL,
315*535d1d4aSmseidel 		0,
316*535d1d4aSmseidel 		0,
317*535d1d4aSmseidel 		aSize.m_cx,
318*535d1d4aSmseidel 		aSize.m_cy,
319cdf0e10cSrcweir 		SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
320cdf0e10cSrcweir }
321cdf0e10cSrcweir 
322*535d1d4aSmseidel //---------------------------------------------------
323cdf0e10cSrcweir // returns the dimension of the preview
324cdf0e10cSrcweir //---------------------------------------------------
325cdf0e10cSrcweir 
getSize(CDimension & theSize) const326cdf0e10cSrcweir sal_Bool SAL_CALL CFilePreview::getSize( CDimension& theSize ) const
327cdf0e10cSrcweir {
328cdf0e10cSrcweir 	OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" );
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 	RECT rect;
331cdf0e10cSrcweir 	sal_Bool bRet = GetWindowRect( m_hwnd, &rect );
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 	theSize.m_cx = _getWidthRect( rect );
334cdf0e10cSrcweir 	theSize.m_cy = _getHeightRect( rect );
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 	return bRet;
337cdf0e10cSrcweir }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir //---------------------------------------------------
340*535d1d4aSmseidel // sets the position of the upper left corner
341cdf0e10cSrcweir // of the preview window relative to the
342cdf0e10cSrcweir // upper left corner of the parent window
343cdf0e10cSrcweir //---------------------------------------------------
344cdf0e10cSrcweir 
setPos(POINT ulCorner)345cdf0e10cSrcweir sal_Bool SAL_CALL CFilePreview::setPos( POINT ulCorner )
346cdf0e10cSrcweir {
347cdf0e10cSrcweir 	OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" );
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 	// resize the fileopen file listbox
350*535d1d4aSmseidel 	return SetWindowPos(
351*535d1d4aSmseidel 		m_hwnd,
352*535d1d4aSmseidel 		NULL,
353*535d1d4aSmseidel 		ulCorner.x,
354*535d1d4aSmseidel 		ulCorner.y,
355*535d1d4aSmseidel 		0,
356*535d1d4aSmseidel 		0,
357cdf0e10cSrcweir 		SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir //---------------------------------------------------
361cdf0e10cSrcweir // returns the current position of the preview
362cdf0e10cSrcweir // relative to the upper left corner of the
363cdf0e10cSrcweir // parent window
364cdf0e10cSrcweir //---------------------------------------------------
365cdf0e10cSrcweir 
getPos(POINT & ulCorner) const366cdf0e10cSrcweir sal_Bool SAL_CALL CFilePreview::getPos( POINT& ulCorner ) const
367cdf0e10cSrcweir {
368cdf0e10cSrcweir 	OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" );
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 	POINT pt = { 0, 0 };
371cdf0e10cSrcweir 	RECT rect;
372cdf0e10cSrcweir 
373cdf0e10cSrcweir 	sal_Bool bRet = GetWindowRect( m_hwnd, &rect );
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 	ulCorner.x = rect.left;
376cdf0e10cSrcweir 	ulCorner.y = rect.top;
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 	ScreenToClient( m_hwnd, &ulCorner );
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 	return bRet;
381cdf0e10cSrcweir }
382cdf0e10cSrcweir 
383cdf0e10cSrcweir //---------------------------------------------------
384*535d1d4aSmseidel //
385cdf0e10cSrcweir //---------------------------------------------------
386cdf0e10cSrcweir 
enable(sal_Bool bEnable)387cdf0e10cSrcweir void SAL_CALL CFilePreview::enable( sal_Bool bEnable )
388cdf0e10cSrcweir {
389cdf0e10cSrcweir 	m_bEnabled = bEnable;
390*535d1d4aSmseidel 
391cdf0e10cSrcweir 	// force a redraw
392cdf0e10cSrcweir 	InvalidateRect( m_hwnd, NULL, sal_True );
393*535d1d4aSmseidel 	UpdateWindow( m_hwnd );
394cdf0e10cSrcweir }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir //---------------------------------------------------
397cdf0e10cSrcweir // shows the preview window
398cdf0e10cSrcweir // possible values see SHOW_STATE
399cdf0e10cSrcweir // SS_SHOW     - make the window visible
400cdf0e10cSrcweir // SS_HIDE     - hide the window
401cdf0e10cSrcweir // SS_ENABLED  - enable the window
402cdf0e10cSrcweir // SS_DISABLED - disable the window
403cdf0e10cSrcweir //---------------------------------------------------
404cdf0e10cSrcweir 
show(sal_Bool bShow)405cdf0e10cSrcweir sal_Bool SAL_CALL CFilePreview::show( sal_Bool bShow )
406cdf0e10cSrcweir {
407cdf0e10cSrcweir 	OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" );
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 	sal_Int32 showState = bShow ? SW_SHOW : SW_HIDE;
410cdf0e10cSrcweir 	return ShowWindow( m_hwnd, showState );
411cdf0e10cSrcweir }
412cdf0e10cSrcweir 
413*535d1d4aSmseidel //---------------------------------------------------
414*535d1d4aSmseidel // if the preview is shown and enabled
415cdf0e10cSrcweir // preview of the given file will be shown
416cdf0e10cSrcweir // returns true on success or false if an error
41707a3d7f1SPedro Giffuni // occurred (the file in not there or not accessible etc.)
418cdf0e10cSrcweir //---------------------------------------------------
419cdf0e10cSrcweir 
update(const rtl::OUString & aFileName)420cdf0e10cSrcweir sal_Bool SAL_CALL CFilePreview::update( const rtl::OUString& aFileName )
421*535d1d4aSmseidel {
422cdf0e10cSrcweir 	OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" );
423cdf0e10cSrcweir 
424cdf0e10cSrcweir 	try
425cdf0e10cSrcweir 	{
426cdf0e10cSrcweir 		if ( m_bEnabled )
427*535d1d4aSmseidel 		{
428cdf0e10cSrcweir 			if ( m_IPicture )
429cdf0e10cSrcweir 				m_IPicture.Release( );
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 			loadFile( aFileName );
432*535d1d4aSmseidel 
433cdf0e10cSrcweir 			// force a complete window redraw
434cdf0e10cSrcweir 			InvalidateRect( m_hwnd, NULL, sal_True );
435*535d1d4aSmseidel 			UpdateWindow( m_hwnd );
436cdf0e10cSrcweir 		}
437*535d1d4aSmseidel 	}
438cdf0e10cSrcweir 	catch( _com_error& )
439*535d1d4aSmseidel 	{
440cdf0e10cSrcweir 	}
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 	return sal_True;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir //---------------------------------------------------
446cdf0e10cSrcweir //
447cdf0e10cSrcweir //---------------------------------------------------
448cdf0e10cSrcweir 
onPaint(HWND hWnd,HDC hDC)449cdf0e10cSrcweir void SAL_CALL CFilePreview::onPaint( HWND hWnd, HDC hDC )
450cdf0e10cSrcweir {
451cdf0e10cSrcweir 	OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" );
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 	try
454*535d1d4aSmseidel 	{
455*535d1d4aSmseidel 		if ( m_bEnabled )
456cdf0e10cSrcweir 		{
457cdf0e10cSrcweir 			// get width and height of picture
458cdf0e10cSrcweir 			long cxPicHIMETRIC;
459cdf0e10cSrcweir 			long cyPicHIMETRIC;
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 			m_IPicture->get_Width( &cxPicHIMETRIC );
462cdf0e10cSrcweir 			m_IPicture->get_Height( &cyPicHIMETRIC );
463*535d1d4aSmseidel 
464cdf0e10cSrcweir 			// convert himetric to pixels
465*535d1d4aSmseidel 			int cxPicPIXEL = Himetric2Pixel( hDC, cxPicHIMETRIC, LOGPIXELSX );
466*535d1d4aSmseidel 			int cyPicPIXEL = Himetric2Pixel( hDC, cyPicHIMETRIC, LOGPIXELSY );
467*535d1d4aSmseidel 
468cdf0e10cSrcweir 			// scale the picture based on the size of the preview window
469cdf0e10cSrcweir 			RECT rcPrevWnd;
470cdf0e10cSrcweir 			GetClientRect(hWnd, &rcPrevWnd);
471cdf0e10cSrcweir 
472*535d1d4aSmseidel 			CDimension scaledPicSize = _scalePictureSize(
473cdf0e10cSrcweir 				hWnd, CDimension( cxPicPIXEL, cyPicPIXEL ) );
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 			// calc the upper left corner so that the picture
476cdf0e10cSrcweir 			// is centered within the window
477cdf0e10cSrcweir 			POINT ulCorner = _calcULCorner( hWnd, scaledPicSize );
478cdf0e10cSrcweir 
479cdf0e10cSrcweir 			// render the picture
480cdf0e10cSrcweir 			HRESULT hr = m_IPicture->Render(
481cdf0e10cSrcweir 				hDC,
482cdf0e10cSrcweir 				ulCorner.x,
483cdf0e10cSrcweir 				ulCorner.y,
484cdf0e10cSrcweir 				scaledPicSize.m_cx,
485cdf0e10cSrcweir 				scaledPicSize.m_cy,
486cdf0e10cSrcweir 				0,
487cdf0e10cSrcweir 				cyPicHIMETRIC,
488cdf0e10cSrcweir 				cxPicHIMETRIC,
489cdf0e10cSrcweir 				-cyPicHIMETRIC,
490*535d1d4aSmseidel 				&rcPrevWnd );
491cdf0e10cSrcweir 		} // end if ( m_bEnabled )
492cdf0e10cSrcweir 	}
493cdf0e10cSrcweir 	catch( _com_error& )
494*535d1d4aSmseidel 	{
495cdf0e10cSrcweir 	}
496cdf0e10cSrcweir }
497cdf0e10cSrcweir 
498cdf0e10cSrcweir //---------------------------------------------------
499cdf0e10cSrcweir //
500cdf0e10cSrcweir //---------------------------------------------------
501*535d1d4aSmseidel 
loadFile(const rtl::OUString & aFileName)502cdf0e10cSrcweir sal_Bool CFilePreview::loadFile( const rtl::OUString& aFileName )
503cdf0e10cSrcweir {
504cdf0e10cSrcweir 	HANDLE		hFile   = 0;
505cdf0e10cSrcweir 	HGLOBAL		hGlobal = 0;
506cdf0e10cSrcweir 	LPVOID		pData   = NULL;
507cdf0e10cSrcweir 	IStreamPtr	pIStream;
508cdf0e10cSrcweir 	HRESULT		hr = E_FAIL;
509cdf0e10cSrcweir 	sal_Bool	bRet;
510cdf0e10cSrcweir 	sal_uInt32	nBytesRead;
511*535d1d4aSmseidel 	sal_uInt32	fszExtra;
512*535d1d4aSmseidel 	sal_uInt32	fsize;
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 	hFile = CreateFile(
515cdf0e10cSrcweir 		aFileName.getStr( ),
516cdf0e10cSrcweir 		GENERIC_READ,
517cdf0e10cSrcweir 		0,
518cdf0e10cSrcweir 		NULL,
519cdf0e10cSrcweir 		OPEN_EXISTING,
520cdf0e10cSrcweir 		0,
521cdf0e10cSrcweir 		NULL );
522cdf0e10cSrcweir 	if ( INVALID_HANDLE_VALUE == hFile )
523cdf0e10cSrcweir 		goto CLEANUP_AND_EXIT;
524cdf0e10cSrcweir 
525cdf0e10cSrcweir 	fszExtra = 0;
526*535d1d4aSmseidel 	fsize = GetFileSize( hFile, &fszExtra );
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 	// empty file, error or file to big
529*535d1d4aSmseidel 	if ( -1 == fsize || 0 == fsize || fszExtra )
530cdf0e10cSrcweir 		goto CLEANUP_AND_EXIT;
531cdf0e10cSrcweir 
532cdf0e10cSrcweir 	hGlobal = GlobalAlloc( GMEM_MOVEABLE, fsize );
533cdf0e10cSrcweir 	if ( !hGlobal )
534cdf0e10cSrcweir 		goto CLEANUP_AND_EXIT;
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 	pData = GlobalLock( hGlobal );
537cdf0e10cSrcweir 	if ( !pData )
538cdf0e10cSrcweir 		goto CLEANUP_AND_EXIT;
539*535d1d4aSmseidel 
540cdf0e10cSrcweir 	bRet = ReadFile(
541cdf0e10cSrcweir 		hFile, pData, fsize, &nBytesRead, NULL );
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 	if ( !bRet )
544cdf0e10cSrcweir 		goto CLEANUP_AND_EXIT;
545*535d1d4aSmseidel 
546cdf0e10cSrcweir 	hr = CreateStreamOnHGlobal(
547cdf0e10cSrcweir 		hGlobal, sal_False, &pIStream );
548cdf0e10cSrcweir 
549cdf0e10cSrcweir 	if ( SUCCEEDED( hr ) )
550cdf0e10cSrcweir 	{
551cdf0e10cSrcweir 		hr = OleLoadPicture(
552*535d1d4aSmseidel 			pIStream, fsize, sal_False,
553cdf0e10cSrcweir 			__uuidof( IPicture ), (LPVOID*)&m_IPicture );
554cdf0e10cSrcweir 	}
555*535d1d4aSmseidel 
556cdf0e10cSrcweir CLEANUP_AND_EXIT:
557cdf0e10cSrcweir 	if ( hFile )
558cdf0e10cSrcweir 		CloseHandle( hFile );
559cdf0e10cSrcweir 
560cdf0e10cSrcweir 	if ( pData )
561cdf0e10cSrcweir 		GlobalUnlock( hGlobal );
562cdf0e10cSrcweir 
563cdf0e10cSrcweir 	if ( hGlobal )
564cdf0e10cSrcweir 		GlobalFree( hGlobal );
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 	return ( SUCCEEDED( hr ) );
567cdf0e10cSrcweir }
568cdf0e10cSrcweir 
569cdf0e10cSrcweir //---------------------------------------------------
570cdf0e10cSrcweir //
571cdf0e10cSrcweir //---------------------------------------------------
572*535d1d4aSmseidel 
WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)573*535d1d4aSmseidel LRESULT CALLBACK CFilePreview::WndProc(
574*535d1d4aSmseidel 	HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
575cdf0e10cSrcweir {
576cdf0e10cSrcweir 	LRESULT lResult = 0;
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 	switch( uMsg )
579cdf0e10cSrcweir 	{
580cdf0e10cSrcweir 	case WM_PAINT:
581cdf0e10cSrcweir 	{
582cdf0e10cSrcweir 		OSL_PRECOND( s_FilePreviewInst, "Static member not initialized" );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir 		HDC         hDC;
585*535d1d4aSmseidel 		PAINTSTRUCT ps;
586cdf0e10cSrcweir 
587cdf0e10cSrcweir 		hDC = BeginPaint( hWnd, &ps );
588cdf0e10cSrcweir 		s_FilePreviewInst->onPaint( hWnd, hDC );
589cdf0e10cSrcweir 		EndPaint( hWnd, &ps );
590cdf0e10cSrcweir 	}
591cdf0e10cSrcweir 	break;
592cdf0e10cSrcweir 
593*535d1d4aSmseidel 	// under windows 95/98 the creation of the
594*535d1d4aSmseidel 		// hidden target request window fails if
595cdf0e10cSrcweir 		// we don't handle this message ourself
596cdf0e10cSrcweir 		// because the DefWindowProc returns 0 as
597cdf0e10cSrcweir 		// a result of handling WM_NCCREATE what
598cdf0e10cSrcweir 		// leads to a failure of CreateWindow[Ex]!!!
599cdf0e10cSrcweir 	case WM_NCCREATE:
600cdf0e10cSrcweir 		lResult = sal_True;
601cdf0e10cSrcweir 		break;
602cdf0e10cSrcweir 
603cdf0e10cSrcweir 	default:
604cdf0e10cSrcweir 		return DefWindowProc( hWnd, uMsg, wParam, lParam );
605cdf0e10cSrcweir 	}
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 	return lResult;
608cdf0e10cSrcweir }
609cdf0e10cSrcweir 
610