Sunday, October 21, 2007

Windows XP Visual Style Controls with wxRuby

wxRuby uses the native Microsoft Windows common controls when displaying widgets on a Windows OS. You may have noticed, however, that the form controls do not have the Windows XP look and feel. They have the flat and 2-dimensional look of earlier Windows versions...



...rather than having the rounded corners and 3-dimensional look of Windows XP...



Note, among other things, the "glowing button" effect when the mouse hovered over the "Get Films Data" button.

This is because Windows XP comes with both version 5 and version 6 of the Common Controls, but unless specifically instructed to use version 6, it will default to using version 5 controls.

So, how do you instruct Windows to use the version 6 controls for your wxRuby GUI application? By including a simple manifest XML file with your application.

Copy the following text into a new text file. Save the file as "rubyw.exe.manifest" in your ruby/bin folder, the same folder that contains rubyw.exe. You might also save a copy to the same folder as "ruby.exe.manifest".


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.8.6.0" processorArchitecture="X86"
name="Microsoft.Winweb.Ruby" type="win32"/>
<description>Ruby interpreter</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

When the ruby.exe or rubyw.exe interpreter is run, Windows will look for a manifest file matching the program name in the same folder. When it finds our manifest file, it will then use the version 6 controls, as defined in the <dependency> section of the manifest.

We place the file in our c:\ruby\bin directory because that is where ruby.exe and rubyw.exe are located. We name the file ruby.exe.manifest or rubyw.exe.manifest to match the name of the interpreter being run.

If you are compiling your application with RubyScript2Exe, copy the manifest file into the folder with your script, then embed the manifest file in your compiled executable using the RUBYSCRIPT2EXE.bin statement:

RUBYSCRIPT2EXE.bin = ["rubyw.exe.manifest"]

When your compiled executable is run, your manifest file will be extracted to the same temporary "/bin" folder as the rubw.exe (or ruby.exe) interpreter.

Questions? Comments? Suggestions? Post a comment here or send me email.

Thanks for stopping by!

Digg my article

14 comments:

Anonymous said...

Hi,

Good tips.

Also, What do you think about best gui for ruby apps., especially for windows?

Thanks.

Kev said...
This comment has been removed by the author.
Anonymous said...

Your site has been very helpful. Will you have a howto on building & exporting xml with formbuilder tied to wxRuby?

Marcos Ricardo said...

Hi,

A really good tip...

To hilight Murat's question, which is the best Ruby GUI ?

I'm a newbie in Ruby, made some tests with TK and is time to go on next steps.

Kind Regards

Marcos Ricardo

Anonymous said...

Regarding XRC and integrating wxRuby with formbuilders, you might find this useful: Using XRCise. It describes a tool that scaffolds Ruby GUI classes from formbuilders like DialogBlocks.

alex

David Mullet said...

It's impossible to declare any one GUI library as The Best, but I generally use wxRuby. It is stable, free of charge, and provides a native look and feel.

I will be happy to delve into details of using wxRuby. I usually code my own wxRuby forms, rather than use XRC files from wxForms Builder. But I can walk through examples of each very soon.

David

Anonymous said...

Nice, thanks!

Anonymous said...

Very helpful! I installed the manifest files and they work when I invoke a ruby script as follows:

C:\> mywxrubyapp.rb args

but not when I invoke it thus:

C:\> ruby mywxrubyapp.rb args

I'd like to know of a way to make the latter invocation find the manifest file. (Because that's how my scripts are being invoked by an app over which I have no control.)

Thanks much!

David Mullet said...

@Anonymous:

If I understand your problem correctly...

Place a copy of ruby.exe.manifest in the ruby/bin directory from which your ruby.exe file is located.

The manifest file must match the interpreter name and must be located in the same folder with the interpreter being launched.

I hope that helps.

David

Anonymous said...

Awesome! Thanks!

Anonymous said...

i have a doubt..
i use ruby 1.8.6 27 rc2 and i put ruby.exe.manifest and rubyw.exe.manifest on ruby.exe dir but....
my windows not get the windwos styles O.O...

someone help-me please!
my email is luiz_valentim@live.com

Anonymous said...

If this solution doesn't work for you, you can try embedding manifest into rubyw.exe, using mt.exe from Windows SDK:
mt.exe -manifest rubyw.exe.manifest -outputresource:rubyw.exe;#1

Anonymous said...

It works for me using ruby.exe.manifest (instead of rubyw) but my application is having trouble refreshing correctly. There's a lot of black spots and notebook tabs that aren't refreshed at all. Any idea on what's going on?

Anonymous said...

Is it possible to do the same thing using OCRA instead of rubyscript2exe?