1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "nsReadableUtils.h"
10 #include "nsIServiceManager.h"
11 #include "nsIPlatformCharset.h"
14 #include "nsIStringBundle.h"
15 #include "nsEnumeratorUtils.h"
17 #include "nsIWidget.h"
19 #include "nsFilePicker.h"
22 #define MAX_PATH CCHMAXPATH
26 typedef struct _MyData
28 PAPSZ papszIFilterList
;
33 NS_IMPL_ISUPPORTS1(nsFilePicker
, nsIFilePicker
)
35 char nsFilePicker::mLastUsedDirectory
[MAX_PATH
+1] = { 0 };
38 static char* gpszFDSaveCaption
= 0;
39 static char* gpszFDFileExists
= 0;
40 static char* gpszFDFileReadOnly
= 0;
42 MRESULT EXPENTRY
DirDialogProc( HWND hwndDlg
, ULONG msg
, MPARAM mp1
, MPARAM mp2
);
43 MRESULT EXPENTRY
FileDialogProc( HWND hwndDlg
, ULONG msg
, MPARAM mp1
, MPARAM mp2
);
45 //-------------------------------------------------------------------------
47 // nsFilePicker constructor
49 //-------------------------------------------------------------------------
50 nsFilePicker::nsFilePicker()
53 mUnicodeEncoder
= nullptr;
54 mUnicodeDecoder
= nullptr;
58 //-------------------------------------------------------------------------
60 // nsFilePicker destructor
62 //-------------------------------------------------------------------------
63 nsFilePicker::~nsFilePicker()
68 NS_IF_RELEASE(mUnicodeEncoder
);
69 NS_IF_RELEASE(mUnicodeDecoder
);
73 nsFilePicker::ReleaseGlobals()
75 if (gpszFDSaveCaption
) {
76 free(gpszFDSaveCaption
);
77 free(gpszFDFileExists
);
78 free(gpszFDFileReadOnly
);
82 //-------------------------------------------------------------------------
84 // Show - Display the file dialog
86 //-------------------------------------------------------------------------
87 NS_IMETHODIMP
nsFilePicker::Show(int16_t *retval
)
89 NS_ENSURE_ARG_POINTER(retval
);
92 nsAutoCString fileBuffer
;
93 char *converted
= ConvertToFileSystemCharset(mDefault
);
94 if (nullptr == converted
) {
95 LossyCopyUTF16toASCII(mDefault
, fileBuffer
);
98 fileBuffer
.Assign(converted
);
99 nsMemory::Free( converted
);
102 char *title
= ConvertToFileSystemCharset(mTitle
);
103 if (nullptr == title
)
104 title
= ToNewCString(mTitle
);
105 nsAutoCString initialDir
;
106 if (mDisplayDirectory
)
107 mDisplayDirectory
->GetNativePath(initialDir
);
108 // If no display directory, re-use the last one.
109 if(initialDir
.IsEmpty())
110 initialDir
= mLastUsedDirectory
;
115 memset(&filedlg
, 0, sizeof(FILEDLG
));
116 filedlg
.cbSize
= sizeof(FILEDLG
);
117 filedlg
.pszTitle
= title
;
119 if (mMode
== modeGetFolder
) {
120 PL_strncat(filedlg
.szFullFile
, initialDir
.get(), MAX_PATH
);
121 if (filedlg
.szFullFile
[0] &&
122 filedlg
.szFullFile
[strlen(filedlg
.szFullFile
) - 1] != '\\')
123 PL_strncat(filedlg
.szFullFile
, "\\", 1);
124 PL_strncat(filedlg
.szFullFile
, "^", 1);
125 filedlg
.fl
= FDS_OPEN_DIALOG
| FDS_CENTER
;
126 filedlg
.pfnDlgProc
= DirDialogProc
;
127 DosError(FERR_DISABLEHARDERR
);
128 WinFileDlg(HWND_DESKTOP
, mWnd
, &filedlg
);
129 DosError(FERR_ENABLEHARDERR
);
130 char* tempptr
= strchr(filedlg
.szFullFile
, '^');
133 if (filedlg
.lReturn
== DID_OK
) {
135 if (!mDisplayDirectory
)
136 mDisplayDirectory
= do_CreateInstance("@mozilla.org/file/local;1");
137 if (mDisplayDirectory
)
138 mDisplayDirectory
->InitWithNativePath(nsDependentCString(filedlg
.szFullFile
));
139 mFile
.Assign(filedlg
.szFullFile
);
143 PL_strncpy(filedlg
.szFullFile
, initialDir
.get(), MAX_PATH
);
144 if (filedlg
.szFullFile
[0] &&
145 filedlg
.szFullFile
[strlen(filedlg
.szFullFile
) - 1] != '\\')
146 PL_strncat(filedlg
.szFullFile
, "\\", 1);
147 PL_strncat(filedlg
.szFullFile
, fileBuffer
.get(), MAX_PATH
);
148 filedlg
.fl
= FDS_CENTER
;
149 if (mMode
== modeSave
) {
150 filedlg
.fl
|= FDS_SAVEAS_DIALOG
| FDS_ENABLEFILELB
;
151 } else if (mMode
== modeOpenMultiple
) {
152 filedlg
.fl
|= FDS_MULTIPLESEL
| FDS_OPEN_DIALOG
;
154 filedlg
.fl
|= FDS_OPEN_DIALOG
;
157 pmydata
= (PMYDATA
)calloc(1, sizeof(MYDATA
));
158 filedlg
.ulUser
= (ULONG
)pmydata
;
159 filedlg
.pfnDlgProc
= FileDialogProc
;
164 apszTypeList
= (PSZ
*)malloc(mTitles
.Length()*sizeof(PSZ
)+1);
165 for (i
= 0; i
< mTitles
.Length(); i
++)
167 const nsString
& typeWide
= mTitles
[i
];
168 nsAutoCharBuffer buffer
;
170 WideCharToMultiByte(0, typeWide
.get(), typeWide
.Length(),
172 apszTypeList
[i
] = ToNewCString(nsDependentCString(buffer
.Elements()));
175 filedlg
.papszITypeList
= (PAPSZ
)apszTypeList
;
178 apszFilterList
= (PSZ
*)malloc(mFilters
.Length()*sizeof(PSZ
)+1);
179 for (i
= 0; i
< mFilters
.Length(); i
++)
181 const nsString
& filterWide
= mFilters
[i
];
182 apszFilterList
[i
] = ToNewCString(filterWide
);
184 apszFilterList
[i
] = 0;
185 pmydata
->papszIFilterList
= (PAPSZ
)apszFilterList
;
187 pmydata
->ulCurExt
= mSelectedType
;
189 bool fileExists
= true;
191 DosError(FERR_DISABLEHARDERR
);
192 WinFileDlg(HWND_DESKTOP
, mWnd
, &filedlg
);
193 DosError(FERR_ENABLEHARDERR
);
194 if ((filedlg
.lReturn
== DID_OK
) && (mMode
== modeSave
)) {
195 PRFileInfo64 fileinfo64
;
196 PRStatus status
= PR_GetFileInfo64(filedlg
.szFullFile
, &fileinfo64
);
197 if (status
== PR_SUCCESS
) {
203 if (!gpszFDSaveCaption
) {
205 char LoadError
[CCHMAXPATH
];
206 char loadedString
[256];
208 DosLoadModule(LoadError
, CCHMAXPATH
, "PMSDMRI", &hmod
);
209 length
= WinLoadString((HAB
)0, hmod
, 1110, 256, loadedString
);
210 gpszFDSaveCaption
= (char*)malloc(length
+1);
211 strcpy(gpszFDSaveCaption
, loadedString
);
212 length
= WinLoadString((HAB
)0, hmod
, 1135, 256, loadedString
);
213 gpszFDFileExists
= (char*)malloc(length
+1);
214 strcpy(gpszFDFileExists
, loadedString
);
215 length
= WinLoadString((HAB
)0, hmod
, 1136, 256, loadedString
);
216 gpszFDFileReadOnly
= (char*)malloc(length
+1);
217 strcpy(gpszFDFileReadOnly
, loadedString
);
219 for (i
=0;i
<256 && gpszFDFileExists
[i
];i
++ ) {
220 if (gpszFDFileExists
[i
] == '%') {
221 gpszFDFileExists
[i
+1] = 's';
225 for (i
=0;i
<256 && gpszFDFileReadOnly
[i
];i
++ ) {
226 if (gpszFDFileReadOnly
[i
] == '%') {
227 gpszFDFileReadOnly
[i
+1] = 's';
234 char pszFullText
[256+CCHMAXPATH
];
237 DosQueryPathInfo( filedlg
.szFullFile
, FIL_STANDARD
, &fsts3
, sizeof(FILESTATUS3
));
238 if (fsts3
.attrFile
& FILE_READONLY
) {
239 sprintf(pszFullText
, gpszFDFileReadOnly
, filedlg
.szFullFile
);
240 ulResponse
= WinMessageBox(HWND_DESKTOP
, mWnd
, pszFullText
,
241 gpszFDSaveCaption
, 0,
242 MB_OK
| MB_MOVEABLE
| MB_WARNING
);
244 sprintf(pszFullText
, gpszFDFileExists
, filedlg
.szFullFile
);
245 ulResponse
= WinMessageBox(HWND_DESKTOP
, mWnd
, pszFullText
,
246 gpszFDSaveCaption
, 0,
247 MB_YESNO
| MB_MOVEABLE
| MB_WARNING
);
250 if (ulResponse
== MBID_YES
) {
255 } while (mMode
== modeSave
&& fileExists
&& filedlg
.lReturn
== DID_OK
);
257 if (filedlg
.lReturn
== DID_OK
) {
259 if (mMode
== modeOpenMultiple
) {
262 if (filedlg
.papszFQFilename
) {
263 for (ULONG i
=0;i
<filedlg
.ulFQFCount
;i
++) {
264 nsCOMPtr
<nsIFile
> file
= do_CreateInstance("@mozilla.org/file/local;1", &rv
);
265 NS_ENSURE_SUCCESS(rv
,rv
);
267 rv
= file
->InitWithNativePath(nsDependentCString(*(filedlg
.papszFQFilename
)[i
]));
268 NS_ENSURE_SUCCESS(rv
,rv
);
270 rv
= mFiles
.AppendObject(file
);
271 NS_ENSURE_SUCCESS(rv
,rv
);
273 WinFreeFileDlgList(filedlg
.papszFQFilename
);
275 nsCOMPtr
<nsIFile
> file
= do_CreateInstance("@mozilla.org/file/local;1", &rv
);
276 NS_ENSURE_SUCCESS(rv
,rv
);
278 rv
= file
->InitWithNativePath(nsDependentCString(filedlg
.szFullFile
));
279 NS_ENSURE_SUCCESS(rv
,rv
);
281 rv
= mFiles
.AppendObject(file
);
282 NS_ENSURE_SUCCESS(rv
,rv
);
285 mFile
.Assign(filedlg
.szFullFile
);
287 mSelectedType
= (int16_t)pmydata
->ulCurExt
;
290 for (i
= 0; i
< mTitles
.Length(); i
++)
292 nsMemory::Free(*(filedlg
.papszITypeList
[i
]));
294 free(filedlg
.papszITypeList
);
296 for (i
= 0; i
< mFilters
.Length(); i
++)
298 nsMemory::Free(*(pmydata
->papszIFilterList
[i
]));
300 free(pmydata
->papszIFilterList
);
305 nsMemory::Free( title
);
308 int16_t returnOKorReplace
= returnOK
;
311 // Remember last used directory.
312 nsCOMPtr
<nsIFile
> file(do_CreateInstance("@mozilla.org/file/local;1", &rv
));
313 NS_ENSURE_SUCCESS(rv
, rv
);
315 file
->InitWithNativePath(mFile
);
316 nsCOMPtr
<nsIFile
> dir
;
317 if (NS_SUCCEEDED(file
->GetParent(getter_AddRefs(dir
)))) {
318 nsAutoCString newDir
;
319 dir
->GetNativePath(newDir
);
320 if(!newDir
.IsEmpty())
321 PL_strncpyz(mLastUsedDirectory
, newDir
.get(), MAX_PATH
+1);
322 // Update mDisplayDirectory with this directory, also.
323 // Some callers rely on this.
324 if (!mDisplayDirectory
)
325 mDisplayDirectory
= do_CreateInstance("@mozilla.org/file/local;1");
326 if (mDisplayDirectory
)
327 mDisplayDirectory
->InitWithNativePath( nsDependentCString(mLastUsedDirectory
) );
330 if (mMode
== modeSave
) {
331 // Windows does not return resultReplace,
332 // we must check if file already exists
334 file
->Exists(&exists
);
336 returnOKorReplace
= returnReplace
;
338 *retval
= returnOKorReplace
;
341 *retval
= returnCancel
;
348 NS_IMETHODIMP
nsFilePicker::GetFile(nsIFile
**aFile
)
350 NS_ENSURE_ARG_POINTER(aFile
);
355 nsCOMPtr
<nsIFile
> file(do_CreateInstance("@mozilla.org/file/local;1"));
357 NS_ENSURE_TRUE(file
, NS_ERROR_FAILURE
);
359 file
->InitWithNativePath(mFile
);
361 NS_ADDREF(*aFile
= file
);
366 //-------------------------------------------------------------------------
367 NS_IMETHODIMP
nsFilePicker::GetFileURL(nsIURI
**aFileURL
)
370 nsCOMPtr
<nsIFile
> file
;
371 nsresult rv
= GetFile(getter_AddRefs(file
));
375 return NS_NewFileURI(aFileURL
, file
);
378 NS_IMETHODIMP
nsFilePicker::GetFiles(nsISimpleEnumerator
**aFiles
)
380 NS_ENSURE_ARG_POINTER(aFiles
);
381 return NS_NewArrayEnumerator(aFiles
, mFiles
);
384 //-------------------------------------------------------------------------
386 // Get the file + path
388 //-------------------------------------------------------------------------
389 NS_IMETHODIMP
nsFilePicker::SetDefaultString(const nsAString
& aString
)
393 //First, make sure the file name is not too long!
395 int32_t nameIndex
= mDefault
.RFind("\\");
396 if (nameIndex
== kNotFound
)
400 nameLength
= mDefault
.Length() - nameIndex
;
402 if (nameLength
> CCHMAXPATH
) {
403 int32_t extIndex
= mDefault
.RFind(".");
404 if (extIndex
== kNotFound
)
405 extIndex
= mDefault
.Length();
407 //Let's try to shave the needed characters from the name part
408 int32_t charsToRemove
= nameLength
- CCHMAXPATH
;
409 if (extIndex
- nameIndex
>= charsToRemove
) {
410 mDefault
.Cut(extIndex
- charsToRemove
, charsToRemove
);
414 //Then, we need to replace illegal characters.
415 //Windows has the following statement:
416 //At this stage, we cannot replace the backslash as the string might represent a file path.
417 //But it is not correct - Windows assumes this is not a path as well,
418 //as one of the FILE_ILLEGAL_CHARACTERS is a colon (:)
420 mDefault
.ReplaceChar("\"", '\'');
421 mDefault
.ReplaceChar("<", '(');
422 mDefault
.ReplaceChar(">", ')');
424 mDefault
.ReplaceChar(FILE_ILLEGAL_CHARACTERS
, '_');
429 NS_IMETHODIMP
nsFilePicker::GetDefaultString(nsAString
& aString
)
431 return NS_ERROR_FAILURE
;
434 //-------------------------------------------------------------------------
436 // The default extension to use for files
438 //-------------------------------------------------------------------------
439 NS_IMETHODIMP
nsFilePicker::GetDefaultExtension(nsAString
& aExtension
)
441 aExtension
= mDefaultExtension
;
445 NS_IMETHODIMP
nsFilePicker::SetDefaultExtension(const nsAString
& aExtension
)
447 mDefaultExtension
= aExtension
;
451 //-------------------------------------------------------------------------
453 // Set the filter index
455 //-------------------------------------------------------------------------
456 NS_IMETHODIMP
nsFilePicker::GetFilterIndex(int32_t *aFilterIndex
)
458 *aFilterIndex
= mSelectedType
;
462 NS_IMETHODIMP
nsFilePicker::SetFilterIndex(int32_t aFilterIndex
)
464 mSelectedType
= aFilterIndex
;
468 //-------------------------------------------------------------------------
469 void nsFilePicker::InitNative(nsIWidget
*aParent
,
470 const nsAString
& aTitle
)
472 mWnd
= (HWND
) ((aParent
) ? aParent
->GetNativeData(NS_NATIVE_WINDOW
) : 0);
473 mTitle
.Assign(aTitle
);
477 //-------------------------------------------------------------------------
478 void nsFilePicker::GetFileSystemCharset(nsCString
& fileSystemCharset
)
480 static nsAutoCString aCharset
;
483 if (aCharset
.Length() < 1) {
484 nsCOMPtr
<nsIPlatformCharset
> platformCharset
= do_GetService(NS_PLATFORMCHARSET_CONTRACTID
, &rv
);
485 if (NS_SUCCEEDED(rv
))
486 rv
= platformCharset
->GetCharset(kPlatformCharsetSel_FileName
, aCharset
);
488 NS_ASSERTION(NS_SUCCEEDED(rv
), "error getting platform charset");
490 aCharset
.AssignLiteral("IBM850");
492 fileSystemCharset
= aCharset
;
495 //-------------------------------------------------------------------------
496 char * nsFilePicker::ConvertToFileSystemCharset(const nsAString
& inString
)
498 char *outString
= nullptr;
501 // get file system charset and create a unicode encoder
502 if (nullptr == mUnicodeEncoder
) {
503 nsAutoCString fileSystemCharset
;
504 GetFileSystemCharset(fileSystemCharset
);
506 nsCOMPtr
<nsICharsetConverterManager
> ccm
=
507 do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID
, &rv
);
508 if (NS_SUCCEEDED(rv
)) {
509 rv
= ccm
->GetUnicodeEncoderRaw(fileSystemCharset
.get(), &mUnicodeEncoder
);
513 // converts from unicode to the file system charset
514 if (NS_SUCCEEDED(rv
)) {
515 int32_t inLength
= inString
.Length();
517 const nsAFlatString
& flatInString
= PromiseFlatString(inString
);
520 rv
= mUnicodeEncoder
->GetMaxLength(flatInString
.get(), inLength
,
522 if (NS_SUCCEEDED(rv
)) {
523 outString
= static_cast<char*>(nsMemory::Alloc( outLength
+1 ));
524 if (nullptr == outString
) {
527 rv
= mUnicodeEncoder
->Convert(flatInString
.get(), &inLength
, outString
,
529 if (NS_SUCCEEDED(rv
)) {
530 outString
[outLength
] = '\0';
535 return NS_SUCCEEDED(rv
) ? outString
: nullptr;
538 //-------------------------------------------------------------------------
539 char16_t
* nsFilePicker::ConvertFromFileSystemCharset(const char *inString
)
541 char16_t
*outString
= nullptr;
544 // get file system charset and create a unicode encoder
545 if (nullptr == mUnicodeDecoder
) {
546 nsAutoCString fileSystemCharset
;
547 GetFileSystemCharset(fileSystemCharset
);
549 nsCOMPtr
<nsICharsetConverterManager
> ccm
=
550 do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID
, &rv
);
551 if (NS_SUCCEEDED(rv
)) {
552 rv
= ccm
->GetUnicodeDecoderRaw(fileSystemCharset
.get(), &mUnicodeDecoder
);
556 // converts from the file system charset to unicode
557 if (NS_SUCCEEDED(rv
)) {
558 int32_t inLength
= strlen(inString
);
560 rv
= mUnicodeDecoder
->GetMaxLength(inString
, inLength
, &outLength
);
561 if (NS_SUCCEEDED(rv
)) {
562 outString
= static_cast<char16_t
*>(nsMemory::Alloc( (outLength
+1) * sizeof( char16_t
) ));
563 if (nullptr == outString
) {
566 rv
= mUnicodeDecoder
->Convert(inString
, &inLength
, outString
, &outLength
);
567 if (NS_SUCCEEDED(rv
)) {
568 outString
[outLength
] = 0;
573 NS_ASSERTION(NS_SUCCEEDED(rv
), "error charset conversion");
574 return NS_SUCCEEDED(rv
) ? outString
: nullptr;
579 nsFilePicker::AppendFilter(const nsAString
& aTitle
, const nsAString
& aFilter
)
581 if (aFilter
.EqualsLiteral("..apps"))
582 mFilters
.AppendElement(NS_LITERAL_STRING("*.exe;*.cmd;*.com;*.bat"));
584 mFilters
.AppendElement(aFilter
);
585 mTitles
.AppendElement(aTitle
);
590 MRESULT EXPENTRY
DirDialogProc( HWND hwndDlg
, ULONG msg
, MPARAM mp1
, MPARAM mp2
)
612 ULONG ulCurY
, ulCurX
;
613 LONG lScreenX
, lScreenY
, lDlgFrameX
, lDlgFrameY
, lTitleBarY
;
615 lScreenX
= WinQuerySysValue(HWND_DESKTOP
, SV_CXSCREEN
);
616 lScreenY
= WinQuerySysValue(HWND_DESKTOP
, SV_CYSCREEN
);
617 lDlgFrameX
= WinQuerySysValue(HWND_DESKTOP
, SV_CXDLGFRAME
);
618 lDlgFrameY
= WinQuerySysValue(HWND_DESKTOP
, SV_CYDLGFRAME
);
619 lTitleBarY
= WinQuerySysValue(HWND_DESKTOP
, SV_CYTITLEBAR
);
621 hwndFileST
= WinWindowFromID(hwndDlg
, DID_FILENAME_TXT
);
622 hwndDirST
= WinWindowFromID(hwndDlg
, DID_DIRECTORY_TXT
);
623 hwndDirLB
= WinWindowFromID(hwndDlg
, DID_DIRECTORY_LB
);
624 hwndDriveST
= WinWindowFromID(hwndDlg
, DID_DRIVE_TXT
);
625 hwndDriveCB
= WinWindowFromID(hwndDlg
, DID_DRIVE_CB
);
626 hwndOK
= WinWindowFromID(hwndDlg
, DID_OK
);
627 hwndCancel
= WinWindowFromID(hwndDlg
, DID_CANCEL
);
630 // Reposition drives combobox
632 ulCurX
= SPACING
+ lDlgFrameX
;
633 WinQueryWindowPos(hwndOK
, &swpOK
);
634 WinSetWindowPos(hwndOK
, 0, ulCurX
, ulCurY
, 0, 0, SWP_MOVE
);
635 ulCurY
+= swpOK
.cy
+ SPACING
;
636 WinQueryWindowPos(hwndCancel
, &swpCancel
);
637 WinSetWindowPos(hwndCancel
, 0, ulCurX
+swpOK
.cx
+10, SPACING
, 0, 0, SWP_MOVE
);
638 WinQueryWindowPos(hwndDirLB
, &swpDirLB
);
639 WinSetWindowPos(hwndDirLB
, 0, ulCurX
, ulCurY
, swpDirLB
.cx
, swpDirLB
.cy
, SWP_MOVE
| SWP_SIZE
);
640 ulCurY
+= swpDirLB
.cy
+ SPACING
;
641 WinQueryWindowPos(hwndDirST
, &swpDirST
);
642 WinSetWindowPos(hwndDirST
, 0, ulCurX
, ulCurY
, swpDirST
.cx
, swpDirST
.cy
, SWP_MOVE
| SWP_SIZE
);
643 ulCurY
+= swpDirST
.cy
+ SPACING
;
644 WinQueryWindowPos(hwndDriveCB
, &swpDriveCB
);
645 WinQueryWindowPos(WinWindowFromID(hwndDriveCB
, CBID_EDIT
), &swpDriveCBEF
);
646 WinSetWindowPos(hwndDriveCB
, 0, ulCurX
, ulCurY
-(swpDriveCB
.cy
-swpDriveCBEF
.cy
)+5,
649 SWP_SIZE
| SWP_MOVE
);
650 ulCurY
+= swpDriveCBEF
.cy
+ SPACING
;
651 WinQueryWindowPos(hwndDriveST
, &swpDriveST
);
652 WinSetWindowPos(hwndDriveST
, 0, ulCurX
, ulCurY
, swpDriveST
.cx
, swpDriveST
.cy
, SWP_MOVE
| SWP_SIZE
);
653 ulCurY
+= swpDriveST
.cy
+ SPACING
;
654 WinQueryWindowPos(hwndFileST
, &swpFileST
);
655 WinSetWindowPos(hwndFileST
, 0, ulCurX
, ulCurY
, swpFileST
.cx
, swpFileST
.cy
, SWP_MOVE
| SWP_SIZE
);
656 ulCurY
+= swpFileST
.cy
+ SPACING
;
659 henum
= WinBeginEnumWindows(hwndDlg
);
660 while ((hwndNext
= WinGetNextWindow(henum
)) != NULLHANDLE
)
662 USHORT usID
= WinQueryWindowUShort(hwndNext
, QWS_ID
);
663 if (usID
!= DID_FILENAME_TXT
&&
664 usID
!= DID_DIRECTORY_TXT
&&
665 usID
!= DID_DIRECTORY_LB
&&
666 usID
!= DID_DRIVE_TXT
&&
667 usID
!= DID_DRIVE_CB
&&
669 usID
!= DID_CANCEL
&&
670 usID
!= FID_TITLEBAR
&&
671 usID
!= FID_SYSMENU
&&
674 WinShowWindow(hwndNext
, FALSE
);
678 WinSetWindowPos(hwndDlg
,
680 (lScreenX
/2)-((swpDirLB
.cx
+2*SPACING
+2*lDlgFrameX
)/2),
681 (lScreenY
/2)-((ulCurY
+2*lDlgFrameY
+lTitleBarY
)/2),
682 swpDirLB
.cx
+2*SPACING
+2*lDlgFrameX
,
683 ulCurY
+2*lDlgFrameY
+lTitleBarY
,
684 SWP_MOVE
| SWP_SIZE
);
690 pfiledlg
= (PFILEDLG
)WinQueryWindowPtr(hwndDlg
, QWL_USER
);
695 RECTL rectlString
= {0,0,1000,1000};
699 CHAR szString
[CCHMAXPATH
];
701 hwndST
= WinWindowFromID(hwndDlg
, DID_FILENAME_TXT
);
703 strcpy(szString
, pfiledlg
->szFullFile
);
704 iLength
= strlen(pfiledlg
->szFullFile
);
705 /* If we are not just a drive */
707 if (szString
[iLength
-1] == '\\') {
708 szString
[iLength
-1] = '\0';
713 hps
= WinGetPS(hwndST
);
714 WinQueryWindowPos(hwndST
, &swp
);
716 WinDrawText(hps
, iLength
, szString
,
718 DT_BOTTOM
| DT_QUERYEXTENT
| DT_TEXTATTRS
);
719 while(rectlString
.xRight
> swp
.cx
)
721 iHalfLen
= iLength
/ 2;
725 ptr
= szString
+ iHalfLen
;
726 memmove(ptr
- 1, ptr
, strlen(ptr
) + 1);
727 szString
[iHalfLen
- 2] = '.';
728 szString
[iHalfLen
- 1] = '.';
729 szString
[iHalfLen
] = '.';
730 iLength
= strlen(szString
);
731 rectlString
.xLeft
= rectlString
.yBottom
= 0;
732 rectlString
.xRight
= rectlString
.yTop
= 1000;
733 WinDrawText(hps
, iLength
, szString
,
735 DT_BOTTOM
| DT_QUERYEXTENT
| DT_TEXTATTRS
);
739 WinSetWindowText(hwndST
, szString
);
743 return WinDefFileDlgProc(hwndDlg
, msg
, mp1
, mp2
);
746 MRESULT EXPENTRY
FileDialogProc( HWND hwndDlg
, ULONG msg
, MPARAM mp1
, MPARAM mp2
)
757 /* Create another dropdown that we manage */
758 mr
= WinDefFileDlgProc(hwndDlg
, msg
, mp1
, mp2
);
759 hwndTypeCombo
= WinWindowFromID(hwndDlg
, DID_FILTER_CB
);
760 WinQueryWindowPos(hwndTypeCombo
, &swp
);
761 WinSetWindowPos(hwndTypeCombo
, NULLHANDLE
, 0, 0, 0, 0, SWP_HIDE
);
762 hwndTypeCombo
= WinCreateWindow( hwndDlg
, WC_COMBOBOX
, "",
763 WS_VISIBLE
| WS_PARENTCLIP
| WS_SYNCPAINT
| WS_TABSTOP
| CBS_DROPDOWNLIST
,
765 swp
.cx
, swp
.cy
, hwndDlg
, swp
.hwndInsertBehind
, 290,
767 WinSendMsg( hwndTypeCombo
, LM_DELETEALL
, (MPARAM
)0, (MPARAM
)0 );
768 pfiledlg
= (PFILEDLG
)WinQueryWindowULong( hwndDlg
, QWL_USER
);
769 pmydata
= (PMYDATA
)pfiledlg
->ulUser
;
771 while (*(pfiledlg
->papszITypeList
[i
]) != nullptr) {
772 WinSendMsg( hwndTypeCombo
, LM_INSERTITEM
, (MPARAM
)LIT_END
, (MPARAM
)*(pfiledlg
->papszITypeList
[i
]) );
775 WinSendMsg( hwndTypeCombo
, LM_SELECTITEM
, (MPARAM
)pmydata
->ulCurExt
, (MPARAM
)TRUE
);
780 if ((SHORT1FROMMP(mp1
) == 290) &&
781 (SHORT2FROMMP(mp1
) == CBN_LBSELECT
)) {
782 hwndTypeCombo
= WinWindowFromID(hwndDlg
, 290);
783 pfiledlg
= (PFILEDLG
)WinQueryWindowULong( hwndDlg
, QWL_USER
);
784 pmydata
= (PMYDATA
)pfiledlg
->ulUser
;
785 pmydata
->ulCurExt
= (ULONG
)WinSendMsg( hwndTypeCombo
, LM_QUERYSELECTION
, (MPARAM
)LIT_FIRST
, (MPARAM
)0 );
786 if (pfiledlg
->fl
& FDS_OPEN_DIALOG
) {
787 WinSetWindowText(WinWindowFromID(hwndDlg
,DID_FILENAME_ED
), *(pmydata
->papszIFilterList
[pmydata
->ulCurExt
]));
788 WinSendMsg(WinWindowFromID(hwndDlg
,DID_FILENAME_ED
), EM_SETSEL
, MPFROM2SHORT(0, 32000), (MPARAM
)0 );
789 WinSendMsg(hwndDlg
, WM_CONTROL
, MPFROM2SHORT(DID_FILTER_CB
, CBN_LBSELECT
), (MPARAM
)0 );
791 return (MRESULT
)TRUE
;
796 return WinDefFileDlgProc(hwndDlg
, msg
, mp1
, mp2
);