comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/program/Program.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children 950d84783eac
comparison
equal deleted inserted replaced
-1:000000000000 0:6dd524f61e62
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D Programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module org.eclipse.swt.program.Program;
14
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.graphics.Image;
17 import org.eclipse.swt.graphics.ImageData;
18 import org.eclipse.swt.internal.win32.OS;
19
20 import java.lang.all;
21 static import tango.text.convert.Utf;
22
23 /**
24 * Instances of this class represent programs and
25 * their associated file extensions in the operating
26 * system.
27 *
28 * @see <a href="http://www.eclipse.org/swt/snippets/#program">Program snippets</a>
29 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
30 */
31 public final class Program {
32 String name;
33 String command;
34 String iconName;
35 String extension;
36 static const String[] ARGUMENTS = ["%1"[], "%l", "%L"]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
37
38 /**
39 * Prevents uninitialized instances from being created outside the package.
40 */
41 this () {
42 }
43
44 static String assocQueryString (int assocStr, TCHAR[] key, bool expand) {
45 TCHAR[] pszOut = NewTCHARs(0, 1024);
46 uint[1] pcchOut;
47 pcchOut[0] = pszOut.length;
48 int flags = OS.ASSOCF_NOTRUNCATE | OS.ASSOCF_INIT_IGNOREUNKNOWN;
49 int result = OS.AssocQueryString (flags, assocStr, key.ptr, null, pszOut.ptr, pcchOut.ptr);
50 if (result is OS.E_POINTER) {
51 pszOut = NewTCHARs(0, pcchOut [0]);
52 result = OS.AssocQueryString (flags, assocStr, key.ptr, null, pszOut.ptr, pcchOut.ptr);
53 }
54 if (result is 0) {
55 if (!OS.IsWinCE && expand) {
56 int length_ = OS.ExpandEnvironmentStrings (pszOut.ptr, null, 0);
57 if (length_ !is 0) {
58 TCHAR[] lpDst = NewTCHARs (0, length_);
59 OS.ExpandEnvironmentStrings (pszOut.ptr, lpDst.ptr, length_);
60 return tango.text.convert.Utf.toString( lpDst[ 0 .. Math.max (0, length_ - 1) ] );
61 } else {
62 return "";
63 }
64 } else {
65 return tango.text.convert.Utf.toString( pszOut[ 0 .. Math.max (0, pcchOut [0] - 1)]);
66 }
67 }
68 return null;
69 }
70
71 /**
72 * Finds the program that is associated with an extension.
73 * The extension may or may not begin with a '.'. Note that
74 * a <code>Display</code> must already exist to guarantee that
75 * this method returns an appropriate result.
76 *
77 * @param extension the program extension
78 * @return the program or <code>null</code>
79 *
80 */
81 public static Program findProgram (String extension) {
82 // SWT extension: allow null string
83 //if (extension is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
84 if (extension.length is 0) return null;
85 if (extension.charAt (0) !is '.') extension = "." ~ extension; //$NON-NLS-1$
86 /* Use the character encoding for the default locale */
87 TCHAR[] key = StrToTCHARs (0, extension, true);
88 Program program = null;
89 if (OS.IsWinCE) {
90 void*[1] phkResult;
91 if (OS.RegOpenKeyEx ( cast(void*)OS.HKEY_CLASSES_ROOT, key.ptr, 0, OS.KEY_READ, phkResult.ptr) !is 0) {
92 return null;
93 }
94 uint [1] lpcbData;
95 int result = OS.RegQueryValueEx (phkResult [0], null, null, null, null, lpcbData.ptr);
96 if (result is 0) {
97 TCHAR[] lpData = NewTCHARs (0, lpcbData [0] / TCHAR.sizeof);
98 result = OS.RegQueryValueEx (phkResult [0], null, null, null, cast(ubyte*)lpData.ptr, lpcbData.ptr);
99 if (result is 0) program = getProgram ( TCHARzToStr( lpData.ptr ), extension);
100 }
101 OS.RegCloseKey (phkResult [0]);
102 } else {
103 String command = assocQueryString (OS.ASSOCSTR_COMMAND, key, true);
104 if (command !is null) {
105 String name = null;
106 if (name is null) name = assocQueryString (OS.ASSOCSTR_FRIENDLYDOCNAME, key, false);
107 if (name is null) name = assocQueryString (OS.ASSOCSTR_FRIENDLYAPPNAME, key, false);
108 if (name is null) name = "";
109 String iconName = assocQueryString (OS.ASSOCSTR_DEFAULTICON, key, true);
110 if (iconName is null) iconName = "";
111 program = new Program ();
112 program.name = name;
113 program.command = command;
114 program.iconName = iconName;
115 program.extension = extension;
116 }
117 }
118 return program;
119 }
120
121 /**
122 * Answer all program extensions in the operating system. Note
123 * that a <code>Display</code> must already exist to guarantee
124 * that this method returns an appropriate result.
125 *
126 * @return an array of extensions
127 */
128 public static String [] getExtensions () {
129 String [] extensions = new String [1024];
130 /* Use the character encoding for the default locale */
131 TCHAR[] lpName = NewTCHARs (0, 1024);
132 uint [1] lpcName; lpcName[0] = lpName.length;
133 FILETIME ft;
134 int dwIndex = 0, count = 0;
135 while (OS.RegEnumKeyEx ( cast(void*)OS.HKEY_CLASSES_ROOT, dwIndex, lpName.ptr, lpcName.ptr, null, null, null, &ft) !is OS.ERROR_NO_MORE_ITEMS) {
136 String extension = TCHARsToStr( lpName[0 .. lpcName[0] ]);
137 lpcName [0] = lpName.length;
138 if (extension.length > 0 && extension.charAt (0) is '.') {
139 if (count is extensions.length) {
140 String[] newExtensions = new String[]( extensions.length + 1024 );
141 System.arraycopy (extensions, 0, newExtensions, 0, extensions.length);
142 extensions = newExtensions;
143 }
144 extensions [count++] = extension;
145 }
146 dwIndex++;
147 }
148 if (count !is extensions.length) {
149 String[] newExtension = new String[]( count );
150 System.arraycopy (extensions, 0, newExtension, 0, count);
151 extensions = newExtension;
152 }
153 return extensions;
154 }
155
156 static String getKeyValue (String string, bool expand) {
157 /* Use the character encoding for the default locale */
158 TCHAR[] key = StrToTCHARs (0, string, true);
159 void* [1] phkResult;
160 if (OS.RegOpenKeyEx (cast(void*)OS.HKEY_CLASSES_ROOT, key.ptr, 0, OS.KEY_READ, phkResult.ptr) !is 0) {
161 return null;
162 }
163 String result = null;
164 uint [1] lpcbData;
165 if (OS.RegQueryValueEx (phkResult [0], null, null, null, null, lpcbData.ptr) is 0) {
166 result = "";
167 int length_ = lpcbData [0] / TCHAR.sizeof;
168 if (length_ !is 0) {
169 /* Use the character encoding for the default locale */
170 TCHAR[] lpData = NewTCHARs (0, length_);
171 if (OS.RegQueryValueEx (phkResult [0], null, null, null, cast(ubyte*)lpData.ptr, lpcbData.ptr) is 0) {
172 if (!OS.IsWinCE && expand) {
173 length_ = OS.ExpandEnvironmentStrings (lpData.ptr, null, 0);
174 if (length_ !is 0) {
175 TCHAR[] lpDst = NewTCHARs (0, length_);
176 OS.ExpandEnvironmentStrings (lpData.ptr, lpDst.ptr, length_);
177 result = tango.text.convert.Utf.toString ( lpDst[0 .. Math.max (0, length_ - 1) ] );
178 }
179 } else {
180 length_ = Math.max (0, lpData.length - 1);
181 result = tango.text.convert.Utf.toString ( lpData[0 .. length_]);
182 }
183 }
184 }
185 }
186 if (phkResult [0] !is null) OS.RegCloseKey (phkResult [0]);
187 return result;
188 }
189
190 static Program getProgram (String key, String extension) {
191
192 /* Name */
193 String name = getKeyValue (key, false);
194 if (name is null || name.length is 0) {
195 name = key;
196 }
197
198 /* Command */
199 String DEFAULT_COMMAND = "\\shell"; //$NON-NLS-1$
200 String defaultCommand = getKeyValue (key ~ DEFAULT_COMMAND, true);
201 if (defaultCommand is null || defaultCommand.length is 0) defaultCommand = "open"; //$NON-NLS-1$
202 String COMMAND = "\\shell\\" ~ defaultCommand ~ "\\command"; //$NON-NLS-1$
203 String command = getKeyValue (key ~ COMMAND, true);
204 if (command is null || command.length is 0) return null;
205
206 /* Icon */
207 String DEFAULT_ICON = "\\DefaultIcon"; //$NON-NLS-1$
208 String iconName = getKeyValue (key ~ DEFAULT_ICON, true);
209 if (iconName is null) iconName = ""; //$NON-NLS-1$
210
211 /* Program */
212 Program program = new Program ();
213 program.name = name;
214 program.command = command;
215 program.iconName = iconName;
216 program.extension = extension;
217 return program;
218 }
219
220 /**
221 * Answers all available programs in the operating system. Note
222 * that a <code>Display</code> must already exist to guarantee
223 * that this method returns an appropriate result.
224 *
225 * @return an array of programs
226 */
227 public static Program [] getPrograms () {
228 Program [] programs = new Program [1024];
229 /* Use the character encoding for the default locale */
230 TCHAR[] lpName = NewTCHARs (0, 1024);
231 uint [1] lpcName; lpcName[0] = lpName.length;
232 FILETIME ft;
233 int dwIndex = 0, count = 0;
234 while (OS.RegEnumKeyEx (cast(void*)OS.HKEY_CLASSES_ROOT, dwIndex, lpName.ptr, lpcName.ptr, null, null, null, &ft) !is OS.ERROR_NO_MORE_ITEMS) {
235 String path = tango.text.convert.Utf.toString ( lpName[0 .. lpcName [0]]);
236 lpcName [0] = lpName.length ;
237 Program program = getProgram (path, null);
238 if (program !is null) {
239 if (count is programs.length) {
240 Program [] newPrograms = new Program [programs.length + 1024];
241 System.arraycopy (programs, 0, newPrograms, 0, programs.length);
242 programs = newPrograms;
243 }
244 programs [count++] = program;
245 }
246 dwIndex++;
247 }
248 if (count !is programs.length) {
249 Program [] newPrograms = new Program [count];
250 System.arraycopy (programs, 0, newPrograms, 0, count);
251 programs = newPrograms;
252 }
253 return programs;
254 }
255
256 /**
257 * Launches the operating system executable associated with the file or
258 * URL (http:// or https://). If the file is an executable then the
259 * executable is launched. Note that a <code>Display</code> must already
260 * exist to guarantee that this method returns an appropriate result.
261 *
262 * @param fileName the file or program name or URL (http:// or https://)
263 * @return <code>true</code> if the file is launched, otherwise <code>false</code>
264 *
265 * @exception IllegalArgumentException <ul>
266 * <li>ERROR_NULL_ARGUMENT when fileName is null</li>
267 * </ul>
268 */
269 public static bool launch (String fileName) {
270 if (fileName is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
271
272 /* Use the character encoding for the default locale */
273 auto hHeap = OS.GetProcessHeap ();
274 TCHAR[] buffer = StrToTCHARs (0, fileName, true);
275 int byteCount = buffer.length * TCHAR.sizeof;
276 auto lpFile = cast(wchar*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
277 OS.MoveMemory (lpFile, buffer.ptr, byteCount);
278 SHELLEXECUTEINFO info;
279 info.cbSize = SHELLEXECUTEINFO.sizeof;
280 info.lpFile = lpFile;
281 info.nShow = OS.SW_SHOW;
282 bool result = cast(bool) OS.ShellExecuteEx (&info);
283 if (lpFile !is null) OS.HeapFree (hHeap, 0, lpFile);
284 return result;
285 }
286
287 /**
288 * Executes the program with the file as the single argument
289 * in the operating system. It is the responsibility of the
290 * programmer to ensure that the file contains valid data for
291 * this program.
292 *
293 * @param fileName the file or program name
294 * @return <code>true</code> if the file is launched, otherwise <code>false</code>
295 *
296 * @exception IllegalArgumentException <ul>
297 * <li>ERROR_NULL_ARGUMENT when fileName is null</li>
298 * </ul>
299 */
300 public bool execute (String fileName) {
301 if (fileName is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
302 int index = 0;
303 bool append = true;
304 String prefix = command, suffix = ""; //$NON-NLS-1$
305 while (index < ARGUMENTS.length) {
306 int i = command.indexOf (ARGUMENTS [index]);
307 if (i !is -1) {
308 append = false;
309 prefix = command.substring (0, i);
310 suffix = command.substring (i + ARGUMENTS [index].length , command.length );
311 break;
312 }
313 index++;
314 }
315 if (append) fileName = " \"" ~ fileName ~ "\"";
316 String commandLine = prefix ~ fileName ~ suffix;
317 auto hHeap = OS.GetProcessHeap ();
318 /* Use the character encoding for the default locale */
319 TCHAR[] buffer = StrToTCHARs (0, commandLine, true);
320 int byteCount = buffer.length * TCHAR.sizeof;
321 auto lpCommandLine = cast(TCHAR*)OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
322 OS.MoveMemory (lpCommandLine, buffer.ptr, byteCount);
323 STARTUPINFO lpStartupInfo;
324 lpStartupInfo.cb = STARTUPINFO.sizeof;
325 PROCESS_INFORMATION lpProcessInformation;
326 bool success = cast(bool) OS.CreateProcess (null, lpCommandLine, null, null, false, 0, null, null, &lpStartupInfo, &lpProcessInformation);
327 if (lpCommandLine !is null) OS.HeapFree (hHeap, 0, lpCommandLine);
328 if (lpProcessInformation.hProcess !is null) OS.CloseHandle (lpProcessInformation.hProcess);
329 if (lpProcessInformation.hThread !is null) OS.CloseHandle (lpProcessInformation.hThread);
330 return success;
331 }
332
333 /**
334 * Returns the receiver's image data. This is the icon
335 * that is associated with the receiver in the operating
336 * system.
337 *
338 * @return the image data for the program, may be null
339 */
340 public ImageData getImageData () {
341 if (extension !is null) {
342 SHFILEINFOW shfi;
343 int flags = OS.SHGFI_ICON | OS.SHGFI_SMALLICON | OS.SHGFI_USEFILEATTRIBUTES;
344 TCHAR[] pszPath = StrToTCHARs (0, extension, true);
345 OS.SHGetFileInfo (pszPath.ptr, OS.FILE_ATTRIBUTE_NORMAL, &shfi, SHFILEINFO.sizeof, flags);
346 if (shfi.hIcon !is null) {
347 Image image = Image.win32_new (null, SWT.ICON, shfi.hIcon);
348 ImageData imageData = image.getImageData ();
349 image.dispose ();
350 return imageData;
351 }
352 }
353 int nIconIndex = 0;
354 String fileName = iconName;
355 int index = iconName.indexOf (',');
356 if (index !is -1) {
357 fileName = iconName.substring (0, index);
358 String iconIndex = iconName.substring (index + 1, iconName.length ).trim ();
359 try {
360 nIconIndex = Integer.parseInt (iconIndex);
361 } catch (NumberFormatException e) {}
362 }
363 int length = fileName.length;
364 if (length !is 0 && fileName.charAt (0) is '\"') {
365 if (fileName.charAt (length - 1) is '\"') {
366 fileName = fileName.substring (1, length - 1);
367 }
368 }
369 /* Use the character encoding for the default locale */
370 TCHAR[] lpszFile = StrToTCHARs (0, fileName, true);
371 HICON [1] phiconSmall, phiconLarge;
372 OS.ExtractIconEx (lpszFile.ptr, nIconIndex, phiconLarge.ptr, phiconSmall.ptr, 1);
373 if (phiconSmall [0] is null) return null;
374 Image image = Image.win32_new (null, SWT.ICON, phiconSmall [0]);
375 ImageData imageData = image.getImageData ();
376 image.dispose ();
377 return imageData;
378 }
379
380 /**
381 * Returns the receiver's name. This is as short and
382 * descriptive a name as possible for the program. If
383 * the program has no descriptive name, this string may
384 * be the executable name, path or empty.
385 *
386 * @return the name of the program
387 */
388 public String getName () {
389 return name;
390 }
391
392 /**
393 * Compares the argument to the receiver, and returns true
394 * if they represent the <em>same</em> object using a class
395 * specific comparison.
396 *
397 * @param other the object to compare with this object
398 * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
399 *
400 * @see #hashCode()
401 */
402 public override int opEquals(Object other) {
403 if (this is other) return true;
404 if ( auto program = cast(Program)other ) {
405 return name.equals(program.name) && command.equals(program.command)
406 && iconName.equals(program.iconName);
407 }
408 return false;
409 }
410
411 /**
412 * Returns an integer hash code for the receiver. Any two
413 * objects that return <code>true</code> when passed to
414 * <code>equals</code> must return the same value for this
415 * method.
416 *
417 * @return the receiver's hash
418 *
419 * @see #equals(Object)
420 */
421 public override hash_t toHash() {
422 return .toHash(name) ^ .toHash(command) ^ .toHash(iconName);
423 }
424
425 /**
426 * Returns a string containing a concise, human-readable
427 * description of the receiver.
428 *
429 * @return a string representation of the program
430 */
431 public String toString () {
432 return "Program {" ~ name ~ "}"; //$NON-NLS-1$ //$NON-NLS-2$
433 }
434
435 }