|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-7 by Raw Material Software ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the
- GNU General Public License, as published by the Free Software Foundation;
- either version 2 of the License, or (at your option) any later version.
-
- JUCE is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with JUCE; if not, visit www.gnu.org/licenses or write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- ------------------------------------------------------------------------------
-
- If you'd like to release a closed-source product which uses JUCE, commercial
- licenses are also available: visit www.rawmaterialsoftware.com/juce for
- more information.
-
- ==============================================================================
- */
-
- #ifdef _MSC_VER
- #pragma warning (disable: 4514)
- #pragma warning (push)
- #endif
-
- #include "win32_headers.h"
- #include <shlobj.h>
-
- #include "../../../src/juce_core/basics/juce_StandardHeader.h"
-
- BEGIN_JUCE_NAMESPACE
-
- #include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h"
- #include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
- #include "../../../src/juce_core/basics/juce_SystemStats.h"
-
- #ifdef _MSC_VER
- #pragma warning (pop)
- #endif
-
- //==============================================================================
- static const void* defaultDirPath = 0;
- static String returnedString; // need this to get non-existent pathnames from the directory chooser
- static Component* currentExtraFileWin = 0;
-
- static bool areThereAnyAlwaysOnTopWindows()
- {
- for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
- {
- Component* c = Desktop::getInstance().getComponent (i);
-
- if (c != 0 && c->isAlwaysOnTop() && c->isShowing())
- return true;
- }
-
- return false;
- }
-
- static int CALLBACK browseCallbackProc (HWND hWnd, UINT msg, LPARAM lParam, LPARAM /*lpData*/)
- {
- if (msg == BFFM_INITIALIZED)
- {
- SendMessage (hWnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) defaultDirPath);
- }
- else if (msg == BFFM_VALIDATEFAILEDW)
- {
- returnedString = (LPCWSTR) lParam;
- }
- else if (msg == BFFM_VALIDATEFAILEDA)
- {
- returnedString = (const char*) lParam;
- }
-
- return 0;
- }
-
- void juce_setWindowStyleBit (HWND h, int styleType, int feature, bool bitIsSet);
-
- static UINT_PTR CALLBACK openCallback (HWND hdlg, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam)
- {
- if (currentExtraFileWin != 0)
- {
- if (uiMsg == WM_INITDIALOG)
- {
- HWND dialogH = GetParent (hdlg);
- jassert (dialogH != 0);
- if (dialogH == 0)
- dialogH = hdlg;
-
- RECT r, cr;
- GetWindowRect (dialogH, &r);
- GetClientRect (dialogH, &cr);
-
- SetWindowPos (dialogH, 0,
- r.left, r.top,
- currentExtraFileWin->getWidth() + jmax (150, r.right - r.left),
- jmax (150, r.bottom - r.top),
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
-
- currentExtraFileWin->setBounds (cr.right, cr.top, currentExtraFileWin->getWidth(), cr.bottom - cr.top);
- currentExtraFileWin->getChildComponent(0)->setBounds (0, 0, currentExtraFileWin->getWidth(), currentExtraFileWin->getHeight());
-
- SetParent ((HWND) currentExtraFileWin->getWindowHandle(), (HWND) dialogH);
- juce_setWindowStyleBit ((HWND)currentExtraFileWin->getWindowHandle(), GWL_STYLE, WS_CHILD, (dialogH != 0));
- juce_setWindowStyleBit ((HWND)currentExtraFileWin->getWindowHandle(), GWL_STYLE, WS_POPUP, (dialogH == 0));
- }
- else if (uiMsg == WM_NOTIFY)
- {
- LPOFNOTIFY ofn = (LPOFNOTIFY) lParam;
-
- if (ofn->hdr.code == CDN_SELCHANGE)
- {
- FilePreviewComponent* comp = (FilePreviewComponent*) currentExtraFileWin->getChildComponent(0);
-
- if (comp != 0)
- {
- TCHAR path [MAX_PATH * 2];
- path[0] = 0;
- CommDlg_OpenSave_GetFilePath (GetParent (hdlg), (LPARAM) &path, MAX_PATH);
-
- const String fn ((const WCHAR*) path);
-
- comp->selectedFileChanged (File (fn));
- }
- }
- }
- }
-
- return 0;
- }
-
- class FPComponentHolder : public Component
- {
- public:
- FPComponentHolder()
- {
- setVisible (true);
- setOpaque (true);
- }
-
- ~FPComponentHolder()
- {
- }
-
- void paint (Graphics& g)
- {
- g.fillAll (Colours::lightgrey);
- }
-
- private:
- FPComponentHolder (const FPComponentHolder&);
- const FPComponentHolder& operator= (const FPComponentHolder&);
- };
-
- //==============================================================================
- void FileChooser::showPlatformDialog (OwnedArray<File>& results,
- const String& title,
- const File& currentFileOrDirectory,
- const String& filter,
- bool selectsDirectory,
- bool isSaveDialogue,
- bool warnAboutOverwritingExistingFiles,
- bool selectMultipleFiles,
- FilePreviewComponent* extraInfoComponent)
- {
- const int numCharsAvailable = 32768;
- MemoryBlock filenameSpace ((numCharsAvailable + 1) * sizeof (WCHAR), true);
- WCHAR* const fname = (WCHAR*) filenameSpace.getData();
- int fnameIdx = 0;
-
- JUCE_TRY
- {
- // use a modal window as the parent for this dialog box
- // to block input from other app windows
- const Rectangle mainMon (Desktop::getInstance().getMainMonitorArea());
-
- Component w (String::empty);
- w.setBounds (mainMon.getX() + mainMon.getWidth() / 4,
- mainMon.getY() + mainMon.getHeight() / 4,
- 0, 0);
- w.setOpaque (true);
- w.setAlwaysOnTop (areThereAnyAlwaysOnTopWindows());
- w.addToDesktop (0);
-
- if (extraInfoComponent == 0)
- w.enterModalState();
-
- String initialDir;
-
- if (currentFileOrDirectory.isDirectory())
- {
- initialDir = currentFileOrDirectory.getFullPathName();
- }
- else
- {
- currentFileOrDirectory.getFileName().copyToBuffer (fname, numCharsAvailable);
-
- initialDir = currentFileOrDirectory.getParentDirectory().getFullPathName();
- }
-
- if (currentExtraFileWin->isValidComponent())
- {
- jassertfalse
- return;
- }
-
- if (selectsDirectory)
- {
- LPITEMIDLIST list = 0;
- filenameSpace.fillWith (0);
-
- {
- BROWSEINFO bi;
- zerostruct (bi);
-
- bi.hwndOwner = (HWND) w.getWindowHandle();
- bi.pszDisplayName = fname;
- bi.lpszTitle = title;
- bi.lpfn = browseCallbackProc;
- #ifdef BIF_USENEWUI
- bi.ulFlags = BIF_USENEWUI | BIF_VALIDATE;
- #else
- bi.ulFlags = 0x50;
- #endif
- defaultDirPath = (const WCHAR*) initialDir;
-
- list = SHBrowseForFolder (&bi);
-
- if (! SHGetPathFromIDListW (list, fname))
- {
- fname[0] = 0;
- returnedString = String::empty;
- }
- }
-
- LPMALLOC al;
- if (list != 0 && SUCCEEDED (SHGetMalloc (&al)))
- al->Free (list);
-
- defaultDirPath = 0;
-
- if (returnedString.isNotEmpty())
- {
- const String stringFName (fname);
-
- results.add (new File (File (stringFName).getSiblingFile (returnedString)));
- returnedString = String::empty;
-
- return;
- }
- }
- else
- {
- DWORD flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
-
- if (warnAboutOverwritingExistingFiles)
- flags |= OFN_OVERWRITEPROMPT;
-
- if (selectMultipleFiles)
- flags |= OFN_ALLOWMULTISELECT;
-
- if (extraInfoComponent != 0)
- {
- flags |= OFN_ENABLEHOOK;
-
- currentExtraFileWin = new FPComponentHolder();
- currentExtraFileWin->addAndMakeVisible (extraInfoComponent);
- currentExtraFileWin->setSize (jlimit (20, 800, extraInfoComponent->getWidth()),
- extraInfoComponent->getHeight());
- currentExtraFileWin->addToDesktop (0);
-
- currentExtraFileWin->enterModalState();
- }
-
- {
- WCHAR filters [1024];
- zeromem (filters, sizeof (filters));
- filter.copyToBuffer (filters, 1024);
- filter.copyToBuffer (filters + filter.length() + 1,
- 1022 - filter.length());
-
- OPENFILENAMEW of;
- zerostruct (of);
-
- #ifdef OPENFILENAME_SIZE_VERSION_400W
- of.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
- #else
- of.lStructSize = sizeof (of);
- #endif
- of.hwndOwner = (HWND) w.getWindowHandle();
- of.lpstrFilter = filters;
- of.nFilterIndex = 1;
- of.lpstrFile = fname;
- of.nMaxFile = numCharsAvailable;
- of.lpstrInitialDir = initialDir;
- of.lpstrTitle = title;
- of.Flags = flags;
-
- if (extraInfoComponent != 0)
- of.lpfnHook = &openCallback;
-
- if (isSaveDialogue)
- {
- if (! GetSaveFileName (&of))
- fname[0] = 0;
- else
- fnameIdx = of.nFileOffset;
- }
- else
- {
- if (! GetOpenFileName (&of))
- fname[0] = 0;
- else
- fnameIdx = of.nFileOffset;
- }
- }
- }
- }
- #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (...)
- {
- fname[0] = 0;
- }
- #endif
-
- deleteAndZero (currentExtraFileWin);
-
- const WCHAR* const files = fname;
-
- if (selectMultipleFiles && fnameIdx > 0 && files [fnameIdx - 1] == 0)
- {
- const WCHAR* filename = files + fnameIdx;
-
- while (*filename != 0)
- {
- const String filepath (String (files) + T("\\") + String (filename));
- results.add (new File (filepath));
- filename += CharacterFunctions::length (filename) + 1;
- }
- }
- else if (files[0] != 0)
- {
- results.add (new File (files));
- }
- }
-
- END_JUCE_NAMESPACE
|