* You are viewing Posts Tagged ‘Vista’

Vista glass in SWT application - continuation

In my previous post about Vista glass I’ve introduced very simple way to enable DWM glass in SWT. Since that time, I did a lot of experiments how one can improve that experience, and I’ve found solutions to almost all issues with DWM/Glass/Vista in SWT. This post became much bigger than I’ve anticipated, therefore it’s divided into “text after more…” :-)

First, let’s see some screenshot of application in work:

Vista native look for SWT - glass

Continue Reading »

Using Vista’s UAC in SWT

UAC allows users to launch specific applications with elevated privileges, e.g. Changing some system settings, or launching an application that needs to have access to files not in your profile (e.g. C:/Program Files/ directory). To accomplish that we need to do two things.

First is to launch application with elevated privileges, it’s quite easy to do, we need to use OS.ShellExecuteEx and SHELLEXECUTEINFO in which there’s a field called lpVerb. This field needs to have runas string. Here’s the example code (it’s modified version of launch(String) method from Program class.

/**
 * Launches the operating system executable associated with the file or
 * URL (http:// or https://) with elevated privileges.  If the file is an
 * executable then the executable is launched.  Note that a
 * <code>Display</code> must already exist to guarantee that this method
 * returns an appropriate result. This method waits on OS.ShellExecuteEx
 * until user close UAC warning. This works only with Windows Vista and
 * higher. On lower versions of Windows there will be no visible difference.
 *
 * @param fileName the file or program name or URL (http:// or https://)
 * @return <code>true</code> if the file is launched, otherwise
 *         <code>false</code>
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT when fileName is null</li>
 * </ul>
 */

public static boolean launchElevated (String fileName) {
    if (fileName == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
   
    /* Use the character encoding for the default locale */
    int /*long*/ hHeap = OS.GetProcessHeap ();

    TCHAR buffer = new TCHAR (0, fileName, true);
    int byteCount = buffer.length () * TCHAR.sizeof;
    int /*long*/ lpFile = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
    OS.MoveMemory (lpFile, buffer, byteCount);

    TCHAR verbBuffer = new TCHAR (0, "runas", true);
    int verbByteCount = verbBuffer.length () * TCHAR.sizeof;
    int /*long*/ lpVerb = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, verbByteCount);
    OS.MoveMemory (lpVerb, verbBuffer, verbByteCount);

    SHELLEXECUTEINFO info = new SHELLEXECUTEINFO ();
    info.cbSize = SHELLEXECUTEINFO.sizeof;
    info.lpFile = lpFile;
    info.lpVerb = lpVerb;
    info.nShow = OS.SW_SHOW;
    boolean result = OS.ShellExecuteEx (info);

    if (lpFile != 0) OS.HeapFree (hHeap, 0, lpFile);
    if (lpVerb != 0) OS.HeapFree (hHeap, 0, lpVerb);

    return result;
}

Second thing is visual approach. All Vista’s applications that tries to elevate privileges have shield icon as button image. We don’t need to provide this icon by ourselves, we just simply send a message BCM_SETSHIELD to button widget with lParam 1 (true) or 0 (false).

OS.SendMessageW(button.handle, BCM_SETSHIELD, 0, 1);

Since BCM_SETSHIELD is not available in OS class (I wonder why?) we need to declare it:

public static final int BCM_SETSHIELD = OS.BCM_FIRST + 0xc;

Here’s obligatory screenshot of BCM_SETSHIELD message in use. In this screenshot there’s an example of retrieving icon from my previous post.

Launch notepad.exe elevated

Hope it will help, it did me :-)

Vista glass in SWT application

Desktop Java applications by definition are/should be portable to multiple operating systems. Writing with SWT refines set of available operating systems, but it also gives you some opportunities to make application aware of operating system and blends it visually. With Windows Vista’s new Desktop Window Manager we are able to create visually more stunning and eye catching applications. Look at the Chrome screenshot below, notice the decoration of window, it’s transparent and blurred:

Chrome

You can actually do similar thing in SWT (under Windows Vista only) and here’s a small example screenshot:

Vista glass in SWT

So, what do we need to do to accomplish that? It’s quite easy, as a matter of fact, but requires nasty access to internal OS class which makes it SWT windows only!

/**
 * Applies vista glass frame - works only on Vista with Areo.
 */

private void applyVistaGlassFrame()
{
    int glassHeight = 100;

    MARGINS margins = new MARGINS();
    margins.cyTopHeight = glassHeight;

    OS.DwmExtendFrameIntoClientArea(shell.handle, margins);
}

Example above will add 100 pixels of glass area at top of the dialog.

But that’s not enough, we need also to cover glass area with black color, for this we can add Composite widget that will have background color set to SWT.COLOR_BLACK.

Unfortunately this functionality is not 100% covered by SWT. Additional checks against Vista needs to be done. We also need to know if Desktop Window Manager’s Compositions are enabled. Unfortunately we don’t have access to DwmIsCompositionEnabled (it’s not declared in OS class).

While writing this article, I’ve came up with idea how this can be used in Eclipse - about dialog. Recent changes to about dialog are great, but what if go a little bit further and make top of the dialog similar to this, but under Windows Vista with composition instead of white background use glass?