diff options
-rw-r--r-- | src/windows/classes/sun/awt/windows/WFileDialogPeer.java | 5 | ||||
-rw-r--r-- | src/windows/native/sun/windows/awt_FileDialog.cpp | 565 | ||||
-rw-r--r-- | src/windows/native/sun/windows/awt_ole.h | 17 |
3 files changed, 523 insertions, 64 deletions
diff --git a/src/windows/classes/sun/awt/windows/WFileDialogPeer.java b/src/windows/classes/sun/awt/windows/WFileDialogPeer.java index 4d80996cae..7e828bcbfb 100644 --- a/src/windows/classes/sun/awt/windows/WFileDialogPeer.java +++ b/src/windows/classes/sun/awt/windows/WFileDialogPeer.java @@ -36,6 +36,7 @@ import java.util.MissingResourceException; import java.util.Vector; import sun.awt.CausedFocusEvent; import sun.awt.AWTAccessor; +import sun.security.action.GetBooleanAction; final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { @@ -97,6 +98,10 @@ final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { _dispose(); } + private static boolean useCommonItemDialog() { + return AccessController.doPrivileged(new GetBooleanAction("sun.awt.windows.useCommonItemDialog")); + } + private native void _show(); private native void _hide(); diff --git a/src/windows/native/sun/windows/awt_FileDialog.cpp b/src/windows/native/sun/windows/awt_FileDialog.cpp index 0749cf1b70..1e5d78da69 100644 --- a/src/windows/native/sun/windows/awt_FileDialog.cpp +++ b/src/windows/native/sun/windows/awt_FileDialog.cpp @@ -27,11 +27,13 @@ #include "awt_FileDialog.h" #include "awt_Dialog.h" #include "awt_Toolkit.h" +#include "awt_ole.h" #include "ComCtl32Util.h" #include <commdlg.h> #include <cderr.h> #include <shlobj.h> - +#include <shlwapi.h> +#include <shobjidl.h> /************************************************************************ * AwtFileDialog fields @@ -52,11 +54,92 @@ jfieldID AwtFileDialog::dirID; jfieldID AwtFileDialog::fileID; jfieldID AwtFileDialog::filterID; +class CoTaskStringHolder { +public: + CoTaskStringHolder() : m_str(NULL) {} + + CoTaskStringHolder& operator=(CoTaskStringHolder& other) { + Clean(); + m_str = other.m_str; + other.m_str = NULL; + return *this; + } + + LPTSTR* operator&() { + return &m_str; + } + + operator bool() { + return m_str != NULL; + } + + operator LPTSTR() { + return m_str; + } + + ~CoTaskStringHolder() { + Clean(); + } +private: + LPTSTR m_str; + + void Clean() { + if (m_str) + ::CoTaskMemFree(m_str); + } +}; + +template <typename T> +class SmartHolderBase { +public: + SmartHolderBase() : m_pointer(NULL) {} + + SmartHolderBase& operator=(const SmartHolderBase&) = delete; + + void Attach(T* other) { + Clean(); + m_pointer = other; + } + + operator bool() { + return m_pointer != NULL; + } + + operator T*() { + return m_pointer; + } + + ~SmartHolderBase() { + Clean(); + } +protected: + T* m_pointer; + + virtual void Clean() { + if (m_pointer) + delete m_pointer; + } +}; + +template<typename T> +class SmartHolder : public SmartHolderBase<T> { +}; + +template <typename T> +class SmartHolder<T[]> : public SmartHolderBase<T> { + virtual void Clean() { + if (m_pointer) + delete [] m_pointer; + } +}; + /* Localized filter string */ #define MAX_FILTER_STRING 128 static TCHAR s_fileFilterString[MAX_FILTER_STRING]; /* Non-localized suffix of the filter string */ static const TCHAR s_additionalString[] = TEXT(" (*.*)\0*.*\0"); +static SmartHolder<COMDLG_FILTERSPEC> s_fileFilterSpec; +static UINT s_fileFilterCount; // Default limit of the output buffer. #define SINGLE_MODE_BUFFER_LIMIT MAX_PATH+1 @@ -65,8 +148,45 @@ static const TCHAR s_additionalString[] = TEXT(" (*.*)\0*.*\0"); // The name of the property holding the pointer to the OPENFILENAME structure. static LPCTSTR OpenFileNameProp = TEXT("AWT_OFN"); +_COM_SMARTPTR_TYPEDEF(IFileDialog, __uuidof(IFileDialog)); +_COM_SMARTPTR_TYPEDEF(IFileDialogEvents, __uuidof(IFileDialogEvents)); +_COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem)); +_COM_SMARTPTR_TYPEDEF(IFileOpenDialog, __uuidof(IFileOpenDialog)); +_COM_SMARTPTR_TYPEDEF(IShellItemArray, __uuidof(IShellItemArray)); +_COM_SMARTPTR_TYPEDEF(IOleWindowPtr, __uuidof(IOleWindowPtr)); + /***********************************************************************/ +COMDLG_FILTERSPEC *CreateFilterSpec(UINT *count) { + UINT filterCount = 0; + for (UINT index = 0; index < MAX_FILTER_STRING - 1; index++) { + if (s_fileFilterString[index] == _T('\0')) { + filterCount++; + if (s_fileFilterString[index + 1] == _T('\0')) + break; + } + } + filterCount /= 2; + COMDLG_FILTERSPEC *filterSpec = new COMDLG_FILTERSPEC[filterCount]; + UINT currentIndex = 0; + TCHAR *currentStart = s_fileFilterString; + for (UINT index = 0; index < MAX_FILTER_STRING - 1; index++) { + if (s_fileFilterString[index] == _T('\0')) { + if (currentIndex & 1) { + filterSpec[currentIndex / 2].pszSpec = currentStart; + } else { + filterSpec[currentIndex / 2].pszName = currentStart; + } + currentStart = s_fileFilterString + index + 1; + currentIndex++; + if (s_fileFilterString[index + 1] == _T('\0')) + break; + } + } + *count = filterCount; + return filterSpec; +} + void AwtFileDialog::Initialize(JNIEnv *env, jstring filterDescription) { @@ -86,6 +206,7 @@ AwtFileDialog::Initialize(JNIEnv *env, jstring filterDescription) } DASSERT(s + sizeof(s_additionalString) < s_fileFilterString + MAX_FILTER_STRING); memcpy(s, s_additionalString, sizeof(s_additionalString)); + s_fileFilterSpec.Attach(CreateFilterSpec(&s_fileFilterCount)); } LRESULT CALLBACK FileDialogWndProc(HWND hWnd, UINT message, @@ -229,12 +350,237 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) CATCH_BAD_ALLOC_RET(TRUE); } +struct FileDialogData { + IFileDialogPtr fileDialog; + SmartHolder<TCHAR[]> result; + UINT resultSize; + jobject peer; +}; + +HRESULT GetSelectedResults(FileDialogData *data) { + OLE_TRY + + IFileOpenDialogPtr fileOpenDialog; + UINT currentOffset = 0; + IShellItemArrayPtr psia; + DWORD itemsCount; + + OLE_HRT(data->fileDialog->QueryInterface(IID_PPV_ARGS(&fileOpenDialog))) + OLE_HRT(fileOpenDialog->GetSelectedItems(&psia)); + OLE_HRT(psia->GetCount(&itemsCount)); + + UINT maxBufferSize = (MAX_PATH + 1) * itemsCount + 1; + data->result.Attach(new TCHAR[maxBufferSize]); + data->resultSize = maxBufferSize; + LPTSTR resultBuffer = data->result; + for (DWORD i = 0; i < itemsCount; i++) { + IShellItemPtr psi; + OLE_HRT(psia->GetItemAt(i, &psi)); + if (i == 0 && itemsCount > 1) { + IShellItemPtr psiParent; + CoTaskStringHolder filePath; + OLE_HRT(psi->GetParent(&psiParent)); + OLE_HRT(psiParent->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + size_t filePathLength = _tcslen(filePath); + _tcsncpy(resultBuffer + currentOffset, filePath, filePathLength); + resultBuffer[currentOffset + filePathLength] = _T('\0'); + currentOffset += filePathLength + 1; + } + + CoTaskStringHolder filePath; + SIGDN displayForm = itemsCount > 1 ? SIGDN_PARENTRELATIVE : SIGDN_FILESYSPATH; + OLE_HRT(psi->GetDisplayName(displayForm, &filePath)); + size_t filePathLength = _tcslen(filePath); + _tcsncpy(resultBuffer + currentOffset, filePath, filePathLength); + resultBuffer[currentOffset + filePathLength] = _T('\0'); + currentOffset += filePathLength + 1; + } + resultBuffer[currentOffset] = _T('\0'); + resultBuffer[currentOffset + 1] = _T('\0'); + data->fileDialog->Close(S_OK); + + OLE_CATCH + OLE_RETURN_HR +} + +LRESULT CALLBACK +FileDialogSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) +{ + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + TRY; + + HWND parent = ::GetParent(hWnd); + + switch (uMsg) { + case WM_COMMAND: { + if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK) { + OLE_TRY + OLE_HRT(GetSelectedResults((FileDialogData*) dwRefData)); + OLE_CATCH + } + if (LOWORD(wParam) == IDCANCEL) { + jobject peer = (jobject) (::GetProp(hWnd, ModalDialogPeerProp)); + env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong) 0); + } + break; + } + case WM_SETICON: { + return 0; + } + case WM_DESTROY: { + HIMC hIMC = ::ImmGetContext(hWnd); + if (hIMC != NULL) { + ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0); + ::ImmReleaseContext(hWnd, hIMC); + } + + RemoveWindowSubclass(hWnd, &FileDialogSubclassProc, uIdSubclass); + + ::RemoveProp(parent, ModalDialogPeerProp); + break; + } + } + + return DefSubclassProc(hWnd, uMsg, wParam, lParam); + + CATCH_BAD_ALLOC_RET(TRUE); +} + +class CDialogEventHandler : public IFileDialogEvents +{ +public: + IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) + { + static const QITAB qit[] = { + QITABENT(CDialogEventHandler, IFileDialogEvents), + { 0 }, + }; + return QISearch(this, qit, riid, ppv); + } + + IFACEMETHODIMP_(ULONG) AddRef() + { + return InterlockedIncrement(&m_refCount); + } + + IFACEMETHODIMP_(ULONG) Release() + { + long retVal = InterlockedDecrement(&m_refCount); + if (!retVal) + delete this; + return retVal; + } + + IFACEMETHODIMP OnFolderChange(IFileDialog *fileDialog) { + if (!m_activated) { + InitDialog(fileDialog); + m_activated = true; + } + return S_OK; + }; + + IFACEMETHODIMP OnFileOk(IFileDialog *) { + if (!data->result) { + OLE_TRY + OLE_HRT(GetSelectedResults(data)); + OLE_CATCH + } + return S_OK; + }; + + IFACEMETHODIMP OnFolderChanging(IFileDialog *, IShellItem *) { return S_OK; }; + IFACEMETHODIMP OnHelp(IFileDialog *) { return S_OK; }; + IFACEMETHODIMP OnSelectionChange(IFileDialog *) { return S_OK; }; + IFACEMETHODIMP OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; }; + IFACEMETHODIMP OnTypeChange(IFileDialog *pfd) { return S_OK; }; + IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; }; + + CDialogEventHandler(FileDialogData *data) : data(data), m_refCount(1), m_activated(false) { }; +private: + ~CDialogEventHandler() { }; + FileDialogData *data; + bool m_activated; + long m_refCount; + + void InitDialog(IFileDialog *fileDialog) { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + TRY; + OLE_TRY + + IOleWindowPtr pWindow; + OLE_HR = fileDialog->QueryInterface(IID_PPV_ARGS(&pWindow)); + if (!SUCCEEDED(OLE_HR)) + return; + + HWND hdlg; + OLE_HRT(pWindow->GetWindow(&hdlg)); + + HWND parent = ::GetParent(hdlg); + jobject peer = data->peer; + env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong)parent); + ::SetProp(parent, ModalDialogPeerProp, reinterpret_cast<HANDLE>(peer)); + + // fix for 4508670 - disable CS_SAVEBITS + DWORD style = ::GetClassLong(hdlg, GCL_STYLE); + ::SetClassLong(hdlg, GCL_STYLE, style & ~CS_SAVEBITS); + + // set appropriate icon for parentless dialogs + jobject awtParent = env->GetObjectField(peer, AwtFileDialog::parentID); + if (awtParent == NULL) { + ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG, + (LPARAM)AwtToolkit::GetInstance().GetAwtIcon()); + } else { + AwtWindow *awtWindow = (AwtWindow *)JNI_GET_PDATA(awtParent); + ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG, + (LPARAM)(awtWindow->GetHIcon())); + ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_SMALL, + (LPARAM)(awtWindow->GetHIconSm())); + env->DeleteLocalRef(awtParent); + } + + SetWindowSubclass(hdlg, &FileDialogSubclassProc, 0, (DWORD_PTR) data); + + OLE_CATCH + CATCH_BAD_ALLOC; + } +}; + +HRESULT CDialogEventHandler_CreateInstance(FileDialogData *data, REFIID riid, void **ppv) +{ + OLE_TRY + IFileDialogEventsPtr dlg(new CDialogEventHandler(data), false); + OLE_HRT(dlg->QueryInterface(riid, ppv)); + OLE_CATCH + OLE_RETURN_HR +} + +HRESULT CreateShellItem(LPTSTR path, IShellItem *shellItem) { + size_t pathLength = _tcslen(path); + for (size_t index = 0; index < pathLength; index++) { + if (path[index] == _T('/')) + path[index] = _T('\\'); + } + + return ::SHCreateItemInKnownFolder(FOLDERID_ComputerFolder, 0, path, IID_PPV_ARGS(&shellItem)); +} + +CoTaskStringHolder GetShortName(LPTSTR path) { + CoTaskStringHolder shortName; + OLE_TRY + IShellItemPtr shellItem; + OLE_HRT(CreateShellItem(path, shellItem)); + OLE_HRT(shellItem->GetDisplayName(SIGDN_PARENTRELATIVE, &shortName)); + OLE_CATCH + return SUCCEEDED(OLE_HR) ? shortName : CoTaskStringHolder(); +} + void AwtFileDialog::Show(void *p) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject peer; - LPTSTR fileBuffer = NULL; LPTSTR currentDirectory = NULL; jint mode = 0; BOOL result = FALSE; @@ -248,13 +594,24 @@ AwtFileDialog::Show(void *p) AwtComponent* awtParent = NULL; jboolean multipleMode = JNI_FALSE; + OLE_DECL + OLEHolder _ole_; + IFileDialogPtr pfd; + IFileDialogEventsPtr pfde; + IShellItemPtr psiResult; + FileDialogData data; + DWORD dwCookie; + OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); peer = (jobject)p; + static BOOL useCommonItemDialog = JNU_CallStaticMethodByName(env, NULL, + "sun/awt/windows/WFileDialogPeer", "useCommonItemDialog", "()Z").z == JNI_TRUE; try { DASSERT(peer); + target = env->GetObjectField(peer, AwtObject::targetID); parent = env->GetObjectField(peer, AwtFileDialog::parentID); if (parent != NULL) { @@ -296,68 +653,132 @@ AwtFileDialog::Show(void *p) fileBuffer[0] = _T('\0'); } - ofn.lStructSize = sizeof(ofn); - ofn.lpstrFilter = s_fileFilterString; - ofn.nFilterIndex = 1; - /* - Fix for 6488834. - To disable Win32 native parent modality we have to set - hwndOwner field to either NULL or some hidden window. For - parentless dialogs we use NULL to show them in the taskbar, - and for all other dialogs AwtToolkit's HWND is used. - */ - if (awtParent != NULL) - { - ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd(); - } - else - { - ofn.hwndOwner = NULL; - } - ofn.lpstrFile = fileBuffer; - ofn.nMaxFile = bufferLimit; - ofn.lpstrTitle = titleBuffer; - ofn.lpstrInitialDir = directoryBuffer; - ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | - OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING; - fileFilter = env->GetObjectField(peer, - AwtFileDialog::fileFilterID); - if (!JNU_IsNull(env,fileFilter)) { - ofn.Flags |= OFN_ENABLEINCLUDENOTIFY; - } - ofn.lCustData = (LPARAM)peer; - ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc; + fileFilter = env->GetObjectField(peer, AwtFileDialog::fileFilterID); + + if (!useCommonItemDialog) { + ofn.lStructSize = sizeof(ofn); + ofn.lpstrFilter = s_fileFilterString; + ofn.nFilterIndex = 1; + /* + Fix for 6488834. + To disable Win32 native parent modality we have to set + hwndOwner field to either NULL or some hidden window. For + parentless dialogs we use NULL to show them in the taskbar, + and for all other dialogs AwtToolkit's HWND is used. + */ + if (awtParent != NULL) { + ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd(); + } else { + ofn.hwndOwner = NULL; + } + ofn.lpstrFile = fileBuffer; + ofn.nMaxFile = bufferLimit; + ofn.lpstrTitle = titleBuffer; + ofn.lpstrInitialDir = directoryBuffer; + ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | + OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING; + + if (!JNU_IsNull(env,fileFilter)) { + ofn.Flags |= OFN_ENABLEINCLUDENOTIFY; + } + ofn.lCustData = (LPARAM)peer; + ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc; - if (multipleMode == JNI_TRUE) { - ofn.Flags |= OFN_ALLOWMULTISELECT; - } + if (multipleMode == JNI_TRUE) { + ofn.Flags |= OFN_ALLOWMULTISELECT; + } - // Save current directory, so we can reset if it changes. - currentDirectory = new TCHAR[MAX_PATH+1]; + // Save current directory, so we can reset if it changes. + currentDirectory = new TCHAR[MAX_PATH+1]; - VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0); + VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0); + } mode = env->GetIntField(target, AwtFileDialog::modeID); AwtDialog::CheckInstallModalHook(); - // show the Win32 file dialog - if (mode == java_awt_FileDialog_LOAD) { - result = ::GetOpenFileName(&ofn); - } else { - result = ::GetSaveFileName(&ofn); + if (useCommonItemDialog) { + OLE_NEXT_TRY + GUID fileDialogMode = mode == java_awt_FileDialog_LOAD ? CLSID_FileOpenDialog : CLSID_FileSaveDialog; + OLE_HRT(pfd.CreateInstance(fileDialogMode)); + + data.fileDialog = pfd; + data.peer = peer; + OLE_HRT(CDialogEventHandler_CreateInstance(&data, IID_PPV_ARGS(&pfde))); + OLE_HRT(pfd->Advise(pfde, &dwCookie)); + + DWORD dwFlags; + OLE_HRT(pfd->GetOptions(&dwFlags)); + dwFlags |= FOS_FORCEFILESYSTEM; + if (multipleMode == JNI_TRUE) { + dwFlags |= FOS_ALLOWMULTISELECT; + } + OLE_HRT(pfd->SetOptions(dwFlags)); + + OLE_HRT(pfd->SetTitle(titleBuffer)); + + OLE_HRT(pfd->SetFileTypes(s_fileFilterCount, s_fileFilterSpec)); + OLE_HRT(pfd->SetFileTypeIndex(1)); + + IShellItemPtr directoryItem; + if (SUCCEEDED(CreateShellItem(directoryBuffer, directoryItem))) { + pfd->SetFolder(directoryItem); + } + CoTaskStringHolder shortName = GetShortName(fileBuffer); + if (shortName) { + OLE_HRT(pfd->SetFileName(shortName)); + } + OLE_CATCH } - // Fix for 4181310: FileDialog does not show up. - // If the dialog is not shown because of invalid file name - // replace the file name by empty string. - if (!result) { - dlgerr = ::CommDlgExtendedError(); - if (dlgerr == FNERR_INVALIDFILENAME) { - _tcscpy_s(fileBuffer, bufferLimit, TEXT("")); - if (mode == java_awt_FileDialog_LOAD) { - result = ::GetOpenFileName(&ofn); - } else { - result = ::GetSaveFileName(&ofn); + + if (useCommonItemDialog && SUCCEEDED(OLE_HR)) { + if (mode == java_awt_FileDialog_LOAD) { + result = SUCCEEDED(pfd->Show(NULL)) && data.result; + if (!result) { + OLE_NEXT_TRY + OLE_HRT(pfd->GetResult(&psiResult)); + CoTaskStringHolder filePath; + OLE_HRT(psiResult->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + size_t filePathLength = _tcslen(filePath); + data.result.Attach(new TCHAR[filePathLength + 1]); + _tcscpy_s(data.result, filePathLength + 1, filePath); + OLE_CATCH + result = SUCCEEDED(OLE_HR); + } + } else { + result = SUCCEEDED(pfd->Show(NULL)); + if (result) { + OLE_NEXT_TRY + OLE_HRT(pfd->GetResult(&psiResult)); + CoTaskStringHolder filePath; + OLE_HRT(psiResult->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + size_t filePathLength = _tcslen(filePath); + data.result.Attach(new TCHAR[filePathLength + 1]); + _tcscpy_s(data.result, filePathLength + 1, filePath); + OLE_CATCH + result = SUCCEEDED(OLE_HR); + } + } + } else { + // show the Win32 file dialog + if (mode == java_awt_FileDialog_LOAD) { + result = ::GetOpenFileName(&ofn); + } else { + result = ::GetSaveFileName(&ofn); + } + // Fix for 4181310: FileDialog does not show up. + // If the dialog is not shown because of invalid file name + // replace the file name by empty string. + if (!result) { + dlgerr = ::CommDlgExtendedError(); + if (dlgerr == FNERR_INVALIDFILENAME) { + _tcscpy_s(fileBuffer, bufferLimit, TEXT("")); + if (mode == java_awt_FileDialog_LOAD) { + result = ::GetOpenFileName(&ofn); + } else { + result = ::GetSaveFileName(&ofn); + } } } } @@ -368,19 +789,31 @@ AwtFileDialog::Show(void *p) AwtDialog::ModalActivateNextWindow(NULL, target, peer); - VERIFY(::SetCurrentDirectory(currentDirectory)); + if (useCommonItemDialog) { + VERIFY(::SetCurrentDirectory(currentDirectory)); + } // Report result to peer. if (result) { - jint length = multipleMode - ? (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile) - : (jint)_tcslen(ofn.lpstrFile); + jint length; + if (useCommonItemDialog) { + length = (jint) GetBufferLength(data.result, data.resultSize); + } else { + length = multipleMode + ? (jint) GetBufferLength(ofn.lpstrFile, ofn.nMaxFile) + : (jint) _tcslen(ofn.lpstrFile); + } + jcharArray jnames = env->NewCharArray(length); if (jnames == NULL) { throw std::bad_alloc(); } - env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile); + if (useCommonItemDialog) { + env->SetCharArrayRegion(jnames, 0, length, (jchar *) (LPTSTR) data.result); + } else { + env->SetCharArrayRegion(jnames, 0, length, (jchar *) ofn.lpstrFile); + } env->CallVoidMethod(peer, AwtFileDialog::handleSelectedMID, jnames); env->DeleteLocalRef(jnames); } else { @@ -389,6 +822,12 @@ AwtFileDialog::Show(void *p) DASSERT(!safe_ExceptionOccurred(env)); } catch (...) { + if (useCommonItemDialog) { + if (pfd) { + pfd->Unadvise(dwCookie); + } + } + env->DeleteLocalRef(target); env->DeleteLocalRef(parent); env->DeleteLocalRef(title); @@ -403,6 +842,12 @@ AwtFileDialog::Show(void *p) throw; } + if (useCommonItemDialog) { + if (pfd) { + pfd->Unadvise(dwCookie); + } + } + env->DeleteLocalRef(target); env->DeleteLocalRef(parent); env->DeleteLocalRef(title); diff --git a/src/windows/native/sun/windows/awt_ole.h b/src/windows/native/sun/windows/awt_ole.h index db54c64fce..cbca45bed8 100644 --- a/src/windows/native/sun/windows/awt_ole.h +++ b/src/windows/native/sun/windows/awt_ole.h @@ -183,11 +183,20 @@ struct CLogEntryPoint0 { struct OLEHolder { OLEHolder() - : m_hr(::OleInitialize(NULL)) - {} + : m_hr(::OleInitialize(NULL)) + { + if (SUCCEEDED(m_hr)) { + STRACE(_T("{OLE")); + } + } - ~OLEHolder(){} - operator bool() const { return S_OK==SUCCEEDED(m_hr); } + ~OLEHolder(){ + if (SUCCEEDED(m_hr)) { + ::OleUninitialize(); + STRACE(_T("}OLE")); + } + } + operator bool() const { return TRUE==SUCCEEDED(m_hr); } HRESULT m_hr; }; |