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