Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Karpisek2017-09-08 11:17:20 +0000
committerNiraj Modi2017-10-06 10:56:16 +0000
commit37e6b935a9b182ccc361b7f96a951e9a1c600671 (patch)
tree0a05a23ae5483962d38f3c65873f7c420f5919e2
parent7359cb3bf2545f1dd97950f54bcc25b8badd16e7 (diff)
downloadeclipse.platform.swt-37e6b935a9b182ccc361b7f96a951e9a1c600671.tar.gz
eclipse.platform.swt-37e6b935a9b182ccc361b7f96a951e9a1c600671.tar.xz
eclipse.platform.swt-37e6b935a9b182ccc361b7f96a951e9a1c600671.zip
Bug 443250 - [win32] Support modern native directory dialog
- directory dialog on windows vista and newer will be from now using more modern 'Common Item Dialog' -if this vista-style dialog is not available (old windows version) then basic win32 directory dialog will be used Change-Id: Ib0f4f02e5909908442c23e0b618b82faf3b7cac8 Signed-off-by: Martin Karpisek <martin.karpisek@gmail.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c32
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/FileDialogVtbl.java44
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/ShellItemVtbl.java25
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java8
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/DirectoryDialog.java85
8 files changed, 198 insertions, 5 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c
index fab88806c3..3586326c98 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13119,6 +13119,36 @@ fail:
}
#endif
+#ifndef NO_SHCreateItemFromParsingName
+JNIEXPORT jint JNICALL OS_NATIVE(SHCreateItemFromParsingName)
+ (JNIEnv *env, jclass that, jcharArray arg0, jintLong arg1, jbyteArray arg2, jintLongArray arg3)
+{
+ jchar *lparg0=NULL;
+ jbyte *lparg2=NULL;
+ jintLong *lparg3=NULL;
+ jint rc = 0;
+ OS_NATIVE_ENTER(env, that, SHCreateItemFromParsingName_FUNC);
+ if (arg0) if ((lparg0 = (*env)->GetCharArrayElements(env, arg0, NULL)) == NULL) goto fail;
+ if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ if (arg3) if ((lparg3 = (*env)->GetIntLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
+/*
+ rc = (jint)SHCreateItemFromParsingName(lparg0, arg1, lparg2, lparg3);
+*/
+ {
+ OS_LOAD_FUNCTION(fp, SHCreateItemFromParsingName)
+ if (fp) {
+ rc = (jint)((jint (CALLING_CONVENTION*)(jchar *, jintLong, jbyte *, jintLong *))fp)(lparg0, arg1, lparg2, lparg3);
+ }
+ }
+fail:
+ if (arg3 && lparg3) (*env)->ReleaseIntLongArrayElements(env, arg3, lparg3, 0);
+ if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+ if (arg0 && lparg0) (*env)->ReleaseCharArrayElements(env, arg0, lparg0, 0);
+ OS_NATIVE_EXIT(env, that, SHCreateItemFromParsingName_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_SHCreateItemFromRelativeName
JNIEXPORT jint JNICALL OS_NATIVE(SHCreateItemFromRelativeName)
(JNIEnv *env, jclass that, jintLong arg0, jcharArray arg1, jintLong arg2, jbyteArray arg3, jintLongArray arg4)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h
index 7c254b6b1c..529bb52995 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -93,6 +93,7 @@
#define SetWindowTheme_LIB "uxtheme.dll"
#define SHCreateItemFromRelativeName_LIB "shell32.dll"
#define SHCreateItemInKnownFolder_LIB "shell32.dll"
+#define SHCreateItemFromParsingName_LIB "shell32.dll"
#define TransparentBlt_LIB "msimg32.dll"
#define UnregisterTouchWindow_LIB "user32.dll"
#define UpdateLayeredWindow_LIB "user32.dll"
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c
index 64fd8ea1fc..139cc47da5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -1337,6 +1337,7 @@ char * OS_nativeFunctionNames[] = {
"SHACTIVATEINFO_1sizeof",
"SHBrowseForFolderA",
"SHBrowseForFolderW",
+ "SHCreateItemFromParsingName",
"SHCreateItemFromRelativeName",
"SHCreateItemInKnownFolder",
"SHCreateMenuBar",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h
index 514f9124c8..ed962d9a73 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -1347,6 +1347,7 @@ typedef enum {
SHACTIVATEINFO_1sizeof_FUNC,
SHBrowseForFolderA_FUNC,
SHBrowseForFolderW_FUNC,
+ SHCreateItemFromParsingName_FUNC,
SHCreateItemFromRelativeName_FUNC,
SHCreateItemInKnownFolder_FUNC,
SHCreateMenuBar_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/FileDialogVtbl.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/FileDialogVtbl.java
new file mode 100644
index 0000000000..ce28a225d8
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/FileDialogVtbl.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Martin Karpisek and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Karpisek <martin.karpisek@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.com.win32;
+
+/**
+ * Function number constants for IFileDialog COM interface
+ */
+public class FileDialogVtbl{
+ public static final int QUERY_INTERFACE = 0;
+ public static final int ADD_REF = 1;
+ public static final int RELEASE = 2;
+ public static final int SHOW = 3;
+ public static final int SET_FILE_TYPES = 4;
+ public static final int SET_FILE_TYPE_INDEX = 5;
+ public static final int GET_FILE_TYPE_INDEX = 6;
+ public static final int ADVISE = 7;
+ public static final int UNADVISE = 8;
+ public static final int SET_OPTIONS = 9;
+ public static final int GET_OPTIONS = 10;
+ public static final int SET_DEFAULT_FOLDER = 11;
+ public static final int SET_FOLDER = 12;
+ public static final int GET_FOLDER = 13;
+ public static final int GET_CURRENT_SELECTION = 14;
+ public static final int SET_FILE_NAME = 15;
+ public static final int GET_FILE_NAME = 16;
+ public static final int SET_TITLE = 17;
+ public static final int SET_OK_BUTTON_LABEL = 18;
+ public static final int SET_FILE_NAME_LABEL = 19;
+ public static final int GET_RESULT = 20;
+ public static final int ADD_PLACE = 21;
+ public static final int SET_DEFAULT_EXTENSION = 22;
+ public static final int CLOSE = 23;
+ public static final int SET_CLIENT_GUID = 24;
+ public static final int CLEAR_CLIENT_DATA = 25;
+ public static final int SET_FILTER = 26;
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/ShellItemVtbl.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/ShellItemVtbl.java
new file mode 100644
index 0000000000..14a0d0afe7
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/com/win32/ShellItemVtbl.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Martin Karpisek and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Karpisek <martin.karpisek@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal.com.win32;
+
+/**
+ * Function number constants for IShellItem COM interface
+ */
+public class ShellItemVtbl{
+ public static final int QUERY_INTERFACE = 0;
+ public static final int ADD_REF = 1;
+ public static final int RELEASE = 2;
+ public static final int BIND_TO_HANDLER = 3;
+ public static final int GET_PARENT = 4;
+ public static final int GET_DISPLAY_NAME = 5;
+ public static final int GET_ATTRIBUTES = 6;
+ public static final int COMPARE = 7;
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
index 4d5b9bddcd..0ce818eb8e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Martin Karpisek <martin.karpisek@gmail.com> - Bug 443250
*******************************************************************************/
package org.eclipse.swt.internal.win32;
@@ -25,6 +26,7 @@ public class OS extends C {
public static final boolean IsWin95;
public static final boolean IsWinNT;
public static final boolean IsWinCE;
+ public static final boolean IsWinVista;
public static final boolean IsPPC;
public static final boolean IsHPC;
public static final boolean IsSP;
@@ -90,6 +92,7 @@ public class OS extends C {
WIN32_MINOR = info.dwMinorVersion;
WIN32_VERSION = VERSION (WIN32_MAJOR, WIN32_MINOR);
IsUnicode = !IsWin32s && !IsWin95;
+ IsWinVista = OS.WIN32_VERSION >= OS.VERSION (6, 0);
/* Load the manifest to force the XP Theme */
if (System.getProperty (NO_MANIFEST) == null) {
@@ -703,6 +706,9 @@ public class OS extends C {
public static final int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
public static final int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
public static final int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
+ public static final int FOS_NOCHANGEDIR = 0x8;
+ public static final int FOS_PICKFOLDERS = 0x20;
+ public static final int FOS_FORCEFILESYSTEM = 0x40;
public static final int FR_PRIVATE = 0x10;
public static final int FSHIFT = 0x4;
public static final int FVIRTKEY = 0x1;
@@ -6863,6 +6869,8 @@ public static final native boolean SHGetPathFromIDListA (long /*int*/ pidl, byte
public static final native int SHCreateItemInKnownFolder (byte [] kfid, int dwKFFlags, char [] pszItem, byte [] riid, long /*int*/ [] ppv);
/** @method flags=dynamic */
public static final native int SHCreateItemFromRelativeName (long /*int*/ psiParent, char [] pszName, long /*int*/ pbc, byte [] riid, long /*int*/ [] ppv);
+/** @method flags=dynamic */
+public static final native int SHCreateItemFromParsingName (char [] pszName, long /*int*/ pbc, byte [] riid, long /*int*/ [] ppv);
/**
* @param bVk cast=(BYTE)
* @param hwnd cast=(HWND)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/DirectoryDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/DirectoryDialog.java
index 6c7b65fc82..aa29191360 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/DirectoryDialog.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/DirectoryDialog.java
@@ -7,12 +7,14 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Martin Karpisek <martin.karpisek@gmail.com> - Bug 443250
*******************************************************************************/
package org.eclipse.swt.widgets;
import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.com.win32.*;
import org.eclipse.swt.internal.win32.*;
/**
@@ -34,6 +36,19 @@ import org.eclipse.swt.internal.win32.*;
* @noextend This class is not intended to be subclassed by clients.
*/
public class DirectoryDialog extends Dialog {
+ static final byte[] CLSID_FileOpenDialog = new byte[16];
+ static final byte[] IID_IFileOpenDialog = new byte[16];
+ static final byte[] IID_IShellItem = new byte[16];
+ static {
+ if (OS.IsWinVista) {
+ //Common Item/File Dialog
+ OS.IIDFromString("{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}\0".toCharArray(), CLSID_FileOpenDialog); //$NON-NLS-1$
+ OS.IIDFromString("{d57c7288-d4ad-4768-be02-9d969532d960}\0".toCharArray(), IID_IFileOpenDialog); //$NON-NLS-1$
+ OS.IIDFromString("{43826d1e-e718-42ee-bc55-a1e261c37bfe}\0".toCharArray(), IID_IShellItem); //$NON-NLS-1$
+ }
+ }
+
+
String message = "", filterPath = ""; //$NON-NLS-1$//$NON-NLS-2$
String directoryPath;
@@ -145,7 +160,14 @@ public String getMessage () {
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
* </ul>
*/
-public String open () {
+public String open() {
+ if (OS.IsWinVista) {
+ return openCommonItemDialog();
+ }
+ return openCommonFileDialog();
+}
+
+private String openCommonFileDialog () {
if (OS.IsWinCE) error (SWT.ERROR_NOT_IMPLEMENTED);
long /*int*/ hHeap = OS.GetProcessHeap ();
@@ -274,6 +296,67 @@ public String open () {
return directoryPath;
}
+private String openCommonItemDialog() {
+ this.directoryPath = null;
+
+ long /*int*/ [] ppv = new long /*int*/ [1];
+ if (OS.CoCreateInstance(CLSID_FileOpenDialog, 0, OS.CLSCTX_INPROC_SERVER, IID_IFileOpenDialog, ppv) == OS.S_OK) {
+ long /*int*/ fileDialog = ppv[0];
+
+ int[] options = new int[1];
+ if ((OS.VtblCall(FileDialogVtbl.GET_OPTIONS, fileDialog, options)) == OS.S_OK) {
+ options[0] |= OS.FOS_PICKFOLDERS | OS.FOS_FORCEFILESYSTEM | OS.FOS_NOCHANGEDIR;
+
+ OS.VtblCall(FileDialogVtbl.SET_OPTIONS, fileDialog, options[0]);
+ }
+
+ if (title == null) title = "";
+ if (title.length() > 0) {
+ char[] buffer = new char[title.length() + 1];
+ title.getChars(0, title.length(), buffer, 0);
+ OS.VtblCall(FileDialogVtbl.SET_TITLE, fileDialog, buffer);
+ }
+
+ if (filterPath != null && filterPath.length() > 0) {
+ String path = filterPath.replace('/', '\\');
+ char[] buffer = new char[path.length() + 1];
+ path.getChars(0, path.length(), buffer, 0);
+ if (OS.SHCreateItemFromParsingName(buffer, 0, IID_IShellItem, ppv) == OS.S_OK) {
+ long /*int*/ psi = ppv[0];
+ /*
+ * SetDefaultDirectory does not work if the dialog has
+ * persisted recently used folder. The fix is to clear the
+ * persisted data.
+ */
+ OS.VtblCall(FileDialogVtbl.CLEAR_CLIENT_DATA, fileDialog);
+ OS.VtblCall(FileDialogVtbl.SET_DEFAULT_FOLDER, fileDialog, psi);
+ OS.VtblCall(FileDialogVtbl.RELEASE, psi);
+ }
+ }
+
+ long /*int*/ hwndOwner = parent.handle;
+ if (OS.VtblCall(FileDialogVtbl.SHOW, fileDialog, hwndOwner) == OS.S_OK) {
+ if (OS.VtblCall(FileDialogVtbl.GET_RESULT, fileDialog, ppv) == OS.S_OK) {
+ long /*int*/ psi = ppv[0];
+ if (OS.VtblCall(ShellItemVtbl.GET_DISPLAY_NAME, psi, OS.SIGDN_FILESYSPATH, ppv) == OS.S_OK) {
+ long /*int*/ wstr = ppv[0];
+ int length = OS.wcslen(wstr);
+ char[] buffer = new char[length];
+ OS.MoveMemory(buffer, wstr, length * 2);
+ OS.CoTaskMemFree(wstr);
+
+ directoryPath = new String(buffer);
+ }
+ OS.VtblCall(FileDialogVtbl.RELEASE, psi);
+ }
+ }
+
+ OS.VtblCall(FileDialogVtbl.RELEASE, fileDialog);
+ }
+
+ return directoryPath;
+}
+
/**
* Sets the path that the dialog will use to filter
* the directories it shows to the argument, which may

Back to the top