xref: /AOO41X/main/fpicker/source/win32/filepicker/FileOpenDlg.hxx (revision 10ce801889b00990ebdbcb412f4f91e2a9e6f21d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _FILEOPENDLG_HXX_
25 #define _FILEOPENDLG_HXX_
26 
27 //------------------------------------------------------------------------
28 // includes
29 //------------------------------------------------------------------------
30 
31 #include <sal/types.h>
32 
33 #ifndef _RTL_USTRING_HXX_
34 #include <rtl/ustring>
35 #endif
36 #include <rtl/ustrbuf.hxx>
37 
38 #include "platform_xp.h"
39 #include "getfilenamewrapper.hxx"
40 
41 // because we don't want to import the new W2k platform skd
42 // into our build environment if have stolen the definition
43 // for the new OPENFILENAME structure from the new headers
44 
45 #ifndef _CDSIZEOF_STRUCT
46 #define _CDSIZEOF_STRUCT(structname, member)  (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
47 #endif
48 
49 typedef struct _tagOFNA {
50    DWORD        lStructSize;
51    HWND         hwndOwner;
52    HINSTANCE    hInstance;
53    LPCSTR       lpstrFilter;
54    LPSTR        lpstrCustomFilter;
55    DWORD        nMaxCustFilter;
56    DWORD        nFilterIndex;
57    LPSTR        lpstrFile;
58    DWORD        nMaxFile;
59    LPSTR        lpstrFileTitle;
60    DWORD        nMaxFileTitle;
61    LPCSTR       lpstrInitialDir;
62    LPCSTR       lpstrTitle;
63    DWORD        Flags;
64    WORD         nFileOffset;
65    WORD         nFileExtension;
66    LPCSTR       lpstrDefExt;
67    LPARAM       lCustData;
68    LPOFNHOOKPROC lpfnHook;
69    LPCSTR       lpTemplateName;
70 #ifdef _MAC
71    LPEDITMENU   lpEditInfo;
72    LPCSTR       lpstrPrompt;
73 #endif
74 #if (_WIN32_WINNT >= 0x0500)
75    void *       pvReserved;
76    DWORD        dwReserved;
77    DWORD        FlagsEx;
78 #endif // (_WIN32_WINNT >= 0x0500)
79 } _OPENFILENAMEA, *_LPOPENFILENAMEA;
80 
81 typedef struct _tagOFNW {
82    DWORD        lStructSize;
83    HWND         hwndOwner;
84    HINSTANCE    hInstance;
85    LPCWSTR      lpstrFilter;
86    LPWSTR       lpstrCustomFilter;
87    DWORD        nMaxCustFilter;
88    DWORD        nFilterIndex;
89    LPWSTR       lpstrFile;
90    DWORD        nMaxFile;
91    LPWSTR       lpstrFileTitle;
92    DWORD        nMaxFileTitle;
93    LPCWSTR      lpstrInitialDir;
94    LPCWSTR      lpstrTitle;
95    DWORD        Flags;
96    WORD         nFileOffset;
97    WORD         nFileExtension;
98    LPCWSTR      lpstrDefExt;
99    LPARAM       lCustData;
100    LPOFNHOOKPROC lpfnHook;
101    LPCWSTR      lpTemplateName;
102 #if (_WIN32_WINNT >= 0x0500)
103    void *       pvReserved;
104    DWORD        dwReserved;
105    DWORD        FlagsEx;
106 #endif // (_WIN32_WINNT >= 0x0500)
107 } _OPENFILENAMEW, *_LPOPENFILENAMEW;
108 
109 #ifdef UNICODE
110 typedef _OPENFILENAMEW _OPENFILENAME;
111 typedef _LPOPENFILENAMEW _LPOPENFILENAME;
112 #else
113 typedef _OPENFILENAMEA _OPENFILENAME;
114 typedef _LPOPENFILENAMEA _LPOPENFILENAME;
115 #endif // UNICODE
116 
117 #if (_WIN32_WINNT >= 0x0500)
118     #define _OPENFILENAME_SIZE_VERSION_400A  _CDSIZEOF_STRUCT(_OPENFILENAMEA,lpTemplateName)
119     #define _OPENFILENAME_SIZE_VERSION_400W  _CDSIZEOF_STRUCT(_OPENFILENAMEW,lpTemplateName)
120     #ifdef UNICODE
121         #define _OPENFILENAME_SIZE_VERSION_400  _OPENFILENAME_SIZE_VERSION_400W
122     #else
123         #define _OPENFILENAME_SIZE_VERSION_400  _OPENFILENAME_SIZE_VERSION_400A
124     #endif // !UNICODE
125 #else
126     #error _WIN32_WINNT seams not to be valid.
127 #endif // (_WIN32_WINNT >= 0x0500)
128 
129 
130 //-------------------------------------------------------------
131 // A simple wrapper class around the Win32 GetOpenFileName API.
132 // This class is not thread-safe and only one instance at a
133 // time is allowed
134 //-------------------------------------------------------------
135 
136 class CFileOpenDialog
137 {
138 public:
139     // ctor
140     // bFileOpenDialog idicates if we want a FileOpen or FileSave
141     // dialog
142     // dwFlags see OPENFILENAME
143     // dwTemplateId - an ID for custom templates
144     // hInstance    - an instance handle for the module
145     // which provides the custom template, unused if dwTemplateId
146     // is 0
147     CFileOpenDialog(
148         bool bFileOpenDialog = sal_True,
149         sal_uInt32 dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
150         sal_uInt32 dwTemplateId = 0,
151         HINSTANCE hInstance = 0);
152 
153     virtual ~CFileOpenDialog();
154 
155     virtual void SAL_CALL setTitle(const rtl::OUString& aTitle);
156 
157     // to set a filter string using the M$ format
158     // e.g. FltName\0*.txt;*.rtf\0...\0\0
159     void SAL_CALL setFilter(const rtl::OUString& aFilter);
160 
161     // set the index of the current filter when the
162     // dialog is about to shown, the index starts with 1
163     // the function succeeded if the given filter index
164     // is greater than zero and is a valid position
165     // within filter string that was previously set
166     bool SAL_CALL setFilterIndex(sal_uInt32 aIndex);
167 
168     // get the index of the currently selected filter
169     // the index of the returned filter starts with 1
170     sal_uInt32 SAL_CALL getSelectedFilterIndex() const;
171 
172     // set the name and optional the path of the
173     // file that will be initially be shown when
174     // the dialog will be displayed
175     virtual void SAL_CALL setDefaultName(const rtl::OUString& aName);
176 
177     // set the initial directory
178     virtual void SAL_CALL setDisplayDirectory(const rtl::OUString& aDirectory);
179 
180     // returns only the path of the selected file
181     virtual rtl::OUString SAL_CALL getLastDisplayDirectory() const;
182 
183     // returns the full file name including drive letter, path
184     // file name and file extension
185     virtual rtl::OUString SAL_CALL getFullFileName() const;
186 
187     // returns the file name and the file extension without
188     // drive letter and path
189     rtl::OUString SAL_CALL getFileName() const;
190 
191     // returns the file extension of the selected file
192     rtl::OUString SAL_CALL getFileExtension();
193 
194     // set a default extension, only the first three letters of
195     // the given extension will be used; the given extension
196     // should not contain a '.'
197     void SAL_CALL setDefaultFileExtension(const rtl::OUString& aExtension);
198 
199     // enables or disables the multiselection mode for
200     // the FileOpen/FileSave dialog
201     void SAL_CALL setMultiSelectionMode(bool bMode);
202 
203     // returns whether multi-selection mode is enabled or not
204     bool SAL_CALL getMultiSelectionMode() const;
205 
206     // shows the dialog, calls preModal before
207     // showing the dialog and postModal after
208     // showing the dialog
209     // the method returns:
210     //  0 - when the dialog was canceled by the user
211     //  1 - when the dialog was closed with ok
212     // -1 - when an error occured
213     sal_Int16 SAL_CALL doModal();
214 
215     // returns the last dialog error that occured
216     sal_uInt32 SAL_CALL getLastDialogError() const;
217 
218     // retrievs the currently selected file
219     // including path and drive information
220     // can be called only if the dialog is
221     // already displayed
222     rtl::OUString SAL_CALL getCurrentFilePath() const;
223 
224     // retrievs the currently selected folder
225     rtl::OUString SAL_CALL getCurrentFolderPath() const;
226 
227     // retrievs the currently selected file name
228     // without drive and path
229     rtl::OUString SAL_CALL getCurrentFileName() const;
230 
231 protected:
232     // have to be overwritten when subclasses
233     // want to do special pre- and post-modal
234     // processing
235 
236     // if preModal return true processing will
237     // continue else doModal exit without showing
238     // a dialog and returns -1
239     virtual bool SAL_CALL preModal();
240 
241     // post modal processing
242     // the function should accept only values returned from
243     // doModal and act appropriately
244     virtual void SAL_CALL postModal(sal_Int16 nDialogResult);
245 
246     // message handler, to be overwritten by subclasses
247     virtual sal_uInt32 SAL_CALL onShareViolation(const rtl::OUString& aPathName);
248     virtual sal_uInt32 SAL_CALL onFileOk();
249     virtual void SAL_CALL onSelChanged(HWND hwndListBox);
250     virtual void SAL_CALL onHelp();
251 
252     // only called back if OFN_EXPLORER is set
253     virtual void SAL_CALL onInitDone();
254     virtual void SAL_CALL onFolderChanged();
255     virtual void SAL_CALL onTypeChanged(sal_uInt32 nFilterIndex);
256 
257     virtual void SAL_CALL onInitDialog(HWND hwndDlg) = 0;
258 
259     virtual sal_uInt32 SAL_CALL onCtrlCommand(HWND hwndDlg, sal_uInt16 ctrlId, sal_uInt16 notifyCode);
260 
261     sal_uInt32 SAL_CALL onWMNotify(HWND hwndChild, LPOFNOTIFYW lpOfNotify);
262 
263     // we use non-virtual functions to do necessary work before
264     // calling the virtual funtions (see Gamma: Template method)
265     void SAL_CALL handleInitDialog(HWND hwndDlg, HWND hwndChild);
266 
267 protected:
268 
269     // handle to the window of the
270     // FileOpen/FileSave dialog
271     // will be set on message
272     // WM_INITDIALOG, before this
273     // value is undefined
274     HWND    m_hwndFileOpenDlg;
275     HWND    m_hwndFileOpenDlgChild;
276 
277     _OPENFILENAME   m_ofn;
278 
279     // we connect the instance with the dialog window using
280     // SetProp, with this function we can reconnect from
281     // callback functions to this instance
282     static CFileOpenDialog* SAL_CALL getCurrentInstance(HWND hwnd);
283 
284     void SAL_CALL centerPositionToParent() const;
285 
286 private:
287     // FileOpen or FileSaveDialog
288     bool            m_bFileOpenDialog;
289     rtl::OUString   m_dialogTitle;
290     rtl::OUString   m_displayDirectory;
291     rtl::OUString   m_defaultExtension;
292 
293     mutable rtl::OUStringBuffer m_filterBuffer;
294     mutable rtl::OUStringBuffer m_fileTitleBuffer;
295     mutable rtl::OUStringBuffer m_helperBuffer;
296     mutable rtl::OUStringBuffer m_fileNameBuffer;
297 
298     CGetFileNameWrapper m_GetFileNameWrapper;
299 
300     WNDPROC             m_pfnBaseDlgProc;
301 
302     // callback function
303     static unsigned int CALLBACK ofnHookProc(
304         HWND hChildDlg, // handle to child dialog box
305         unsigned int uiMsg,     // message identifier
306         WPARAM wParam,  // message parameter
307         LPARAM lParam   // message parameter
308     );
309 
310     // we have to subclass the dialog in order
311     // to clean up the window property we are
312     // using to connect the window with a class
313     // instance in WM_NCDESTROY
314     static LRESULT CALLBACK BaseDlgProc(
315         HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam );
316 
317 private:
318     // avoid copy and assignment
319     CFileOpenDialog(const CFileOpenDialog&);
320     CFileOpenDialog& operator=(const CFileOpenDialog&);
321 };
322 
323 #endif
324