diff options
| author | Manolo Gouy <Manolo> | 2014-11-06 21:33:09 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2014-11-06 21:33:09 +0000 |
| commit | f2bb3ea76cae066113683641043d835c53658301 (patch) | |
| tree | 72793e6147a3bec67b28de12fcac8e938c4e5dae /src | |
| parent | bd1446a6eb5b845179bb850c0f371a323141e8b0 (diff) | |
The Fl_Native_File_Chooser class contains, under WIN32, two system-defined structures
(OPENFILENAMEW and BROWSEINFOW). This forces any application program that uses
Fl_Native_File_Chooser to include file windows.h.
This is corrected by using in the Fl_Native_File_Chooser class pointers to the 2 structures.
The changes are protected by #if FLTK_ABI_VERSION >= 10304 for ABI compatibility.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10437 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Native_File_Chooser_WIN32.cxx | 176 |
1 files changed, 96 insertions, 80 deletions
diff --git a/src/Fl_Native_File_Chooser_WIN32.cxx b/src/Fl_Native_File_Chooser_WIN32.cxx index 45890b298..fbadd21a0 100644 --- a/src/Fl_Native_File_Chooser_WIN32.cxx +++ b/src/Fl_Native_File_Chooser_WIN32.cxx @@ -2,7 +2,7 @@ // // FLTK native OS file chooser widget // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2014 by Bill Spitzak and others. // Copyright 2004 Greg Ercolano. // API changes + filter improvements by Nathan Vander Wilt 2005 // @@ -22,19 +22,26 @@ // #ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE +#include <FL/Enumerations.H> + +#if FLTK_ABI_VERSION < 10304 +#define _ofn_ptr (&_ofn) +#define _binf_ptr (&_binf) +#endif + +# include <stdlib.h> // malloc +# include <stdio.h> // sprintf +#include <wchar.h> -#include <stdio.h> // debugging -#include <wchar.h> //MG #include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat #define FNFC_MAX_PATH 32768 // XXX: MAX_PATH under win32 is 260, too small for modern use -typedef const wchar_t *LPCWSTR; //MG -LPCWSTR utf8towchar(const char *in); //MG -char *wchartoutf8(LPCWSTR in); //MG - #include <FL/Fl_Native_File_Chooser.H> -#include <FL/x.H> +static LPCWSTR utf8towchar(const char *in); +static char *wchartoutf8(LPCWSTR in); + +#include <FL/x.H> // for fl_open_display #define LCURLY_CHR '{' #define RCURLY_CHR '}' @@ -43,6 +50,7 @@ char *wchartoutf8(LPCWSTR in); //MG // STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG) #ifdef DEBUG +#include <stdio.h> static void dnullprint(char *wp) { if ( ! wp ) return; for ( int t=0; true; t++ ) { @@ -125,10 +133,14 @@ static void dnullcat(char*&wp, const char *string, int n = -1 ) { Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { _btype = val; _options = NO_OPTIONS; - memset((void*)&_ofn, 0, sizeof(OPENFILENAMEW)); - _ofn.lStructSize = sizeof(OPENFILENAMEW); - _ofn.hwndOwner = NULL; - memset((void*)&_binf, 0, sizeof(BROWSEINFO)); +#if FLTK_ABI_VERSION >= 10304 + _ofn_ptr = new OPENFILENAMEW; + _binf_ptr = new BROWSEINFOW; +#endif + memset((void*)_ofn_ptr, 0, sizeof(OPENFILENAMEW)); + _ofn_ptr->lStructSize = sizeof(OPENFILENAMEW); + _ofn_ptr->hwndOwner = NULL; + memset((void*)_binf_ptr, 0, sizeof(BROWSEINFOW)); _pathnames = NULL; _tpathnames = 0; _directory = NULL; @@ -155,6 +167,10 @@ Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { clear_pathnames(); ClearOFN(); ClearBINF(); +#if FLTK_ABI_VERSION >= 10304 + delete _binf_ptr; + delete _ofn_ptr; +#endif } // SET TYPE OF BROWSER @@ -222,7 +238,7 @@ void Fl_Native_File_Chooser::add_pathname(const char *s) { } // FREE A PIDL (Pointer to IDentity List) -void Fl_Native_File_Chooser::FreePIDL(LPITEMIDLIST pidl) { +static void FreePIDL(LPITEMIDLIST pidl) { IMalloc *imalloc = NULL; if ( SUCCEEDED(SHGetMalloc(&imalloc)) ) { imalloc->Free(pidl); @@ -233,29 +249,29 @@ void Fl_Native_File_Chooser::FreePIDL(LPITEMIDLIST pidl) { // CLEAR MICROSOFT OFN (OPEN FILE NAME) CLASS void Fl_Native_File_Chooser::ClearOFN() { - // Free any previously allocated lpstrFile before zeroing out _ofn - if ( _ofn.lpstrFile ) { - delete[] _ofn.lpstrFile; - _ofn.lpstrFile = NULL; + // Free any previously allocated lpstrFile before zeroing out _ofn_ptr + if ( _ofn_ptr->lpstrFile ) { + delete[] _ofn_ptr->lpstrFile; + _ofn_ptr->lpstrFile = NULL; } - if ( _ofn.lpstrInitialDir ) { - delete[] (TCHAR*) _ofn.lpstrInitialDir; //msvc6 compilation fix - _ofn.lpstrInitialDir = NULL; + if ( _ofn_ptr->lpstrInitialDir ) { + delete[] (TCHAR*) _ofn_ptr->lpstrInitialDir; //msvc6 compilation fix + _ofn_ptr->lpstrInitialDir = NULL; } - _ofn.lpstrFilter = NULL; // (deleted elsewhere) - int temp = _ofn.nFilterIndex; // keep the filter_value - memset((void*)&_ofn, 0, sizeof(_ofn)); - _ofn.lStructSize = sizeof(OPENFILENAMEW); - _ofn.nFilterIndex = temp; + _ofn_ptr->lpstrFilter = NULL; // (deleted elsewhere) + int temp = _ofn_ptr->nFilterIndex; // keep the filter_value + memset((void*)_ofn_ptr, 0, sizeof(OPENFILENAMEW)); + _ofn_ptr->lStructSize = sizeof(OPENFILENAMEW); + _ofn_ptr->nFilterIndex = temp; } // CLEAR MICROSOFT BINF (BROWSER INFO) CLASS void Fl_Native_File_Chooser::ClearBINF() { - if ( _binf.pidlRoot ) { - FreePIDL((ITEMIDLIST*)_binf.pidlRoot); - _binf.pidlRoot = NULL; + if ( _binf_ptr->pidlRoot ) { + FreePIDL((ITEMIDLIST*)_binf_ptr->pidlRoot); + _binf_ptr->pidlRoot = NULL; } - memset((void*)&_binf, 0, sizeof(_binf)); + memset((void*)_binf_ptr, 0, sizeof(BROWSEINFOW)); } // CONVERT WINDOWS BACKSLASHES TO UNIX FRONTSLASHES @@ -275,16 +291,16 @@ int Fl_Native_File_Chooser::showfile() { ClearOFN(); clear_pathnames(); size_t fsize = FNFC_MAX_PATH; - _ofn.Flags |= OFN_NOVALIDATE; // prevent disabling of front slashes - _ofn.Flags |= OFN_HIDEREADONLY; // hide goofy readonly flag + _ofn_ptr->Flags |= OFN_NOVALIDATE; // prevent disabling of front slashes + _ofn_ptr->Flags |= OFN_HIDEREADONLY; // hide goofy readonly flag // USE NEW BROWSER - _ofn.Flags |= OFN_EXPLORER; // use newer explorer windows - _ofn.Flags |= OFN_ENABLESIZING; // allow window to be resized (hey, why not?) + _ofn_ptr->Flags |= OFN_EXPLORER; // use newer explorer windows + _ofn_ptr->Flags |= OFN_ENABLESIZING; // allow window to be resized (hey, why not?) // XXX: The docs for OFN_NOCHANGEDIR says the flag is 'ineffective' on XP/2K/NT! // But let's set it anyway.. // - _ofn.Flags |= OFN_NOCHANGEDIR; // prevent dialog for messing up the cwd + _ofn_ptr->Flags |= OFN_NOCHANGEDIR; // prevent dialog for messing up the cwd switch ( _btype ) { case BROWSE_DIRECTORY: @@ -294,29 +310,29 @@ int Fl_Native_File_Chooser::showfile() { case BROWSE_FILE: break; case BROWSE_MULTI_FILE: - _ofn.Flags |= OFN_ALLOWMULTISELECT; + _ofn_ptr->Flags |= OFN_ALLOWMULTISELECT; break; case BROWSE_SAVE_FILE: if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { - _ofn.Flags |= OFN_OVERWRITEPROMPT; + _ofn_ptr->Flags |= OFN_OVERWRITEPROMPT; } break; } // SPACE FOR RETURNED FILENAME - _ofn.lpstrFile = new WCHAR[fsize]; - _ofn.nMaxFile = (DWORD) fsize-1; - _ofn.lpstrFile[0] = 0; - _ofn.lpstrFile[1] = 0; // dnull + _ofn_ptr->lpstrFile = new WCHAR[fsize]; + _ofn_ptr->nMaxFile = (DWORD) fsize-1; + _ofn_ptr->lpstrFile[0] = 0; + _ofn_ptr->lpstrFile[1] = 0; // dnull // PARENT WINDOW - _ofn.hwndOwner = GetForegroundWindow(); + _ofn_ptr->hwndOwner = GetForegroundWindow(); // DIALOG TITLE if (_title) { static WCHAR wtitle[200]; wcsncpy(wtitle, utf8towchar(_title), 200); wtitle[200-1] = 0; - _ofn.lpstrTitle = wtitle; + _ofn_ptr->lpstrTitle = wtitle; } else { - _ofn.lpstrTitle = NULL; + _ofn_ptr->lpstrTitle = NULL; } // FILTER if (_parsedfilt != NULL) { // to convert a null-containing char string into a widechar string @@ -325,34 +341,34 @@ int Fl_Native_File_Chooser::showfile() { while(*(p + strlen(p) + 1) != 0) p += strlen(p) + 1; p += strlen(p) + 2; MultiByteToWideChar(CP_UTF8, 0, _parsedfilt, (int) (p - _parsedfilt), wpattern, FNFC_MAX_PATH); - _ofn.lpstrFilter = wpattern; + _ofn_ptr->lpstrFilter = wpattern; } else { - _ofn.lpstrFilter = NULL; + _ofn_ptr->lpstrFilter = NULL; } // PRESET FILE // If set, supercedes _directory. See KB Q86920 for details // if ( _preset_file ) { size_t len = strlen(_preset_file); - if ( len >= _ofn.nMaxFile ) { + if ( len >= _ofn_ptr->nMaxFile ) { char msg[80]; sprintf(msg, "preset_file() filename is too long: %ld is >=%ld", (long)len, (long)fsize); return(-1); } - wcscpy(_ofn.lpstrFile, utf8towchar(_preset_file)); -// Unix2Win(_ofn.lpstrFile); - len = wcslen(_ofn.lpstrFile); - _ofn.lpstrFile[len+0] = 0; // multiselect needs dnull - _ofn.lpstrFile[len+1] = 0; + wcscpy(_ofn_ptr->lpstrFile, utf8towchar(_preset_file)); +// Unix2Win(_ofn_ptr->lpstrFile); + len = wcslen(_ofn_ptr->lpstrFile); + _ofn_ptr->lpstrFile[len+0] = 0; // multiselect needs dnull + _ofn_ptr->lpstrFile[len+1] = 0; } if ( _directory ) { // PRESET DIR // XXX: See KB Q86920 for doc bug: // http://support.microsoft.com/default.aspx?scid=kb;en-us;86920 // - _ofn.lpstrInitialDir = new WCHAR[FNFC_MAX_PATH]; - wcscpy((WCHAR *)_ofn.lpstrInitialDir, utf8towchar(_directory)); - // Unix2Win((char*)_ofn.lpstrInitialDir); + _ofn_ptr->lpstrInitialDir = new WCHAR[FNFC_MAX_PATH]; + wcscpy((WCHAR *)_ofn_ptr->lpstrInitialDir, utf8towchar(_directory)); + // Unix2Win((char*)_ofn_ptr->lpstrInitialDir); } // SAVE THE CURRENT DIRECTORY // XXX: Save the cwd because GetOpenFileName() is probably going to @@ -370,9 +386,9 @@ int Fl_Native_File_Chooser::showfile() { // OPEN THE DIALOG WINDOW int err; if ( _btype == BROWSE_SAVE_FILE ) { - err = GetSaveFileNameW(&_ofn); + err = GetSaveFileNameW(_ofn_ptr); } else { - err = GetOpenFileNameW(&_ofn); + err = GetOpenFileNameW(_ofn_ptr); } // GET EXTENDED ERROR int exterr = CommDlgExtendedError(); @@ -394,12 +410,12 @@ int Fl_Native_File_Chooser::showfile() { switch ( _btype ) { case BROWSE_FILE: case BROWSE_SAVE_FILE: - set_single_pathname(wchartoutf8(_ofn.lpstrFile)); + set_single_pathname(wchartoutf8(_ofn_ptr->lpstrFile)); // Win2Unix(_pathnames[_tpathnames-1]); break; case BROWSE_MULTI_FILE: { // EXTRACT MULTIPLE FILENAMES - const WCHAR *dirname = _ofn.lpstrFile; + const WCHAR *dirname = _ofn_ptr->lpstrFile; size_t dirlen = wcslen(dirname); if ( dirlen > 0 ) { // WALK STRING SEARCHING FOR 'DOUBLE-NULL' @@ -437,7 +453,7 @@ int Fl_Native_File_Chooser::showfile() { // Ref: Usenet: microsoft.public.vc.mfc, Dec 8 2000, 1:38p David Lowndes // Subject: How to specify to select an initial folder .." // -int CALLBACK Fl_Native_File_Chooser::Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) { +static int CALLBACK Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) { switch (msg) { case BFFM_INITIALIZED: if (data) ::SendMessageW(win, BFFM_SETSELECTIONW, TRUE, data); @@ -468,20 +484,20 @@ int Fl_Native_File_Chooser::showdir() { ClearBINF(); clear_pathnames(); // PARENT WINDOW - _binf.hwndOwner = GetForegroundWindow(); + _binf_ptr->hwndOwner = GetForegroundWindow(); // DIALOG TITLE - //_binf.lpszTitle = _title ? _title : NULL; + //_binf_ptr->lpszTitle = _title ? _title : NULL; if (_title) { static WCHAR wtitle[256]; wcsncpy(wtitle, utf8towchar(_title), 256); wtitle[255] = 0; - _binf.lpszTitle = wtitle; + _binf_ptr->lpszTitle = wtitle; } else { - _binf.lpszTitle = NULL; + _binf_ptr->lpszTitle = NULL; } // FLAGS - _binf.ulFlags = 0; // initialize + _binf_ptr->ulFlags = 0; // initialize // TBD: make sure matches to runtime system, if need be. //(what if _WIN32_IE doesn't match system? does the program not run?) @@ -499,22 +515,22 @@ int Fl_Native_File_Chooser::showdir() { // --- #if defined(BIF_NONEWFOLDERBUTTON) // Version 6.0 - if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_NONEWFOLDERBUTTON; - _binf.ulFlags |= BIF_USENEWUI | BIF_RETURNONLYFSDIRS; + if ( _btype == BROWSE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_NONEWFOLDERBUTTON; + _binf_ptr->ulFlags |= BIF_USENEWUI | BIF_RETURNONLYFSDIRS; #elif defined(BIF_USENEWUI) // Version 5.0 - if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_EDITBOX; - else if ( _btype == BROWSE_SAVE_DIRECTORY ) _binf.ulFlags |= BIF_USENEWUI; - _binf.ulFlags |= BIF_RETURNONLYFSDIRS; + if ( _btype == BROWSE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_EDITBOX; + else if ( _btype == BROWSE_SAVE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_USENEWUI; + _binf_ptr->ulFlags |= BIF_RETURNONLYFSDIRS; #elif defined(BIF_EDITBOX) // Version 4.71 - _binf.ulFlags |= BIF_RETURNONLYFSDIRS | BIF_EDITBOX; + _binf_ptr->ulFlags |= BIF_RETURNONLYFSDIRS | BIF_EDITBOX; #else // Version Old - _binf.ulFlags |= BIF_RETURNONLYFSDIRS; + _binf_ptr->ulFlags |= BIF_RETURNONLYFSDIRS; #endif // BUFFER //char displayname[FNFC_MAX_PATH]; WCHAR displayname[FNFC_MAX_PATH]; - _binf.pszDisplayName = displayname; + _binf_ptr->pszDisplayName = displayname; // PRESET DIR WCHAR presetname[FNFC_MAX_PATH]; @@ -522,12 +538,12 @@ int Fl_Native_File_Chooser::showdir() { // Unix2Win(presetname); wcsncpy(presetname, utf8towchar(_directory), FNFC_MAX_PATH); presetname[FNFC_MAX_PATH-1] = 0; - _binf.lParam = (LPARAM)presetname; + _binf_ptr->lParam = (LPARAM)presetname; } - else _binf.lParam = 0; - _binf.lpfn = Dir_CB; + else _binf_ptr->lParam = 0; + _binf_ptr->lpfn = Dir_CB; // OPEN BROWSER - LPITEMIDLIST pidl = SHBrowseForFolderW(&_binf); + LPITEMIDLIST pidl = SHBrowseForFolderW(_binf_ptr); // CANCEL? if ( pidl == NULL ) return(1); @@ -882,12 +898,12 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) { // SET 'CURRENTLY SELECTED FILTER' void Fl_Native_File_Chooser::filter_value(int i) { - _ofn.nFilterIndex = i + 1; + _ofn_ptr->nFilterIndex = i + 1; } // RETURN VALUE OF 'CURRENTLY SELECTED FILTER' int Fl_Native_File_Chooser::filter_value() const { - return(_ofn.nFilterIndex ? _ofn.nFilterIndex-1 : _nfilters+1); + return(_ofn_ptr->nFilterIndex ? _ofn_ptr->nFilterIndex-1 : _nfilters+1); } // PRESET FILENAME FOR 'SAVE AS' CHOOSER @@ -905,7 +921,7 @@ int Fl_Native_File_Chooser::filters() const { return(_nfilters); } -char *wchartoutf8(LPCWSTR in) +static char *wchartoutf8(LPCWSTR in) { static char *out = NULL; static int lchar = 0; @@ -919,7 +935,7 @@ char *wchartoutf8(LPCWSTR in) return out; } -LPCWSTR utf8towchar(const char *in) +static LPCWSTR utf8towchar(const char *in) { static WCHAR *wout = NULL; static int lwout = 0; |
