1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_fpicker.hxx"
30*cdf0e10cSrcweir #include <osl/diagnose.h>
31*cdf0e10cSrcweir #include <osl/conditn.hxx>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "MtaFop.hxx"
34*cdf0e10cSrcweir #include <wchar.h>
35*cdf0e10cSrcweir #include <process.h>
36*cdf0e10cSrcweir #include "..\misc\resourceprovider.hxx"
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include <systools/win32/comtools.hxx>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir using rtl::OUString;
41*cdf0e10cSrcweir using osl::Condition;
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir const sal_uInt32 MSG_BROWSEFORFOLDER = WM_USER + 1;
44*cdf0e10cSrcweir const sal_uInt32 MSG_SHUTDOWN        = WM_USER + 2;
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir const sal_uInt32 MAX_WAITTIME		 = 2000; // msec
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir const sal_Bool MANUAL_RESET     = sal_True;
49*cdf0e10cSrcweir const sal_Bool AUTO_RESET       = sal_False;
50*cdf0e10cSrcweir const sal_Bool INIT_NONSIGNALED = sal_False;
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir typedef sal::systools::COMReference<IMalloc> IMallocPtr;
53*cdf0e10cSrcweir typedef sal::systools::COMReference<IShellFolder> IShellFolderPtr;
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir namespace
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir 	const char* FOLDERPICKER_SRV_DLL_NAME = "fop.dll";
58*cdf0e10cSrcweir 	const char g_szWndClsName[]			  = "FopStaReqWnd###";
59*cdf0e10cSrcweir     const char* CURRENT_INSTANCE          = "CurrInst";
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir     typedef struct _RequestContext
62*cdf0e10cSrcweir     {
63*cdf0e10cSrcweir 	    HANDLE	 hEvent;
64*cdf0e10cSrcweir 	    sal_Bool bRet;
65*cdf0e10cSrcweir     } RequestContext;
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir     inline sal_Bool InitializeRequestContext( RequestContext* aRequestContext )
68*cdf0e10cSrcweir     {
69*cdf0e10cSrcweir         OSL_ASSERT( aRequestContext );
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir         aRequestContext->hEvent = CreateEventA(
72*cdf0e10cSrcweir             0, AUTO_RESET, INIT_NONSIGNALED, NULL );
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir 	    aRequestContext->bRet = sal_False;
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir         return ( 0 != aRequestContext->hEvent );
77*cdf0e10cSrcweir     }
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir     inline void DeinitializeRequestContext( RequestContext* aRequestContext )
80*cdf0e10cSrcweir     {
81*cdf0e10cSrcweir         OSL_ASSERT( aRequestContext && aRequestContext->hEvent );
82*cdf0e10cSrcweir         CloseHandle( aRequestContext->hEvent );
83*cdf0e10cSrcweir     }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir     //-------------------------------
86*cdf0e10cSrcweir     // Determine if current thread is
87*cdf0e10cSrcweir     // an MTA or STA thread
88*cdf0e10cSrcweir     //-------------------------------
89*cdf0e10cSrcweir     bool IsMTA()
90*cdf0e10cSrcweir     {
91*cdf0e10cSrcweir 	    HRESULT hr = CoInitialize(NULL);
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir 	    if (RPC_E_CHANGED_MODE == hr)
94*cdf0e10cSrcweir 		    return true;
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 	    if(SUCCEEDED(hr))
97*cdf0e10cSrcweir 		    CoUninitialize();
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir 	    return false;
100*cdf0e10cSrcweir     }
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir //----------------------------------------------------------------
104*cdf0e10cSrcweir //	static member initialization
105*cdf0e10cSrcweir //----------------------------------------------------------------
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir ATOM CMtaFolderPicker::s_ClassAtom = 0;
108*cdf0e10cSrcweir osl::Mutex CMtaFolderPicker::s_Mutex;
109*cdf0e10cSrcweir sal_Int32 CMtaFolderPicker::s_StaRequestWndRegisterCount = 0;
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir //--------------------------------------------------------------------
112*cdf0e10cSrcweir // ctor
113*cdf0e10cSrcweir //--------------------------------------------------------------------
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir CMtaFolderPicker::CMtaFolderPicker( sal_uInt32 Flags ) :
116*cdf0e10cSrcweir 	m_hStaThread( NULL ),
117*cdf0e10cSrcweir 	m_uStaThreadId( 0 ),
118*cdf0e10cSrcweir 	m_hEvtThrdReady( NULL ),
119*cdf0e10cSrcweir 	m_hwndStaRequestWnd( NULL )
120*cdf0e10cSrcweir {
121*cdf0e10cSrcweir     m_hInstance = GetModuleHandleA( FOLDERPICKER_SRV_DLL_NAME );
122*cdf0e10cSrcweir 	OSL_ENSURE( m_hInstance, "The name of the FolderPicker service dll must have changed" );
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 	ZeroMemory( &m_bi, sizeof( m_bi ) );
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir     // !!!!!!!!!!!!!!!!!  IMPORTANT !!!!!!!!!!!!!!!!!!!
127*cdf0e10cSrcweir     //
128*cdf0e10cSrcweir     // Remember: This HACK prevents you from stepping
129*cdf0e10cSrcweir     // through your code in the debugger because if you
130*cdf0e10cSrcweir     // set a break point in the ctor here the debugger
131*cdf0e10cSrcweir     // may become the owner of the FolderBrowse dialog
132*cdf0e10cSrcweir     // and so it seems that the Visual Studio and the
133*cdf0e10cSrcweir     // office are hanging
134*cdf0e10cSrcweir     m_bi.hwndOwner = GetForegroundWindow( );
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir 	/*
137*cdf0e10cSrcweir 		Flag				Available
138*cdf0e10cSrcweir 		--------------------------------
139*cdf0e10cSrcweir 		BIF_EDITBOX			Version 4.71
140*cdf0e10cSrcweir 		BIF_NEWDIALOGSTYLE	Version 5.0
141*cdf0e10cSrcweir 		BIF_SHAREABLE		Version 5.0
142*cdf0e10cSrcweir 		BIF_VALIDATE		Version 4.71
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 		Version 4.71 - Internet Explorer 4.0
145*cdf0e10cSrcweir 		Version 5.0	 - Internet Explorer 5.0
146*cdf0e10cSrcweir 					   Windows 2000
147*cdf0e10cSrcweir 	*/
148*cdf0e10cSrcweir 	m_bi.ulFlags = Flags;
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir 	m_bi.lpfn    = CMtaFolderPicker::FolderPickerCallback;
151*cdf0e10cSrcweir 	m_bi.lParam  = reinterpret_cast< LPARAM >( this );
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir     //---------------------------------------
154*cdf0e10cSrcweir     // read the default strings for title and
155*cdf0e10cSrcweir     // description from a resource file
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir     CResourceProvider ResProvider;
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir     m_dialogTitle = ResProvider.getResString( 500 );
160*cdf0e10cSrcweir     m_Description = ResProvider.getResString( 501 );
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 	// signals that the thread was successfully set up
163*cdf0e10cSrcweir 	m_hEvtThrdReady  = CreateEventA(
164*cdf0e10cSrcweir 		0,
165*cdf0e10cSrcweir 		MANUAL_RESET,
166*cdf0e10cSrcweir 		INIT_NONSIGNALED,
167*cdf0e10cSrcweir 		NULL );
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir     if ( m_hEvtThrdReady )
170*cdf0e10cSrcweir     {
171*cdf0e10cSrcweir 	    // setup the sta thread
172*cdf0e10cSrcweir 	    m_hStaThread = (HANDLE)_beginthreadex(
173*cdf0e10cSrcweir 		    NULL,
174*cdf0e10cSrcweir             0,
175*cdf0e10cSrcweir             CMtaFolderPicker::StaThreadProc,
176*cdf0e10cSrcweir             this,
177*cdf0e10cSrcweir             0,
178*cdf0e10cSrcweir             &m_uStaThreadId );
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir         OSL_ASSERT( m_hStaThread );
181*cdf0e10cSrcweir     }
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir     OSL_ASSERT( m_hEvtThrdReady );
184*cdf0e10cSrcweir }
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir //--------------------------------------------------------------------
187*cdf0e10cSrcweir // dtor
188*cdf0e10cSrcweir //--------------------------------------------------------------------
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir CMtaFolderPicker::~CMtaFolderPicker( )
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir     // only if the is a valid event handle
193*cdf0e10cSrcweir     // there may also be a thread a hidden
194*cdf0e10cSrcweir     // target request window and so on
195*cdf0e10cSrcweir     // see ctor
196*cdf0e10cSrcweir 	if ( m_hEvtThrdReady )
197*cdf0e10cSrcweir     {
198*cdf0e10cSrcweir         // block calling threads because we
199*cdf0e10cSrcweir         // are about to shutdown
200*cdf0e10cSrcweir 		ResetEvent( m_hEvtThrdReady );
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir         // force the destruction of the sta thread request window
203*cdf0e10cSrcweir         // and the end of the thread
204*cdf0e10cSrcweir         // remeber: DestroyWindow may only be called from within
205*cdf0e10cSrcweir         // the thread that created the window
206*cdf0e10cSrcweir         if ( IsWindow( m_hwndStaRequestWnd ) )
207*cdf0e10cSrcweir         {
208*cdf0e10cSrcweir             SendMessageA( m_hwndStaRequestWnd, MSG_SHUTDOWN, 0, 0 );
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir             // we place unregister class here because
211*cdf0e10cSrcweir             // if we have a valid window we must have
212*cdf0e10cSrcweir             // sucessfully registered a window class
213*cdf0e10cSrcweir             // if the creation of the window itself
214*cdf0e10cSrcweir             // failed after registering the window
215*cdf0e10cSrcweir             // class we have unregistered it immediately
216*cdf0e10cSrcweir             // in createStaRequestWindow below
217*cdf0e10cSrcweir             UnregisterStaRequestWindowClass( );
218*cdf0e10cSrcweir         }
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir         if ( m_hStaThread )
221*cdf0e10cSrcweir         {
222*cdf0e10cSrcweir             // wait for thread shutdown
223*cdf0e10cSrcweir             sal_uInt32 dwResult = WaitForSingleObject( m_hStaThread, MAX_WAITTIME );
224*cdf0e10cSrcweir             OSL_ENSURE( dwResult == WAIT_OBJECT_0, "sta thread could not terminate" );
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir             // terminate the thread if it
227*cdf0e10cSrcweir             // doesn't shutdown itself
228*cdf0e10cSrcweir             if ( WAIT_OBJECT_0 != dwResult )
229*cdf0e10cSrcweir 	            TerminateThread(
230*cdf0e10cSrcweir                     m_hStaThread, sal::static_int_cast< DWORD >(-1) );
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir             CloseHandle( m_hStaThread );
233*cdf0e10cSrcweir         }
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir 	    CloseHandle( m_hEvtThrdReady );
236*cdf0e10cSrcweir     }
237*cdf0e10cSrcweir }
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir //--------------------------------------------------------------------
240*cdf0e10cSrcweir //
241*cdf0e10cSrcweir //--------------------------------------------------------------------
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir sal_Bool CMtaFolderPicker::browseForFolder( )
244*cdf0e10cSrcweir {
245*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir     if (IsMTA())
248*cdf0e10cSrcweir     {
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir         OSL_ASSERT( m_hEvtThrdReady );
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 	    if ( WaitForSingleObject( m_hEvtThrdReady, MAX_WAITTIME ) != WAIT_OBJECT_0 )
253*cdf0e10cSrcweir         {
254*cdf0e10cSrcweir             OSL_ENSURE( sal_False, "sta thread not ready" );
255*cdf0e10cSrcweir 		    return sal_False;
256*cdf0e10cSrcweir         }
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir 	    RequestContext aReqCtx;
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir         if ( !InitializeRequestContext( &aReqCtx ) )
261*cdf0e10cSrcweir         {
262*cdf0e10cSrcweir             OSL_ASSERT( sal_False );
263*cdf0e10cSrcweir             return sal_False;
264*cdf0e10cSrcweir         }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 	    // marshall request into the sta thread
267*cdf0e10cSrcweir 	    PostMessageA(
268*cdf0e10cSrcweir 		    m_hwndStaRequestWnd,
269*cdf0e10cSrcweir             MSG_BROWSEFORFOLDER,
270*cdf0e10cSrcweir             0,
271*cdf0e10cSrcweir             reinterpret_cast< LPARAM >( &aReqCtx ) );
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir         // waiting for the event to be signaled or
274*cdf0e10cSrcweir         // window messages so that we don't block
275*cdf0e10cSrcweir         // our parent window
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir         sal_Bool bContinue = sal_True;
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir         while ( bContinue )
280*cdf0e10cSrcweir         {
281*cdf0e10cSrcweir             DWORD dwResult = MsgWaitForMultipleObjects(
282*cdf0e10cSrcweir                 1, &aReqCtx.hEvent, sal_False, INFINITE, QS_ALLEVENTS );
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir             switch ( dwResult )
285*cdf0e10cSrcweir             {
286*cdf0e10cSrcweir             // the request context event is signaled
287*cdf0e10cSrcweir             case WAIT_OBJECT_0:
288*cdf0e10cSrcweir                 bContinue = sal_False;
289*cdf0e10cSrcweir                 break;
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir             // a window message has arrived
292*cdf0e10cSrcweir             case WAIT_OBJECT_0 + 1:
293*cdf0e10cSrcweir                 {
294*cdf0e10cSrcweir                     // dispatching all messages but we expect to
295*cdf0e10cSrcweir                     // receive only paint or timer messages that's
296*cdf0e10cSrcweir                     // why we don't need to call TranslateMessage or
297*cdf0e10cSrcweir                     // TranslateAccelerator, because keybord or
298*cdf0e10cSrcweir                     // mouse messages are for the FolderPicker which
299*cdf0e10cSrcweir                     // is in the foreground and should not arrive here
300*cdf0e10cSrcweir                     MSG msg;
301*cdf0e10cSrcweir                     while ( PeekMessageA( &msg, NULL, 0, 0, PM_REMOVE ) )
302*cdf0e10cSrcweir                         DispatchMessageA(&msg);
303*cdf0e10cSrcweir                 }
304*cdf0e10cSrcweir                 break;
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir             // should not happen
307*cdf0e10cSrcweir             default:
308*cdf0e10cSrcweir                 OSL_ASSERT( sal_False );
309*cdf0e10cSrcweir             }
310*cdf0e10cSrcweir         }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir         /*sal_Bool*/ bRet = aReqCtx.bRet;
313*cdf0e10cSrcweir         DeinitializeRequestContext( &aReqCtx );
314*cdf0e10cSrcweir     }
315*cdf0e10cSrcweir     else
316*cdf0e10cSrcweir     {
317*cdf0e10cSrcweir         bRet = onBrowseForFolder();
318*cdf0e10cSrcweir     }
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir     return bRet;
321*cdf0e10cSrcweir }
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir //--------------------------------------------------------------------
324*cdf0e10cSrcweir //
325*cdf0e10cSrcweir //--------------------------------------------------------------------
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::setDisplayDirectory( const OUString& aDirectory )
328*cdf0e10cSrcweir {
329*cdf0e10cSrcweir 	m_displayDir = aDirectory;
330*cdf0e10cSrcweir }
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir //--------------------------------------------------------------------
333*cdf0e10cSrcweir //
334*cdf0e10cSrcweir //--------------------------------------------------------------------
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir OUString SAL_CALL CMtaFolderPicker::getDisplayDirectory( )
337*cdf0e10cSrcweir {
338*cdf0e10cSrcweir 	return m_displayDir;
339*cdf0e10cSrcweir }
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir //--------------------------------------------------------------------
342*cdf0e10cSrcweir //
343*cdf0e10cSrcweir //--------------------------------------------------------------------
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir OUString SAL_CALL CMtaFolderPicker::getDirectory( )
346*cdf0e10cSrcweir {
347*cdf0e10cSrcweir     return m_SelectedDir;
348*cdf0e10cSrcweir }
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir //--------------------------------------------------------------------
351*cdf0e10cSrcweir //
352*cdf0e10cSrcweir //--------------------------------------------------------------------
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::setDescription( const rtl::OUString& aDescription )
355*cdf0e10cSrcweir {
356*cdf0e10cSrcweir     m_Description = aDescription;
357*cdf0e10cSrcweir }
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir //--------------------------------------------------------------------
360*cdf0e10cSrcweir //
361*cdf0e10cSrcweir //--------------------------------------------------------------------
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::setTitle( const OUString& aTitle )
364*cdf0e10cSrcweir {
365*cdf0e10cSrcweir 	m_dialogTitle = aTitle;
366*cdf0e10cSrcweir }
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir //--------------------------------------------------------------------
369*cdf0e10cSrcweir //
370*cdf0e10cSrcweir //--------------------------------------------------------------------
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir OUString SAL_CALL CMtaFolderPicker::getTitle( )
373*cdf0e10cSrcweir {
374*cdf0e10cSrcweir 	return m_dialogTitle;
375*cdf0e10cSrcweir }
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir //-----------------------------------------------------
378*cdf0e10cSrcweir // XCancellable
379*cdf0e10cSrcweir //-----------------------------------------------------
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::cancel( )
382*cdf0e10cSrcweir {
383*cdf0e10cSrcweir     if ( IsWindow( m_hwnd ) )
384*cdf0e10cSrcweir     {
385*cdf0e10cSrcweir         // simulate a mouse click to the
386*cdf0e10cSrcweir         // cancel button
387*cdf0e10cSrcweir         PostMessageA(
388*cdf0e10cSrcweir             m_hwnd,
389*cdf0e10cSrcweir             WM_COMMAND,
390*cdf0e10cSrcweir             MAKEWPARAM( IDCANCEL, BN_CLICKED ),
391*cdf0e10cSrcweir             (LPARAM)GetDlgItem( m_hwnd, IDCANCEL ) );
392*cdf0e10cSrcweir     }
393*cdf0e10cSrcweir }
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir //--------------------------------------------------------------------
396*cdf0e10cSrcweir //
397*cdf0e10cSrcweir //--------------------------------------------------------------------
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir sal_Bool SAL_CALL CMtaFolderPicker::onBrowseForFolder( )
400*cdf0e10cSrcweir {
401*cdf0e10cSrcweir 	sal_Bool     bRet;
402*cdf0e10cSrcweir 	LPITEMIDLIST lpiid;
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir 	// pre SHBrowseFroFolder
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 	m_bi.pidlRoot       = 0;
407*cdf0e10cSrcweir 	m_bi.pszDisplayName = reinterpret_cast<LPWSTR>(m_pathBuff.get());
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir     if ( m_Description.getLength( ) )
410*cdf0e10cSrcweir         m_bi.lpszTitle = reinterpret_cast<LPCWSTR>(m_Description.getStr( ));
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir 	lpiid = SHBrowseForFolderW( &m_bi );
413*cdf0e10cSrcweir 	bRet = ( NULL != lpiid );
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir 	// post SHBrowseForFolder
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir 	m_SelectedDir = getPathFromItemIdList( lpiid );
418*cdf0e10cSrcweir 	releaseItemIdList( lpiid );
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir 	return bRet;
421*cdf0e10cSrcweir }
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir //--------------------------------------------------------------------
424*cdf0e10cSrcweir //
425*cdf0e10cSrcweir //--------------------------------------------------------------------
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::releaseItemIdList( LPITEMIDLIST lpItemIdList )
428*cdf0e10cSrcweir {
429*cdf0e10cSrcweir 	IMallocPtr pIMalloc;
430*cdf0e10cSrcweir 	SHGetMalloc(&pIMalloc);
431*cdf0e10cSrcweir 	if (pIMalloc.is())
432*cdf0e10cSrcweir 	{
433*cdf0e10cSrcweir 	    pIMalloc->Free(lpItemIdList);
434*cdf0e10cSrcweir 	    lpItemIdList = NULL;
435*cdf0e10cSrcweir 	}
436*cdf0e10cSrcweir }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir //--------------------------------------------------------------------
439*cdf0e10cSrcweir //
440*cdf0e10cSrcweir //--------------------------------------------------------------------
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir LPITEMIDLIST SAL_CALL CMtaFolderPicker::getItemIdListFromPath( const rtl::OUString& aDirectory )
443*cdf0e10cSrcweir {
444*cdf0e10cSrcweir 	// parameter checking
445*cdf0e10cSrcweir 	if ( !aDirectory.getLength( ) )
446*cdf0e10cSrcweir 		return NULL;
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir 	LPITEMIDLIST lpItemIdList(NULL);
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir 	IShellFolderPtr pIShellFolder;
451*cdf0e10cSrcweir 	SHGetDesktopFolder(&pIShellFolder);
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir     if (pIShellFolder.is())
454*cdf0e10cSrcweir     {
455*cdf0e10cSrcweir 	    pIShellFolder->ParseDisplayName(
456*cdf0e10cSrcweir 		    NULL,
457*cdf0e10cSrcweir 		    NULL,
458*cdf0e10cSrcweir 		    reinterpret_cast<LPWSTR>(const_cast< sal_Unicode* >( aDirectory.getStr( ) )),
459*cdf0e10cSrcweir 		    NULL,
460*cdf0e10cSrcweir 		    &lpItemIdList,
461*cdf0e10cSrcweir 		    NULL );
462*cdf0e10cSrcweir     }
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir 	return lpItemIdList;
465*cdf0e10cSrcweir }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir //--------------------------------------------------------------------
468*cdf0e10cSrcweir //
469*cdf0e10cSrcweir //--------------------------------------------------------------------
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir OUString SAL_CALL CMtaFolderPicker::getPathFromItemIdList( LPCITEMIDLIST lpItemIdList )
472*cdf0e10cSrcweir {
473*cdf0e10cSrcweir 	OUString path;
474*cdf0e10cSrcweir 
475*cdf0e10cSrcweir 	if ( lpItemIdList )
476*cdf0e10cSrcweir 	{
477*cdf0e10cSrcweir 		bool bRet = SHGetPathFromIDListW( lpItemIdList, reinterpret_cast<LPWSTR>(m_pathBuff.get()) );
478*cdf0e10cSrcweir 		if ( bRet )
479*cdf0e10cSrcweir 			path = m_pathBuff.get( );
480*cdf0e10cSrcweir 	}
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir 	return path;
483*cdf0e10cSrcweir }
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir //--------------------------------------------------------------------
486*cdf0e10cSrcweir //
487*cdf0e10cSrcweir //--------------------------------------------------------------------
488*cdf0e10cSrcweir 
489*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::enableOk( sal_Bool bEnable )
490*cdf0e10cSrcweir {
491*cdf0e10cSrcweir 	OSL_ASSERT( IsWindow( m_hwnd ) );
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir 	SendMessageW(
494*cdf0e10cSrcweir 		m_hwnd,
495*cdf0e10cSrcweir 		BFFM_ENABLEOK,
496*cdf0e10cSrcweir 		static_cast< WPARAM >( 0 ),
497*cdf0e10cSrcweir 		static_cast< LPARAM >( bEnable ) );
498*cdf0e10cSrcweir }
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir //--------------------------------------------------------------------
501*cdf0e10cSrcweir //
502*cdf0e10cSrcweir //--------------------------------------------------------------------
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::setSelection( const rtl::OUString& aDirectory )
505*cdf0e10cSrcweir {
506*cdf0e10cSrcweir 	OSL_ASSERT( IsWindow( m_hwnd ) );
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir #ifdef _MSC_VER
509*cdf0e10cSrcweir #pragma message( "#######################################" )
510*cdf0e10cSrcweir #pragma message( "SendMessageW wrapper has to be extended" )
511*cdf0e10cSrcweir #pragma message( "#######################################" )
512*cdf0e10cSrcweir #endif
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir 	SendMessageW(
515*cdf0e10cSrcweir 		m_hwnd,
516*cdf0e10cSrcweir 		BFFM_SETSELECTIONW,
517*cdf0e10cSrcweir 		static_cast< WPARAM >( sal_True ),
518*cdf0e10cSrcweir 		reinterpret_cast< LPARAM >( aDirectory.getStr( ) ) );
519*cdf0e10cSrcweir }
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir //--------------------------------------------------------------------
522*cdf0e10cSrcweir //
523*cdf0e10cSrcweir //--------------------------------------------------------------------
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::setStatusText( const rtl::OUString& aStatusText )
526*cdf0e10cSrcweir {
527*cdf0e10cSrcweir 	OSL_ASSERT( IsWindow( m_hwnd ) );
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir 	SendMessageW(
530*cdf0e10cSrcweir 		m_hwnd,
531*cdf0e10cSrcweir 		BFFM_SETSTATUSTEXTW,
532*cdf0e10cSrcweir 		static_cast< WPARAM >( 0 ),
533*cdf0e10cSrcweir 		reinterpret_cast< LPARAM >( aStatusText.getStr( ) ) );
534*cdf0e10cSrcweir }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir //--------------------------------------------------------------------
537*cdf0e10cSrcweir //
538*cdf0e10cSrcweir //--------------------------------------------------------------------
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::onInitialized( )
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir     LPITEMIDLIST lpiidDisplayDir = getItemIdListFromPath( m_displayDir );
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir 	if ( lpiidDisplayDir )
545*cdf0e10cSrcweir 	{
546*cdf0e10cSrcweir 		SendMessageA(
547*cdf0e10cSrcweir 			m_hwnd,
548*cdf0e10cSrcweir 			BFFM_SETSELECTION,
549*cdf0e10cSrcweir 			(WPARAM)sal_False,
550*cdf0e10cSrcweir 			(LPARAM) lpiidDisplayDir );
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir 		releaseItemIdList( lpiidDisplayDir );
553*cdf0e10cSrcweir 	}
554*cdf0e10cSrcweir }
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir //--------------------------------------------------------------------
557*cdf0e10cSrcweir //
558*cdf0e10cSrcweir //--------------------------------------------------------------------
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir sal_uInt32 CMtaFolderPicker::onValidateFailed()
561*cdf0e10cSrcweir {
562*cdf0e10cSrcweir 	// to be overwritten by subclasses
563*cdf0e10cSrcweir 	return 1;
564*cdf0e10cSrcweir }
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir //--------------------------------------------------------------------
567*cdf0e10cSrcweir //
568*cdf0e10cSrcweir //--------------------------------------------------------------------
569*cdf0e10cSrcweir 
570*cdf0e10cSrcweir int CALLBACK CMtaFolderPicker::FolderPickerCallback( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
571*cdf0e10cSrcweir {
572*cdf0e10cSrcweir 	CMtaFolderPicker* pImpl = reinterpret_cast< CMtaFolderPicker* >( lpData );
573*cdf0e10cSrcweir 	OSL_ASSERT( pImpl );
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir 	int nRC = 0;
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir 	switch( uMsg )
578*cdf0e10cSrcweir 	{
579*cdf0e10cSrcweir 		case BFFM_INITIALIZED:
580*cdf0e10cSrcweir             pImpl->m_hwnd = hwnd;
581*cdf0e10cSrcweir 			pImpl->onInitialized( );
582*cdf0e10cSrcweir 			SetWindowTextW( hwnd, reinterpret_cast<LPCWSTR>(pImpl->m_dialogTitle.getStr()) );
583*cdf0e10cSrcweir 		break;
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir 		case BFFM_SELCHANGED:
586*cdf0e10cSrcweir             pImpl->m_hwnd = hwnd;
587*cdf0e10cSrcweir 			pImpl->onSelChanged(
588*cdf0e10cSrcweir 				pImpl->getPathFromItemIdList(
589*cdf0e10cSrcweir 					reinterpret_cast< LPITEMIDLIST >( lParam ) ) );
590*cdf0e10cSrcweir 		break;
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir 		case BFFM_VALIDATEFAILEDW:
593*cdf0e10cSrcweir 			nRC = pImpl->onValidateFailed();
594*cdf0e10cSrcweir 			break;
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir 		default:
597*cdf0e10cSrcweir 			OSL_ASSERT( sal_False );
598*cdf0e10cSrcweir 	}
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 	return nRC;
601*cdf0e10cSrcweir }
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir //--------------------------------------------------------------------
604*cdf0e10cSrcweir // the window proc
605*cdf0e10cSrcweir //--------------------------------------------------------------------
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir LRESULT CALLBACK CMtaFolderPicker::StaWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
608*cdf0e10cSrcweir {
609*cdf0e10cSrcweir 	LRESULT           lResult = 0;
610*cdf0e10cSrcweir 	CMtaFolderPicker* pImpl   = NULL;
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir     /*
613*cdf0e10cSrcweir         we connect to the belonging class instance of this
614*cdf0e10cSrcweir         window using SetProp, GetProp etc.
615*cdf0e10cSrcweir         this may fail if somehow the class instance destroyed
616*cdf0e10cSrcweir         before the window
617*cdf0e10cSrcweir     */
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir 	switch( uMsg )
620*cdf0e10cSrcweir 	{
621*cdf0e10cSrcweir         case WM_CREATE:
622*cdf0e10cSrcweir             {
623*cdf0e10cSrcweir                 LPCREATESTRUCT lpcs =
624*cdf0e10cSrcweir                     reinterpret_cast< LPCREATESTRUCT >( lParam );
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir                 OSL_ASSERT( lpcs->lpCreateParams );
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir                 // connect the instance handle to the window
629*cdf0e10cSrcweir                 SetPropA( hWnd, CURRENT_INSTANCE, lpcs->lpCreateParams );
630*cdf0e10cSrcweir             }
631*cdf0e10cSrcweir             break;
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir         case WM_NCDESTROY:
634*cdf0e10cSrcweir                 // RemoveProp returns the saved value on success
635*cdf0e10cSrcweir                 pImpl = reinterpret_cast< CMtaFolderPicker* >(
636*cdf0e10cSrcweir                     RemovePropA( hWnd, CURRENT_INSTANCE ) );
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir                 OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) );
639*cdf0e10cSrcweir             break;
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir 	    case MSG_BROWSEFORFOLDER:
642*cdf0e10cSrcweir             {
643*cdf0e10cSrcweir                 RequestContext* aReqCtx = reinterpret_cast< RequestContext* >( lParam );
644*cdf0e10cSrcweir                 OSL_ASSERT( aReqCtx );
645*cdf0e10cSrcweir 
646*cdf0e10cSrcweir                 pImpl = reinterpret_cast< CMtaFolderPicker* >(
647*cdf0e10cSrcweir                     GetPropA( hWnd, CURRENT_INSTANCE ) );
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir                 OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) );
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir                 aReqCtx->bRet = pImpl->onBrowseForFolder( );
652*cdf0e10cSrcweir                 SetEvent( aReqCtx->hEvent );
653*cdf0e10cSrcweir             }
654*cdf0e10cSrcweir 			break;
655*cdf0e10cSrcweir 
656*cdf0e10cSrcweir 		case MSG_SHUTDOWN:
657*cdf0e10cSrcweir             pImpl = reinterpret_cast< CMtaFolderPicker* >(
658*cdf0e10cSrcweir                 GetPropA( hWnd, CURRENT_INSTANCE ) );
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir             OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) );
661*cdf0e10cSrcweir 
662*cdf0e10cSrcweir             DestroyWindow( pImpl->m_hwndStaRequestWnd );
663*cdf0e10cSrcweir 			break;
664*cdf0e10cSrcweir 
665*cdf0e10cSrcweir 		case WM_DESTROY:
666*cdf0e10cSrcweir 			PostQuitMessage( 0 );
667*cdf0e10cSrcweir 			break;
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir 		default:
670*cdf0e10cSrcweir 			lResult = DefWindowProcA( hWnd, uMsg, wParam, lParam );
671*cdf0e10cSrcweir 			break;
672*cdf0e10cSrcweir 	}
673*cdf0e10cSrcweir 
674*cdf0e10cSrcweir 	return lResult;
675*cdf0e10cSrcweir }
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir //--------------------------------------------------------------------
678*cdf0e10cSrcweir //
679*cdf0e10cSrcweir //--------------------------------------------------------------------
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir sal_Bool SAL_CALL CMtaFolderPicker::createStaRequestWindow( )
682*cdf0e10cSrcweir {
683*cdf0e10cSrcweir     bool bIsWnd = false;
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir 	if ( RegisterStaRequestWindowClass( ) )
686*cdf0e10cSrcweir     {
687*cdf0e10cSrcweir 		m_hwndStaRequestWnd = CreateWindowA(
688*cdf0e10cSrcweir 			g_szWndClsName, NULL,
689*cdf0e10cSrcweir             0, 0, 0, 0, 0,
690*cdf0e10cSrcweir             NULL, NULL, m_hInstance,
691*cdf0e10cSrcweir             (LPVOID)this // provide the instance of the class
692*cdf0e10cSrcweir         );
693*cdf0e10cSrcweir 
694*cdf0e10cSrcweir         bIsWnd = IsWindow( m_hwndStaRequestWnd );
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir         // we do immediately unregister the window class
697*cdf0e10cSrcweir         // if the creation of the window fails because we
698*cdf0e10cSrcweir         // don't want to spoil the register class counter
699*cdf0e10cSrcweir         if ( !bIsWnd )
700*cdf0e10cSrcweir             UnregisterStaRequestWindowClass( );
701*cdf0e10cSrcweir 
702*cdf0e10cSrcweir         OSL_ENSURE( bIsWnd, "sta request window creation failed" );
703*cdf0e10cSrcweir     }
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir     return bIsWnd;
706*cdf0e10cSrcweir }
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir //--------------------------------------------------------------------
709*cdf0e10cSrcweir //
710*cdf0e10cSrcweir //--------------------------------------------------------------------
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir unsigned int CMtaFolderPicker::run( )
713*cdf0e10cSrcweir {
714*cdf0e10cSrcweir     OSL_ASSERT( m_hEvtThrdReady );
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir     // setup an sta environment
717*cdf0e10cSrcweir 	HRESULT hr = CoInitialize( NULL );
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir     // if we can't setup an sta environment
720*cdf0e10cSrcweir     // we stop here and return
721*cdf0e10cSrcweir     if ( FAILED( hr ) )
722*cdf0e10cSrcweir     {
723*cdf0e10cSrcweir         OSL_ENSURE( sal_False, "CoInitialize failed" );
724*cdf0e10cSrcweir         return sal::static_int_cast< unsigned int >(-1);
725*cdf0e10cSrcweir     }
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir 	unsigned int nRet;
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir 	if ( createStaRequestWindow( ) )
730*cdf0e10cSrcweir 	{
731*cdf0e10cSrcweir 		SetEvent( m_hEvtThrdReady );
732*cdf0e10cSrcweir 
733*cdf0e10cSrcweir 		// pumping messages
734*cdf0e10cSrcweir 		MSG msg;
735*cdf0e10cSrcweir 		while( GetMessageA( &msg, NULL, 0, 0 ) )
736*cdf0e10cSrcweir 			DispatchMessageA( &msg );
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir 		nRet = 0;
739*cdf0e10cSrcweir 	}
740*cdf0e10cSrcweir 	else
741*cdf0e10cSrcweir     {
742*cdf0e10cSrcweir         OSL_ENSURE( sal_False, "failed to create sta thread" );
743*cdf0e10cSrcweir 		nRet = sal::static_int_cast< unsigned int >(-1);
744*cdf0e10cSrcweir     }
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir     // shutdown sta environment
747*cdf0e10cSrcweir     CoUninitialize( );
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir 	return nRet;
750*cdf0e10cSrcweir }
751*cdf0e10cSrcweir 
752*cdf0e10cSrcweir //--------------------------------------------------------------------
753*cdf0e10cSrcweir //
754*cdf0e10cSrcweir //--------------------------------------------------------------------
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir unsigned int WINAPI CMtaFolderPicker::StaThreadProc( LPVOID pParam )
757*cdf0e10cSrcweir {
758*cdf0e10cSrcweir 	CMtaFolderPicker* pInst =
759*cdf0e10cSrcweir 		reinterpret_cast<CMtaFolderPicker*>( pParam );
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir 	OSL_ASSERT( pInst );
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir 	HRESULT	hr = OleInitialize( NULL );
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir 	unsigned int	result = pInst->run( );
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir 	if ( SUCCEEDED( hr ) )
768*cdf0e10cSrcweir 		OleUninitialize();
769*cdf0e10cSrcweir 
770*cdf0e10cSrcweir 	return result;
771*cdf0e10cSrcweir }
772*cdf0e10cSrcweir 
773*cdf0e10cSrcweir //---------------------------------------------------
774*cdf0e10cSrcweir //
775*cdf0e10cSrcweir //---------------------------------------------------
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir ATOM SAL_CALL CMtaFolderPicker::RegisterStaRequestWindowClass( )
778*cdf0e10cSrcweir {
779*cdf0e10cSrcweir     osl::MutexGuard aGuard( s_Mutex );
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir     if ( 0 == s_ClassAtom )
782*cdf0e10cSrcweir     {
783*cdf0e10cSrcweir         WNDCLASSEXA  wcex;
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir 	    ZeroMemory( &wcex, sizeof( WNDCLASSEXA ) );
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir 	    wcex.cbSize			= sizeof(WNDCLASSEXA);
788*cdf0e10cSrcweir 	    wcex.style			= 0;
789*cdf0e10cSrcweir 	    wcex.lpfnWndProc	= static_cast< WNDPROC >( CMtaFolderPicker::StaWndProc );
790*cdf0e10cSrcweir 	    wcex.cbClsExtra		= 0;
791*cdf0e10cSrcweir 	    wcex.cbWndExtra		= 0;
792*cdf0e10cSrcweir 	    wcex.hInstance		= m_hInstance;
793*cdf0e10cSrcweir 	    wcex.hIcon			= NULL;
794*cdf0e10cSrcweir 	    wcex.hCursor		= NULL;
795*cdf0e10cSrcweir 	    wcex.hbrBackground	= NULL;
796*cdf0e10cSrcweir 	    wcex.lpszMenuName	= NULL;
797*cdf0e10cSrcweir 	    wcex.lpszClassName	= g_szWndClsName;
798*cdf0e10cSrcweir 	    wcex.hIconSm		= NULL;
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir     	s_ClassAtom = RegisterClassExA( &wcex );
801*cdf0e10cSrcweir         OSL_ASSERT( s_ClassAtom );
802*cdf0e10cSrcweir     }
803*cdf0e10cSrcweir 
804*cdf0e10cSrcweir     // increment the register class counter
805*cdf0e10cSrcweir     // so that we keep track of the number
806*cdf0e10cSrcweir     // of class registrations
807*cdf0e10cSrcweir     if ( 0 != s_ClassAtom )
808*cdf0e10cSrcweir         s_StaRequestWndRegisterCount++;
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir     return s_ClassAtom;
811*cdf0e10cSrcweir }
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir //---------------------------------------------------
814*cdf0e10cSrcweir //
815*cdf0e10cSrcweir //---------------------------------------------------
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir void SAL_CALL CMtaFolderPicker::UnregisterStaRequestWindowClass( )
818*cdf0e10cSrcweir {
819*cdf0e10cSrcweir     osl::MutexGuard aGuard( s_Mutex );
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir     OSL_ASSERT( 0 != s_ClassAtom );
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir     // update the register class counter
824*cdf0e10cSrcweir     // and unregister the window class if
825*cdf0e10cSrcweir     // counter drops to zero
826*cdf0e10cSrcweir     if ( 0 != s_ClassAtom )
827*cdf0e10cSrcweir     {
828*cdf0e10cSrcweir         s_StaRequestWndRegisterCount--;
829*cdf0e10cSrcweir         OSL_ASSERT( s_StaRequestWndRegisterCount >= 0 );
830*cdf0e10cSrcweir     }
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir     if ( 0 == s_StaRequestWndRegisterCount )
833*cdf0e10cSrcweir     {
834*cdf0e10cSrcweir         UnregisterClass(
835*cdf0e10cSrcweir 	        (LPCTSTR)MAKELONG( s_ClassAtom, 0 ), m_hInstance );
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir         s_ClassAtom = 0;
838*cdf0e10cSrcweir     }
839*cdf0e10cSrcweir }
840