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 /bundles/org.eclipse.swt/Eclipse SWT
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>
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/DirectoryDialog.java85
1 files changed, 84 insertions, 1 deletions
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