1*b557fc96SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b557fc96SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b557fc96SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b557fc96SAndrew Rist  * distributed with this work for additional information
6*b557fc96SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b557fc96SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b557fc96SAndrew Rist  * "License"); you may not use this file except in compliance
9*b557fc96SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b557fc96SAndrew Rist  *
11*b557fc96SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b557fc96SAndrew Rist  *
13*b557fc96SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b557fc96SAndrew Rist  * software distributed under the License is distributed on an
15*b557fc96SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b557fc96SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b557fc96SAndrew Rist  * specific language governing permissions and limitations
18*b557fc96SAndrew Rist  * under the License.
19*b557fc96SAndrew Rist  *
20*b557fc96SAndrew Rist  *************************************************************/
21*b557fc96SAndrew Rist 
22*b557fc96SAndrew 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 <osl/diagnose.h>
33cdf0e10cSrcweir #include "../misc/WinImplHelper.hxx"
34cdf0e10cSrcweir #include "FileOpenDlg.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir //------------------------------------------------------------------------
37cdf0e10cSrcweir // constants
38cdf0e10cSrcweir //------------------------------------------------------------------------
39cdf0e10cSrcweir 
40cdf0e10cSrcweir namespace /* private */
41cdf0e10cSrcweir {
42cdf0e10cSrcweir     // we choose such large buffers because the size of
43cdf0e10cSrcweir     // an single line edit field can be up to 32k; if
44cdf0e10cSrcweir     // a user has a multi selection FilePicker and selects
45cdf0e10cSrcweir     // a lot of files in a large directory we may reach this
46cdf0e10cSrcweir     // limit and don't want to get out of memory;
47cdf0e10cSrcweir     // another much more elegant way would be to subclass the
48cdf0e10cSrcweir     // FileOpen dialog and overload the BM_CLICK event of the
49cdf0e10cSrcweir     // OK button so that we determine the size of the text
50cdf0e10cSrcweir     // currently in the edit field and resize our buffer
51cdf0e10cSrcweir     // appropriately - in the future we will do this
52cdf0e10cSrcweir     const size_t MAX_FILENAME_BUFF_SIZE  = 32000;
53cdf0e10cSrcweir     const size_t MAX_FILETITLE_BUFF_SIZE = 32000;
54cdf0e10cSrcweir     const size_t MAX_FILTER_BUFF_SIZE    = 4096;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir     const LPTSTR CURRENT_INSTANCE = TEXT("CurrInst");
57cdf0e10cSrcweir 
58cdf0e10cSrcweir     //------------------------------------------
59cdf0e10cSrcweir     // find an appropriate parent window
60cdf0e10cSrcweir     //------------------------------------------
61cdf0e10cSrcweir 
is_current_process_window(HWND hwnd)62cdf0e10cSrcweir     inline bool is_current_process_window(HWND hwnd)
63cdf0e10cSrcweir     {
64cdf0e10cSrcweir         DWORD pid;
65cdf0e10cSrcweir         GetWindowThreadProcessId(hwnd, &pid);
66cdf0e10cSrcweir         return (pid == GetCurrentProcessId());
67cdf0e10cSrcweir     }
68cdf0e10cSrcweir 
choose_parent_window()69cdf0e10cSrcweir     HWND choose_parent_window()
70cdf0e10cSrcweir     {
71cdf0e10cSrcweir         HWND hwnd_parent = GetForegroundWindow();
72cdf0e10cSrcweir         if (!is_current_process_window(hwnd_parent))
73cdf0e10cSrcweir             hwnd_parent = GetDesktopWindow();
74cdf0e10cSrcweir 
75cdf0e10cSrcweir         return hwnd_parent;
76cdf0e10cSrcweir     }
77cdf0e10cSrcweir };
78cdf0e10cSrcweir 
79cdf0e10cSrcweir //------------------------------------------------------------------------
80cdf0e10cSrcweir //
81cdf0e10cSrcweir //------------------------------------------------------------------------
82cdf0e10cSrcweir 
CFileOpenDialog(bool bFileOpenDialog,sal_uInt32 dwFlags,sal_uInt32 dwTemplateId,HINSTANCE hInstance)83cdf0e10cSrcweir CFileOpenDialog::CFileOpenDialog(
84cdf0e10cSrcweir 	bool bFileOpenDialog,
85cdf0e10cSrcweir 	sal_uInt32 dwFlags,
86cdf0e10cSrcweir 	sal_uInt32 dwTemplateId,
87cdf0e10cSrcweir 	HINSTANCE hInstance) :
88cdf0e10cSrcweir 	m_hwndFileOpenDlg(0),
89cdf0e10cSrcweir 	m_hwndFileOpenDlgChild(0),
90cdf0e10cSrcweir 	m_bFileOpenDialog(bFileOpenDialog),
91cdf0e10cSrcweir 	m_filterBuffer(MAX_FILTER_BUFF_SIZE),
92cdf0e10cSrcweir 	m_fileTitleBuffer(MAX_FILETITLE_BUFF_SIZE),
93cdf0e10cSrcweir 	m_helperBuffer(MAX_FILENAME_BUFF_SIZE),
94cdf0e10cSrcweir 	m_fileNameBuffer(MAX_FILENAME_BUFF_SIZE),
95cdf0e10cSrcweir 	m_pfnBaseDlgProc(0)
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	// initialize the OPENFILENAME struct
98cdf0e10cSrcweir 	if (IsWindows2000Platform() || IsWindowsME())
99cdf0e10cSrcweir 	{
100cdf0e10cSrcweir 		ZeroMemory(&m_ofn, sizeof(m_ofn));
101cdf0e10cSrcweir 		m_ofn.lStructSize = sizeof(m_ofn);
102cdf0e10cSrcweir 	}
103cdf0e10cSrcweir 	else // OSVER < Win2000
104cdf0e10cSrcweir 	{
105cdf0e10cSrcweir         // the size of the OPENFILENAME structure is different
106cdf0e10cSrcweir         // under windows < win2000
107cdf0e10cSrcweir 		ZeroMemory(&m_ofn, _OPENFILENAME_SIZE_VERSION_400);
108cdf0e10cSrcweir 		m_ofn.lStructSize = _OPENFILENAME_SIZE_VERSION_400;
109cdf0e10cSrcweir 	}
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     // 0x02000000 for #97681, sfx will make the entry into
112cdf0e10cSrcweir     // the recent document list
113cdf0e10cSrcweir 	m_ofn.Flags |= dwFlags |
114cdf0e10cSrcweir 				   OFN_EXPLORER |
115cdf0e10cSrcweir 		           OFN_ENABLEHOOK |
116cdf0e10cSrcweir 		           OFN_HIDEREADONLY |
117cdf0e10cSrcweir 				   OFN_PATHMUSTEXIST |
118cdf0e10cSrcweir 				   OFN_FILEMUSTEXIST |
119cdf0e10cSrcweir                    OFN_OVERWRITEPROMPT |
120cdf0e10cSrcweir 				   OFN_ENABLESIZING |
121cdf0e10cSrcweir                    OFN_DONTADDTORECENT; // 0x02000000 -> OFN_DONTADDTORECENT only available with new platform sdk
122cdf0e10cSrcweir 
123cdf0e10cSrcweir     // it is a little hack but how else could
124cdf0e10cSrcweir     // we get a parent window (using a vcl window?)
125cdf0e10cSrcweir     m_ofn.hwndOwner = choose_parent_window();
126cdf0e10cSrcweir 
127cdf0e10cSrcweir 	m_ofn.lpstrFile = reinterpret_cast<LPTSTR>(const_cast<sal_Unicode*>(m_fileNameBuffer.getStr()));
128cdf0e10cSrcweir 	m_ofn.nMaxFile  = m_fileNameBuffer.getCapacity();
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 	m_ofn.lpstrFileTitle = reinterpret_cast<LPTSTR>(const_cast<sal_Unicode*>(m_fileTitleBuffer.getStr()));
131cdf0e10cSrcweir 	m_ofn.nMaxFileTitle  = m_fileTitleBuffer.getCapacity();
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 	m_ofn.lpfnHook = CFileOpenDialog::ofnHookProc;
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 	// set a custom template
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 	if (dwTemplateId)
138cdf0e10cSrcweir 	{
139cdf0e10cSrcweir 		OSL_ASSERT(hInstance);
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 		m_ofn.Flags          |= OFN_ENABLETEMPLATE;
142cdf0e10cSrcweir 		m_ofn.lpTemplateName  = MAKEINTRESOURCE(dwTemplateId);
143cdf0e10cSrcweir 		m_ofn.hInstance       = hInstance;
144cdf0e10cSrcweir 	}
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 	// set a pointer to myself as ofn parameter
147cdf0e10cSrcweir 	m_ofn.lCustData = reinterpret_cast<long>(this);
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir //------------------------------------------------------------------------
151cdf0e10cSrcweir //
152cdf0e10cSrcweir //------------------------------------------------------------------------
153cdf0e10cSrcweir 
~CFileOpenDialog()154cdf0e10cSrcweir CFileOpenDialog::~CFileOpenDialog()
155cdf0e10cSrcweir {
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir //------------------------------------------------------------------------
159cdf0e10cSrcweir //
160cdf0e10cSrcweir //------------------------------------------------------------------------
161cdf0e10cSrcweir 
setTitle(const rtl::OUString & aTitle)162cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::setTitle(const rtl::OUString& aTitle)
163cdf0e10cSrcweir {
164cdf0e10cSrcweir 	m_dialogTitle = aTitle;
165cdf0e10cSrcweir 	m_ofn.lpstrTitle = reinterpret_cast<LPCTSTR>(m_dialogTitle.getStr());
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir //------------------------------------------------------------------------
169cdf0e10cSrcweir //
170cdf0e10cSrcweir //------------------------------------------------------------------------
171cdf0e10cSrcweir 
setFilter(const rtl::OUString & aFilter)172cdf0e10cSrcweir void CFileOpenDialog::setFilter(const rtl::OUString& aFilter)
173cdf0e10cSrcweir {
174cdf0e10cSrcweir     // Format is like
175cdf0e10cSrcweir     // "*.TXT" or multiple separate by ';' like "*.TXT;*.DOC;*.SXW"
176cdf0e10cSrcweir     // Do not include spaces in the pattern string
177cdf0e10cSrcweir 	m_filterBuffer.ensureCapacity(aFilter.getLength());
178cdf0e10cSrcweir 	m_filterBuffer.setLength(0);
179cdf0e10cSrcweir 	m_filterBuffer.append(aFilter);
180cdf0e10cSrcweir 	m_ofn.lpstrFilter = reinterpret_cast<LPCTSTR>(m_filterBuffer.getStr());
181cdf0e10cSrcweir }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir //------------------------------------------------------------------------
184cdf0e10cSrcweir //
185cdf0e10cSrcweir //------------------------------------------------------------------------
186cdf0e10cSrcweir 
setFilterIndex(sal_uInt32 aIndex)187cdf0e10cSrcweir bool CFileOpenDialog::setFilterIndex(sal_uInt32 aIndex)
188cdf0e10cSrcweir {
189cdf0e10cSrcweir 	OSL_ASSERT(aIndex > 0);
190cdf0e10cSrcweir 	m_ofn.nFilterIndex = aIndex;
191cdf0e10cSrcweir 	return sal_True;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir //------------------------------------------------------------------------
195cdf0e10cSrcweir //
196cdf0e10cSrcweir //------------------------------------------------------------------------
197cdf0e10cSrcweir 
getSelectedFilterIndex() const198cdf0e10cSrcweir sal_uInt32 CFileOpenDialog::getSelectedFilterIndex() const
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	return m_ofn.nFilterIndex;
201cdf0e10cSrcweir }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir //------------------------------------------------------------------------
204cdf0e10cSrcweir //
205cdf0e10cSrcweir //------------------------------------------------------------------------
206cdf0e10cSrcweir 
setDefaultName(const rtl::OUString & aName)207cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::setDefaultName(const rtl::OUString& aName)
208cdf0e10cSrcweir {
209cdf0e10cSrcweir 	m_fileNameBuffer.setLength(0);
210cdf0e10cSrcweir 	m_fileNameBuffer.append(aName);
211cdf0e10cSrcweir 	m_ofn.lpstrFile = reinterpret_cast<LPTSTR>(const_cast<sal_Unicode*>(m_fileNameBuffer.getStr()));
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir //------------------------------------------------------------------------
215cdf0e10cSrcweir //
216cdf0e10cSrcweir //------------------------------------------------------------------------
217cdf0e10cSrcweir 
setDisplayDirectory(const rtl::OUString & aDirectory)218cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::setDisplayDirectory(const rtl::OUString& aDirectory)
219cdf0e10cSrcweir {
220cdf0e10cSrcweir 	m_displayDirectory = aDirectory;
221cdf0e10cSrcweir 	m_ofn.lpstrInitialDir = reinterpret_cast<LPCTSTR>(m_displayDirectory.getStr());
222cdf0e10cSrcweir }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir //------------------------------------------------------------------------
225cdf0e10cSrcweir //
226cdf0e10cSrcweir //------------------------------------------------------------------------
227cdf0e10cSrcweir 
getLastDisplayDirectory() const228cdf0e10cSrcweir rtl::OUString SAL_CALL CFileOpenDialog::getLastDisplayDirectory() const
229cdf0e10cSrcweir {
230cdf0e10cSrcweir 	return m_displayDirectory;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir //------------------------------------------------------------------------
234cdf0e10cSrcweir //
235cdf0e10cSrcweir //------------------------------------------------------------------------
236cdf0e10cSrcweir 
getFullFileName() const237cdf0e10cSrcweir rtl::OUString SAL_CALL CFileOpenDialog::getFullFileName() const
238cdf0e10cSrcweir {
239cdf0e10cSrcweir 	return rtl::OUString(m_fileNameBuffer.getStr(),
240cdf0e10cSrcweir 		_wcslenex(m_fileNameBuffer.getStr()));
241cdf0e10cSrcweir }
242cdf0e10cSrcweir 
243cdf0e10cSrcweir //------------------------------------------------------------------------
244cdf0e10cSrcweir //
245cdf0e10cSrcweir //------------------------------------------------------------------------
246cdf0e10cSrcweir 
getFileName() const247cdf0e10cSrcweir rtl::OUString SAL_CALL CFileOpenDialog::getFileName() const
248cdf0e10cSrcweir {
249cdf0e10cSrcweir 	return rtl::OUString(m_fileTitleBuffer);
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir //------------------------------------------------------------------------
253cdf0e10cSrcweir //
254cdf0e10cSrcweir //------------------------------------------------------------------------
255cdf0e10cSrcweir 
getFileExtension()256cdf0e10cSrcweir rtl::OUString CFileOpenDialog::getFileExtension()
257cdf0e10cSrcweir {
258cdf0e10cSrcweir 	if (m_ofn.nFileExtension)
259cdf0e10cSrcweir 		return rtl::OUString(m_fileNameBuffer.getStr() + m_ofn.nFileExtension,
260cdf0e10cSrcweir 			rtl_ustr_getLength(m_fileNameBuffer.getStr() + m_ofn.nFileExtension));
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	return rtl::OUString();
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir //------------------------------------------------------------------------
266cdf0e10cSrcweir //
267cdf0e10cSrcweir //------------------------------------------------------------------------
268cdf0e10cSrcweir 
setDefaultFileExtension(const rtl::OUString & aExtension)269cdf0e10cSrcweir void CFileOpenDialog::setDefaultFileExtension(const rtl::OUString& aExtension)
270cdf0e10cSrcweir {
271cdf0e10cSrcweir 	m_defaultExtension = aExtension;
272cdf0e10cSrcweir 	m_ofn.lpstrDefExt  = reinterpret_cast<LPCTSTR>(m_defaultExtension.getStr());
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir //------------------------------------------------------------------------
276cdf0e10cSrcweir //
277cdf0e10cSrcweir //------------------------------------------------------------------------
278cdf0e10cSrcweir 
setMultiSelectionMode(bool bMode)279cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::setMultiSelectionMode(bool bMode)
280cdf0e10cSrcweir {
281cdf0e10cSrcweir 	if (bMode)
282cdf0e10cSrcweir 		m_ofn.Flags |= OFN_ALLOWMULTISELECT;
283cdf0e10cSrcweir 	else
284cdf0e10cSrcweir 		m_ofn.Flags &= ~OFN_ALLOWMULTISELECT;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir //------------------------------------------------------------------------
288cdf0e10cSrcweir //
289cdf0e10cSrcweir //------------------------------------------------------------------------
290cdf0e10cSrcweir 
getMultiSelectionMode() const291cdf0e10cSrcweir bool SAL_CALL CFileOpenDialog::getMultiSelectionMode() const
292cdf0e10cSrcweir {
293cdf0e10cSrcweir 	return ((m_ofn.Flags & OFN_ALLOWMULTISELECT) > 0);
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir //------------------------------------------------------------------------
297cdf0e10cSrcweir //
298cdf0e10cSrcweir //------------------------------------------------------------------------
299cdf0e10cSrcweir 
doModal()300cdf0e10cSrcweir sal_Int16 SAL_CALL CFileOpenDialog::doModal()
301cdf0e10cSrcweir {
302cdf0e10cSrcweir 	sal_Int16 nRC = -1;
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 	// pre-processing
305cdf0e10cSrcweir 	if (preModal())
306cdf0e10cSrcweir 	{
307cdf0e10cSrcweir 		bool bRet;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir         if (m_bFileOpenDialog)
310cdf0e10cSrcweir 	        bRet = m_GetFileNameWrapper.getOpenFileName(
311cdf0e10cSrcweir 				reinterpret_cast<LPOPENFILENAME>(&m_ofn));
312cdf0e10cSrcweir         else
313cdf0e10cSrcweir             bRet = m_GetFileNameWrapper.getSaveFileName(
314cdf0e10cSrcweir 				reinterpret_cast<LPOPENFILENAME>(&m_ofn));
315cdf0e10cSrcweir 
316cdf0e10cSrcweir 	    nRC = 1;
317cdf0e10cSrcweir 
318cdf0e10cSrcweir 		if (!bRet)
319cdf0e10cSrcweir 			nRC = (0 == m_GetFileNameWrapper.commDlgExtendedError()) ? 0 : -1;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 		// post-processing
322cdf0e10cSrcweir 		postModal(nRC);
323cdf0e10cSrcweir 	}
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 	return nRC;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir //------------------------------------------------------------------------
329cdf0e10cSrcweir //
330cdf0e10cSrcweir //------------------------------------------------------------------------
331cdf0e10cSrcweir 
getLastDialogError() const332cdf0e10cSrcweir sal_uInt32 SAL_CALL CFileOpenDialog::getLastDialogError() const
333cdf0e10cSrcweir {
334cdf0e10cSrcweir 	return CommDlgExtendedError();
335cdf0e10cSrcweir }
336cdf0e10cSrcweir 
337cdf0e10cSrcweir //------------------------------------------------------------------------
338cdf0e10cSrcweir //
339cdf0e10cSrcweir //------------------------------------------------------------------------
340cdf0e10cSrcweir 
preModal()341cdf0e10cSrcweir bool SAL_CALL CFileOpenDialog::preModal()
342cdf0e10cSrcweir {
343cdf0e10cSrcweir 	return sal_True;
344cdf0e10cSrcweir }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir //------------------------------------------------------------------------
347cdf0e10cSrcweir //
348cdf0e10cSrcweir //------------------------------------------------------------------------
349cdf0e10cSrcweir 
postModal(sal_Int16 nDialogResult)350cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::postModal(sal_Int16 nDialogResult)
351cdf0e10cSrcweir {
352cdf0e10cSrcweir 	OSL_ASSERT((-1 <= nDialogResult) && (nDialogResult <= 1));
353cdf0e10cSrcweir 
354cdf0e10cSrcweir 	if (1 == nDialogResult)
355cdf0e10cSrcweir 	{
356cdf0e10cSrcweir 		// Attention: assuming that nFileOffset is always greater 0 because under
357cdf0e10cSrcweir 		// Windows there is always a drive letter or a server in a complete path
358cdf0e10cSrcweir 		// the OPENFILENAME docu never says that nFileOffset can be 0
359cdf0e10cSrcweir 		m_displayDirectory = rtl::OUString(reinterpret_cast<const sal_Unicode*>(m_ofn.lpstrFile),m_ofn.nFileOffset);
360cdf0e10cSrcweir 	}
361cdf0e10cSrcweir }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir //------------------------------------------------------------------------
364cdf0e10cSrcweir //
365cdf0e10cSrcweir //------------------------------------------------------------------------
366cdf0e10cSrcweir 
getCurrentFilePath() const367cdf0e10cSrcweir rtl::OUString SAL_CALL CFileOpenDialog::getCurrentFilePath() const
368cdf0e10cSrcweir {
369cdf0e10cSrcweir 	OSL_ASSERT(IsWindow(m_hwndFileOpenDlg));
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 	LPARAM nLen = SendMessage(
372cdf0e10cSrcweir 		m_hwndFileOpenDlg,
373cdf0e10cSrcweir 		CDM_GETFILEPATH,
374cdf0e10cSrcweir 		m_helperBuffer.getCapacity(),
375cdf0e10cSrcweir 		reinterpret_cast<LPARAM>(m_helperBuffer.getStr()));
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 	if (nLen > 0)
378cdf0e10cSrcweir 	{
379cdf0e10cSrcweir 		m_helperBuffer.setLength((nLen * sizeof(sal_Unicode)) - 1);
380cdf0e10cSrcweir 		return rtl::OUString(m_helperBuffer);
381cdf0e10cSrcweir 	}
382cdf0e10cSrcweir 	return rtl::OUString();
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
385cdf0e10cSrcweir //------------------------------------------------------------------------
386cdf0e10cSrcweir //
387cdf0e10cSrcweir //------------------------------------------------------------------------
388cdf0e10cSrcweir 
getCurrentFolderPath() const389cdf0e10cSrcweir rtl::OUString SAL_CALL CFileOpenDialog::getCurrentFolderPath() const
390cdf0e10cSrcweir {
391cdf0e10cSrcweir 	OSL_ASSERT(IsWindow(m_hwndFileOpenDlg));
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 	LPARAM nLen = SendMessage(
394cdf0e10cSrcweir 		m_hwndFileOpenDlg,
395cdf0e10cSrcweir 		CDM_GETFOLDERPATH,
396cdf0e10cSrcweir 		m_helperBuffer.getCapacity(),
397cdf0e10cSrcweir 		reinterpret_cast<LPARAM>(m_helperBuffer.getStr()));
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 	if (nLen > 0)
400cdf0e10cSrcweir 	{
401cdf0e10cSrcweir 		m_helperBuffer.setLength((nLen * sizeof(sal_Unicode)) - 1);
402cdf0e10cSrcweir 		return rtl::OUString(m_helperBuffer);
403cdf0e10cSrcweir 	}
404cdf0e10cSrcweir 	return rtl::OUString();
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir //------------------------------------------------------------------------
408cdf0e10cSrcweir //
409cdf0e10cSrcweir //------------------------------------------------------------------------
410cdf0e10cSrcweir 
getCurrentFileName() const411cdf0e10cSrcweir rtl::OUString SAL_CALL CFileOpenDialog::getCurrentFileName() const
412cdf0e10cSrcweir {
413cdf0e10cSrcweir 	OSL_ASSERT(IsWindow(m_hwndFileOpenDlg));
414cdf0e10cSrcweir 
415cdf0e10cSrcweir 	LPARAM nLen = SendMessage(
416cdf0e10cSrcweir 		m_hwndFileOpenDlg,
417cdf0e10cSrcweir 		CDM_GETSPEC,
418cdf0e10cSrcweir 		m_helperBuffer.getCapacity(),
419cdf0e10cSrcweir 		reinterpret_cast<LPARAM>(m_helperBuffer.getStr()));
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 	if (nLen > 0)
422cdf0e10cSrcweir 	{
423cdf0e10cSrcweir 		m_helperBuffer.setLength((nLen * sizeof(sal_Unicode)) - 1);
424cdf0e10cSrcweir 		return rtl::OUString(m_helperBuffer);
425cdf0e10cSrcweir 	}
426cdf0e10cSrcweir 	return rtl::OUString();
427cdf0e10cSrcweir }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir //------------------------------------------------------------------------
430cdf0e10cSrcweir //
431cdf0e10cSrcweir //------------------------------------------------------------------------
432cdf0e10cSrcweir 
onShareViolation(const rtl::OUString &)433cdf0e10cSrcweir sal_uInt32 SAL_CALL CFileOpenDialog::onShareViolation(const rtl::OUString&)
434cdf0e10cSrcweir {
435cdf0e10cSrcweir 	return 0;
436cdf0e10cSrcweir }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir //------------------------------------------------------------------------
439cdf0e10cSrcweir //
440cdf0e10cSrcweir //------------------------------------------------------------------------
441cdf0e10cSrcweir 
onFileOk()442cdf0e10cSrcweir sal_uInt32 SAL_CALL CFileOpenDialog::onFileOk()
443cdf0e10cSrcweir {
444cdf0e10cSrcweir 	return 0;
445cdf0e10cSrcweir }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir //------------------------------------------------------------------------
448cdf0e10cSrcweir //
449cdf0e10cSrcweir //------------------------------------------------------------------------
450cdf0e10cSrcweir 
onSelChanged(HWND)451cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::onSelChanged(HWND)
452cdf0e10cSrcweir {
453cdf0e10cSrcweir }
454cdf0e10cSrcweir 
455cdf0e10cSrcweir //------------------------------------------------------------------------
456cdf0e10cSrcweir //
457cdf0e10cSrcweir //------------------------------------------------------------------------
458cdf0e10cSrcweir 
onHelp()459cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::onHelp()
460cdf0e10cSrcweir {
461cdf0e10cSrcweir }
462cdf0e10cSrcweir 
463cdf0e10cSrcweir //------------------------------------------------------------------------
464cdf0e10cSrcweir //
465cdf0e10cSrcweir //------------------------------------------------------------------------
466cdf0e10cSrcweir 
onInitDone()467cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::onInitDone()
468cdf0e10cSrcweir {
469cdf0e10cSrcweir     centerPositionToParent();
470cdf0e10cSrcweir }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir //------------------------------------------------------------------------
473cdf0e10cSrcweir //
474cdf0e10cSrcweir //------------------------------------------------------------------------
475cdf0e10cSrcweir 
onFolderChanged()476cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::onFolderChanged()
477cdf0e10cSrcweir {
478cdf0e10cSrcweir }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir //------------------------------------------------------------------------
481cdf0e10cSrcweir //
482cdf0e10cSrcweir //------------------------------------------------------------------------
483cdf0e10cSrcweir 
onTypeChanged(sal_uInt32)484cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::onTypeChanged(sal_uInt32)
485cdf0e10cSrcweir {
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
488cdf0e10cSrcweir //------------------------------------------------------------------------
489cdf0e10cSrcweir //
490cdf0e10cSrcweir //------------------------------------------------------------------------
491cdf0e10cSrcweir 
onCtrlCommand(HWND,sal_uInt16,sal_uInt16)492cdf0e10cSrcweir sal_uInt32 SAL_CALL CFileOpenDialog::onCtrlCommand(HWND, sal_uInt16, sal_uInt16)
493cdf0e10cSrcweir {
494cdf0e10cSrcweir 	return 0;
495cdf0e10cSrcweir }
496cdf0e10cSrcweir 
497cdf0e10cSrcweir //------------------------------------------------------------------------
498cdf0e10cSrcweir //
499cdf0e10cSrcweir //------------------------------------------------------------------------
500cdf0e10cSrcweir 
onWMNotify(HWND,LPOFNOTIFY lpOfNotify)501cdf0e10cSrcweir sal_uInt32 SAL_CALL CFileOpenDialog::onWMNotify( HWND, LPOFNOTIFY lpOfNotify )
502cdf0e10cSrcweir {
503cdf0e10cSrcweir 	switch(lpOfNotify->hdr.code)
504cdf0e10cSrcweir 	{
505cdf0e10cSrcweir 	case CDN_SHAREVIOLATION:
506cdf0e10cSrcweir 		return onShareViolation(reinterpret_cast<const sal_Unicode*>(lpOfNotify->pszFile));
507cdf0e10cSrcweir 
508cdf0e10cSrcweir 	case CDN_FILEOK:
509cdf0e10cSrcweir 		return onFileOk();
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 	case CDN_SELCHANGE:
512cdf0e10cSrcweir 		onSelChanged(lpOfNotify->hdr.hwndFrom);
513cdf0e10cSrcweir 		break;
514cdf0e10cSrcweir 
515cdf0e10cSrcweir 	case CDN_HELP:
516cdf0e10cSrcweir 		onHelp();
517cdf0e10cSrcweir 		break;
518cdf0e10cSrcweir 
519cdf0e10cSrcweir 	case CDN_INITDONE:
520cdf0e10cSrcweir 		onInitDone();
521cdf0e10cSrcweir 		break;
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 	case CDN_FOLDERCHANGE:
524cdf0e10cSrcweir 		onFolderChanged();
525cdf0e10cSrcweir 		break;
526cdf0e10cSrcweir 
527cdf0e10cSrcweir 	case CDN_TYPECHANGE:
528cdf0e10cSrcweir         m_ofn.nFilterIndex = lpOfNotify->lpOFN->nFilterIndex;
529cdf0e10cSrcweir 		onTypeChanged(lpOfNotify->lpOFN->nFilterIndex);
530cdf0e10cSrcweir 		break;
531cdf0e10cSrcweir 	}
532cdf0e10cSrcweir 
533cdf0e10cSrcweir 	return 0;
534cdf0e10cSrcweir }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir //------------------------------------------------------------------------
537cdf0e10cSrcweir //
538cdf0e10cSrcweir //------------------------------------------------------------------------
539cdf0e10cSrcweir 
handleInitDialog(HWND hwndDlg,HWND hwndChild)540cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::handleInitDialog(HWND hwndDlg, HWND hwndChild)
541cdf0e10cSrcweir {
542cdf0e10cSrcweir 	m_hwndFileOpenDlg      = hwndDlg;
543cdf0e10cSrcweir 	m_hwndFileOpenDlgChild = hwndChild;
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 	OSL_ASSERT(GetParent(hwndChild) == hwndDlg);
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 	// calling virtual function which the
548cdf0e10cSrcweir 	// client can overload
549cdf0e10cSrcweir 	onInitDialog(hwndDlg);
550cdf0e10cSrcweir }
551cdf0e10cSrcweir 
552cdf0e10cSrcweir //------------------------------------------------------------------------
553cdf0e10cSrcweir //
554cdf0e10cSrcweir //------------------------------------------------------------------------
555cdf0e10cSrcweir 
ofnHookProc(HWND hChildDlg,unsigned int uiMsg,WPARAM wParam,LPARAM lParam)556cdf0e10cSrcweir unsigned int CALLBACK CFileOpenDialog::ofnHookProc(
557cdf0e10cSrcweir 	HWND hChildDlg, unsigned int uiMsg, WPARAM wParam, LPARAM lParam)
558cdf0e10cSrcweir {
559cdf0e10cSrcweir     HWND hwndDlg = GetParent(hChildDlg);
560cdf0e10cSrcweir     CFileOpenDialog* pImpl = NULL;
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 	switch( uiMsg )
563cdf0e10cSrcweir 	{
564cdf0e10cSrcweir 	case WM_INITDIALOG:
565cdf0e10cSrcweir         {
566cdf0e10cSrcweir             _LPOPENFILENAME lpofn = reinterpret_cast<_LPOPENFILENAME>(lParam);
567cdf0e10cSrcweir             pImpl = reinterpret_cast<CFileOpenDialog*>(lpofn->lCustData);
568cdf0e10cSrcweir             OSL_ASSERT(pImpl);
569cdf0e10cSrcweir 
570cdf0e10cSrcweir             // subclass the base dialog for WM_NCDESTROY processing
571cdf0e10cSrcweir             pImpl->m_pfnBaseDlgProc =
572cdf0e10cSrcweir 		        reinterpret_cast<WNDPROC>(
573cdf0e10cSrcweir 			        SetWindowLong(
574cdf0e10cSrcweir 			            hwndDlg,
575cdf0e10cSrcweir 			            GWL_WNDPROC,
576cdf0e10cSrcweir                         reinterpret_cast<LONG>(CFileOpenDialog::BaseDlgProc)));
577cdf0e10cSrcweir             // connect the instance handle to the window
578cdf0e10cSrcweir             SetProp(hwndDlg, CURRENT_INSTANCE, pImpl);
579cdf0e10cSrcweir 		    pImpl->handleInitDialog(hwndDlg, hChildDlg);
580cdf0e10cSrcweir         }
581cdf0e10cSrcweir 		return 0;
582cdf0e10cSrcweir 
583cdf0e10cSrcweir 	case WM_NOTIFY:
584cdf0e10cSrcweir         {
585cdf0e10cSrcweir             pImpl = getCurrentInstance(hwndDlg);
586cdf0e10cSrcweir 		    return pImpl->onWMNotify(
587cdf0e10cSrcweir 			    hChildDlg, reinterpret_cast<LPOFNOTIFY>(lParam));
588cdf0e10cSrcweir         }
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 	case WM_COMMAND:
591cdf0e10cSrcweir         {
592cdf0e10cSrcweir             pImpl = getCurrentInstance(hwndDlg);
593cdf0e10cSrcweir             OSL_ASSERT(pImpl);
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 		    return pImpl->onCtrlCommand(
596cdf0e10cSrcweir 			    hChildDlg, LOWORD(wParam), HIWORD(lParam));
597cdf0e10cSrcweir         }
598cdf0e10cSrcweir 	}
599cdf0e10cSrcweir 
600cdf0e10cSrcweir 	return 0;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir 
603cdf0e10cSrcweir //------------------------------------------------------------------------
604cdf0e10cSrcweir //
605cdf0e10cSrcweir //------------------------------------------------------------------------
606cdf0e10cSrcweir 
BaseDlgProc(HWND hWnd,UINT wMessage,WPARAM wParam,LPARAM lParam)607cdf0e10cSrcweir LRESULT CALLBACK CFileOpenDialog::BaseDlgProc(
608cdf0e10cSrcweir     HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
609cdf0e10cSrcweir {
610cdf0e10cSrcweir 	CFileOpenDialog* pImpl = 0;
611cdf0e10cSrcweir 
612cdf0e10cSrcweir 	if (WM_NCDESTROY == wMessage)
613cdf0e10cSrcweir 	{
614cdf0e10cSrcweir 		pImpl = reinterpret_cast<CFileOpenDialog*>(
615cdf0e10cSrcweir 			RemoveProp(hWnd,CURRENT_INSTANCE));
616cdf0e10cSrcweir 
617cdf0e10cSrcweir 		SetWindowLong(hWnd, GWL_WNDPROC,
618cdf0e10cSrcweir 			reinterpret_cast<LONG>(pImpl->m_pfnBaseDlgProc));
619cdf0e10cSrcweir 	}
620cdf0e10cSrcweir 	else
621cdf0e10cSrcweir 	{
622cdf0e10cSrcweir 		pImpl = getCurrentInstance(hWnd);
623cdf0e10cSrcweir 	}
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 	OSL_ASSERT(pImpl);
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 	return CallWindowProc(
628cdf0e10cSrcweir 		reinterpret_cast<WNDPROC>(pImpl->m_pfnBaseDlgProc),
629cdf0e10cSrcweir 		hWnd,wMessage,wParam,lParam);
630cdf0e10cSrcweir }
631cdf0e10cSrcweir 
632cdf0e10cSrcweir //------------------------------------------------------------------------
633cdf0e10cSrcweir //
634cdf0e10cSrcweir //------------------------------------------------------------------------
635cdf0e10cSrcweir 
getCurrentInstance(HWND hwnd)636cdf0e10cSrcweir CFileOpenDialog* SAL_CALL CFileOpenDialog::getCurrentInstance(HWND hwnd)
637cdf0e10cSrcweir {
638cdf0e10cSrcweir     OSL_ASSERT(IsWindow( hwnd));
639cdf0e10cSrcweir     return reinterpret_cast<CFileOpenDialog*>(
640cdf0e10cSrcweir         GetProp(hwnd, CURRENT_INSTANCE));
641cdf0e10cSrcweir }
642cdf0e10cSrcweir 
643cdf0e10cSrcweir //------------------------------------------------------------------------
644cdf0e10cSrcweir //
645cdf0e10cSrcweir //------------------------------------------------------------------------
646cdf0e10cSrcweir 
centerPositionToParent() const647cdf0e10cSrcweir void SAL_CALL CFileOpenDialog::centerPositionToParent() const
648cdf0e10cSrcweir {
649cdf0e10cSrcweir     OSL_PRECOND(IsWindow(m_hwndFileOpenDlg), "no dialog window, call method only after or in onInitDone");
650cdf0e10cSrcweir 
651cdf0e10cSrcweir     HWND hwndParent = m_ofn.hwndOwner;
652cdf0e10cSrcweir 
653cdf0e10cSrcweir     if (!IsWindow(hwndParent))
654cdf0e10cSrcweir         hwndParent = GetDesktopWindow();
655cdf0e10cSrcweir 
656cdf0e10cSrcweir     OSL_ASSERT(IsWindow(hwndParent));
657cdf0e10cSrcweir 
658cdf0e10cSrcweir     RECT rcPar;
659cdf0e10cSrcweir     GetWindowRect(hwndParent, &rcPar);
660cdf0e10cSrcweir 
661cdf0e10cSrcweir     RECT rcDlg;
662cdf0e10cSrcweir     GetWindowRect(m_hwndFileOpenDlg, &rcDlg);
663cdf0e10cSrcweir 
664cdf0e10cSrcweir     int lDlgW = rcDlg.right  - rcDlg.left;
665cdf0e10cSrcweir     int lDlgH = rcDlg.bottom - rcDlg.top;
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 	int x = (rcPar.left + rcPar.right  - lDlgW) / 2;
668cdf0e10cSrcweir 	int y = (rcPar.top  + rcPar.bottom - lDlgH) / 2;
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 	HDC hdc = GetDC(m_hwndFileOpenDlg);
671cdf0e10cSrcweir 
672cdf0e10cSrcweir     int hResol = GetDeviceCaps(hdc, HORZRES);
673cdf0e10cSrcweir     int vResol = GetDeviceCaps(hdc, VERTRES);
674cdf0e10cSrcweir 
675cdf0e10cSrcweir 	ReleaseDC(m_hwndFileOpenDlg, hdc);
676cdf0e10cSrcweir 
677cdf0e10cSrcweir     if (x < 0)
678cdf0e10cSrcweir         x = 0;
679cdf0e10cSrcweir     else if ((x + lDlgW) > hResol)
680cdf0e10cSrcweir         x = hResol - lDlgW;
681cdf0e10cSrcweir 
682cdf0e10cSrcweir     if (y < 0)
683cdf0e10cSrcweir         y = 0;
684cdf0e10cSrcweir     else if ((y + lDlgH) > vResol)
685cdf0e10cSrcweir         y = vResol - lDlgH;
686cdf0e10cSrcweir 
687cdf0e10cSrcweir     SetWindowPos(
688cdf0e10cSrcweir         m_hwndFileOpenDlg,
689cdf0e10cSrcweir         NULL, x, y, 0, 0,
690cdf0e10cSrcweir         SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE );
691cdf0e10cSrcweir }
692