Lloyd.NET

Programing experiments

Discovering D and Visual Studio (continued…)

Thanks for the feedback from the previous article, I know now that:

  • DFL should work with the BCL in D2, but it just doesn’t at the moment, due to some repository snafu…
  • Visual D had building problem due to… tool chain issues! This page about Visual D known issues explain what’s going on and how to fix it!

Hence by modifying C:\D\dmd2\windows\bin\sc.ini

To be like (changes in maroon)

[Version]
version=7.51 Build 020

[Environment]
LIB="%@P%\..\lib";\dm\lib;%DMD_LIB%
DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import"
LINKCMD=%@P%\link.exe

 

I was able to make do with a much more satisfactory config:

image

 

Community support

Maybe I should mention that D, despite being a marginal language (as in: little know) has a surprisingly pleasantly vibrant community support.

Also the Digitalmars page on D is full of interesting link (particularly Tools => More Tools) but I’d like to grab the attention on 2 communities:

  • D Source forums
  • Digitalmars newsgroups (news server: news.digitalmars.com). Can be accessed with Windows Live Mail or Thunderbird for example. Just create a new newsgroup account

    image

 

Initial sample reloaded

I though it might be a good idea to have DGui in my projects (i.e. as source code / solution’s project) and link my test project against it. This way I can look, play with and learn from some D code written by a more knowledgeable D programmer than I!

It turns out there are key difference with what would happen with trying to do that with C#. Perhaps it behave like it will with Visual C++, I couldn’t tell, not having using it enough…

At any rate here is what happened

  • I created a new Visual D static library
  • Created the directory hierarchy of the DGui source (it’s important for D, just like Java, it reflects package organisation)
  • Added the existing file from DGui
  • And build, successfully first try! (Nicely enough DGui has no other dependency that Phobos / BCL)

image

Now, when looking at the file system, there was no D file in my project’s directory! All these files in the solution explorer linked to the one and only original files.

Hence, I shouldn’t change the import file path of my test project. For the record they remained pointing to
C:\D\dgui

image

 

 

Updating the dependencies

But I still needed to point to my build version of DGui, hence change the library path of my test project. And I also need to set my test project to depends on my (local) dgui project.

Right click on project => Project dependencies => select dgui

 

image image

Set the library search path to the project build location: C:\Dev\DTest\dgui\Debug.

image

F5, it builds and run!

Now for the surprisingly good part, in my test app, if I F12 on one of the class I use, VS actually goes there!

But no method list (yet?).

Just for fun I added a “std.stdio.writeln("hello");” in initialization looking method (I still knows nothing of D, hey!) and .. it printed!

 

Getting rid of the console

I’m trying a GUI sample, yet I have a nagging MS-Dos console appearing every time I run. To get rid of it I should pass a special flags to the linker (in Additional options) so it will mark the executable as being a windows application (i.e. no console attached!)

-L/SUBSYSTEM:windows:4

image

 

 

A brief look at the source code

So far I haven’t coded anything yet! Just wanted to feel comfortable with the development experience… But will post about source code next time!

Anyhow, below is the source code of my test app (straight from events.d in DGui’s samples):

module events;

import dgui.all;

class MainForm: Form
{
    private Button _btnOk;
    
    public this()
    {
        this.text = "DGui Events";
        this.size = Size(300, 250);
        this.startPosition = FormStartPosition.CENTER_SCREEN; // Set Form Position
        
        this._btnOk = new Button();
        this._btnOk.text = "Click Me!";
        this._btnOk.dock = DockStyle.FILL; // Fill the whole form area
        this._btnOk.parent = this;
        this._btnOk.click.attach(&this.onBtnOkClick); //Attach the click event with the selected procedure
    }
    
    private void onBtnOkClick(Control sender, EventArgs e)
    {
        // Display a message box
        MsgBox.show("OnClick", "Button.onClick()");
    }
}

int main(string[] args)
{
    return Application.run(new MainForm()); // Start the application
}     

The exciting things I can see from a quick look at the source is that D supports properties, events and DGui looks quite similar to WinForm!

Except for the lack (at the moment) of designer Sad smile 

Ho well, I just plan to make simple wizards anyway…


Tags:
Categories: D | Source Code
Permalink | Comments (0) | Post RSSRSS comment feed

D for .NET programmer

Recently it appeared to me that, with D, I could finally write solve a long standing problem, that is write a good advanced installer.

What appealed to me where the following features:

  • Statically linked. Produce an exe with no dependency! (Save for win32 that is, fair enough!)
  • Elegant syntax on par with C# and Java
  • Compile time executable code, making it easy to include “resource” files (zip and include file to install inside the installer)
  • Finally with a nice IDE and GUI library (almost as good as a slim WinForm)
  • Can directly call into C (I plan to call into the MsiXXX function) at no cost!

So I started to try to use it.

Ho boy, just having 1 program, using 1 custom library to compile was quite an odyssey! Hopefully this blog entry could save future language explorer!

 

1. Installation

First thing first, you’ll need to download and installer the D SDK (the compiler, linker, runtime library, etc… The whole shebang!) That can be found there:

http://www.digitalmars.com/d/download.html

Unzip the latest version of DMD somewhere, you are done! Now that was easy.

And if you heard about DM / DMC, don’t worry about it. It was for D1, just ignore it.

 

2. IDE

Well, arguably you can go with the command line. The compiler flags and linker flags are simple enough. Yet I’m too spoiled by VS, I need my IDE!
In fact, on the D2 page, following the Editor link on the left (in Tools), I found 3 which were attractive: D-IDE, Entice and Visual D.

D-IDE is cool because it’s C# but that’s about it (it’s still basic and buggy, sadly).

Entice is a GUI designer. It was exciting at first, but I deleted it in the end because it is used for DFL or DWT which both requires to overwrite the base runtime library (aka Phobos). Which I don’t quite feel like doing yet.

And, finally, Visual D, a plugin for Visual Studio. Create D projects in Visual Studio, yoohoo! Download and install it now.

image

 

3. My first program

You can create a new module with Visual D (new D project), press F5, and voila, hello D world!

 

Now I wanted to create a GUI Hello world!

I had a look at DFL and DWT. DFL looks lighter / smaller and good enough for my need. Yet they both required Tango, which seem to be a popular D BCL (aka Phobos) replacement. Well that ended it for me. Tango might be popular but I’m not going to replace my BCL when I can’t even compile a(n advanced) program yet (you’ll see my library trouble next).

Finally I found DGui. Looking like WinForm. Depending just on Phobos (the BCL).

I downloaded, unzipped, copied a sample (in the sample directory) into my “hello.d” file and tried to compile.

Now the problems started…

First error would be:

Error    1    Error: module all is in file 'dgui\all.d' which cannot be read    C:\Dev\DTest\DTest1\hello.d    3

 

This is due to the import statement at the top:

import dgui.all;

 

3.a. file and hierarchy structure

D has 2 ‘code unit’ if I may call it that way. Module and package. It’s a bit like classes and packages in Java. A module is everything in one file. I’m not yet sure if the module should be named after the file it’s in, but that, at least, seems to be the convention.

The package is a folder of source code.

When I wrote “import dgui.all” the compiler looked for the module “all” (i.e. the file “all.d”) in the package (i.e. directory) “dgui”.

I need to specify the search path for those modules / packages for this to work. Go to project properties => Configuration => DMD and add the path to the source of the library.

image

Press F5, now we get an other error! (i.e. we progressed!…)

 

3.b. declaration file

So, what’s going on? And why does it look for a ‘.d’ file (a source file! I want to use the library not recompile it!)

Here is what happen, the compiler needs some declaration to describe the function that are going to be called. They could be defined inline in the program (if calling into Win32 from D for example, much like DllImport in C#), but more generally you it will look at declaration file defined by the library. There are 2 options there:

  1. Unlike C, where the developer should maintain and synchronise a definition (header / .h) and an implementation (.c /.cpp) file, D can use a single implementation file for both purpose. Hence it will look in the original D source file.
  2. If there is a need to protect some intellectual property, the developer can an generate an ‘interface file’ when compiling (ordinary D file with the ‘.di’ extension and only declaration inside) and deploy these instead of the source code.

 

3.c. linking

Much like C, C++ and other native environment, compiling D is a 2 stage program. First compiling the source files into object files (.o) and then linking all those files into various target (library (.lib or .dll), executable (.exe)).

But it’s all done on the key stroke of F5, hence a catch all usage meaning of compile for both compiling (making object files) and linking (creating the final output).

When I ‘compile’ now I get those kind of errors:

Error    1    Error 42: Symbol Undefined _D4dgui4form4Form13startPositionMFNdE4dgui4core5enums17FormStartPositionZv    C:\Dev\DTest\DTest1\   
Error    2    Error 42: Symbol Undefined _D4dgui7control7Control4sizeMFNdS4dgui4core8geometry4SizeZv    C:\Dev\DTest\DTest1\   
Error    3    Error 42: Symbol Undefined _D4dgui6button6Button6__ctorMFZC4dgui6button6Button    C:\Dev\DTest\DTest1\   
etc…

And so on.

'Symbol alien_looking_name’ generally mean a linker problem. It just happened that Visual D create a “buildlog.html” as well as a “$(project).build.cmd” file in the output folder. So you can see what command it ran to compile and the link the program.

Now I guess I need to include dgui.lib in my project. So go to project properties => linker and set the libraries  and search path.

image

Now it still doesn’t compile and give me this warning:

Warning    1    Warning 2: File Not Found dgui.lib    C:\Dev\DTest\DTest1\

 

I can see in the cmd file or build log that it build with the following command

Command Line set PATH=C:\D\dmd2\windows\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\\bin;%PATH% set DMD_LIB=;C:\D\dgui\lib dmd …

Now I can see in D Linker’s documentation that DMD_LIB is not used, it is LIB that is used. I guess it’s a little bug with Visual D (maybe it was made for D1?) at any rate, I solved it by setting the whole path to the DGui library!

image

F5… build succeeded!

 

4. Bonus, compile DGui

Well, one could add all the file of DGui in Visual D I guess. But DGui comes with a “dgui_build_rel.bat”, I should use it, don’t you think?

Well all I had to do was to add the path to dmd.exe (i.e. C:\D\dmd2\windows\bin\) to the PATH environment variable.

As found in System Property => Advance System Settings => Advanced => Environment Variables…

image

Now I can just click on the bat file and… DGui build successfully, that was easy! Smile

 

5. Done

That’s it, I show how to install D, install a library and compile a program using it!


Tags:
Categories: D | Source Code | Visual Studio
Permalink | Comments (0) | Post RSSRSS comment feed

Waitblock

Sometimes that’s the little thing that one find useful.
Here is such a thing!

 

In our app there are lots of time where an operation can be long and we needs to display a wait cursor (Note: unfortunately we use 3rd party data which are impossible to thread, literally!).

I often found this operation cumbersome. You know, store the original cursor, change the cursor, make a try/finally block, restore the original cursor.

So here is a very simple class which do just that very nicely, just with a single line using statement, as in:

using (new WaitCursorBlock()){…}

 

And here is the code of this simple class:

public class WaitCursorBlock : IDisposable
{
  Cursor originalCursor;
  public WaitCursorBlock()
  {
    originalCursor = Mouse.OverrideCursor;
    Mouse.OverrideCursor = Cursors.Wait;
  }
  public void Dispose() {Mouse.OverrideCursor = originalCursor;}
}


Categories: General | Source Code | WPF
Permalink | Comments (0) | Post RSSRSS comment feed

The Last IValueConverter

source code

  • update (2008/09/25): added a ScriptExtension and mentioned the LambdaExtension.

 

Introduction

Back when I started WPF I though Data Binding was great but, sometimes, I just couldn’t get the information I needed from the value easily enough.

Here I would describe a simple fictitious problem. Let says I want to display a list of integer, with a background color depending whether the number is even or odd.

image

The XAML for this might looks like that:

<ListBox ItemsSource="{Binding List, ElementName=root}"><ListBox.ItemTemplate><DataTemplate><TextBlock Text="{Binding}"Background="{?? what shall I put here ??}"/></DataTemplate></ListBox.ItemTemplate></ListBox>

 

Upon initial investigation

Initially I was thinking to write my own MarkupExtension which would have an expression property and run some sort of script.

It turns out:

  1. You can’t do that. The Binding extension do some things you can’t do. For example you can’t always know when a property change. You can’t find an object by name (as with the ElementName property of the Binding extension), etc…
  2. There is a better way. The Binding extension already does all the work, all you need is a smart IValueConverter to set to the Binding.Converter property.

 

What’s an IValueConverter

When you do data binding in WPF, the framework automatically do some conversion for you, so that the provided value can be used to set the target property. But what if you want to modify the behavior a little bit and decide yourself how to do the conversion?
You can, by setting the Converter property of the binding to an IValueConverter!

public class MyConverter : IValueConverter{#region IValueConverter Memberspublic object Convert(object value, Type targetType, object parameter, CultureInfo culture){throw new NotImplementedException();}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){throw new NotImplementedException();}#endregion}

 

Now the code can look like that:

Window1.xaml

<Window.Resources><local:ColorConverter x:Key="int2color"/></Window.Resources><Grid><ListBox ItemsSource="{Binding List, ElementName=root}"><ListBox.ItemTemplate><DataTemplate><TextBlock Text="{Binding}"Background="{Binding Converter={StaticResource int2color}}"/></DataTemplate></ListBox.ItemTemplate></ListBox></Grid>

ColorConverter.cs

public class ColorConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){if (!(value is int))return null;int i = (int)value;return i % 2 == 0 ? Brushes.Red : Brushes.Green;}}

 

Now every time I encounter such a problem I can write a new IValueConverter.
Wait, NOOOOOOOOOOO!!!!…….

Seriously can’t I just write some build-in (in the XAML) quick code?

 

Script investigation

Initially I found Ken Boggart converters (Sorry, no link, my Google skills have apparently decreased with old age). They even have a script based converter.
I didn’t like them enough because it was using a quick and dirty script engine, tightly coupled with the value converter.

 

I also thought of using IronPython as the script engine. And while this is a great and mature project there is one thing which kills me with Python. Code blocks are defined with the indentation! Seriously…
And it’s just not an aesthetic problem. Imagine a moment: write some embedded python script into your xaml, “accidentally” reformat the document (CTRL+E,D) and voila, you have just broken your python script!
Tsss.. too bad.

 

I thought of writing my own simple interpreter. My initial plan was to use ANTLR. And while it’s a great project, with a great IDE, it’s a bit tedious to test / develop a grammar in C#, as all the tools are geared towards Java. Then I discovered Irony.
I haven’t used it much (compared to ANTLR) but my first impression is:

  • Writing the grammar is easier, better looking and definitely more C# friendly than ANTLR.
  • The next stage, the interpreter or AST visiting is much more tedious.
  • Plus ANTLR makes it very super easy to embed action directly into the parser, enabling a all in one parsing / interpreting phase for example.

But then, it turns out, I didn’t need to write my own Irony powered interpreter / script engine, there is already one: Script.NET.

 

The ScriptConverter

Script.NET is a quick and easy script engine that can, as all self-respecting .NET script engine, call upon all .NET methods and classes. It can easily be embedded into your application and the syntax is so simple, you can teach it yourself in 21 minutes! Great, just what I was looking for. And, of course, it uses curly braces to define code blocks!

The current version of Script.NET, at this time (Sept. 2008), doesn’t support the latest Irony. It ships as 3 DLLs on it own (plus the outdated Irony) and it has a dependency on Windows Forms. I decided to “fix” all of that and the version shipped in the zipped source code is not the original Script.NET source code, but a custom version which comes as only 1 DLL, with no WinForms dependency.

In my converter I had to, obviously, add an expression property (for the script). Less obvious but as critical, I had to add a known types property, so that the script could call on static property or on some classes constructor.

 

How does it works

Well to starts with you create a script interpreter with just one line

Script script = Script.Compile("my script string");

Then you can define some global variables or add known types as follows:

script.Context.SetItem("value", ContextItem.Variable, value);script.Context.SetItem("Brushes", ContextItem.Type, typeof(Brushes));

And then you can evaluate it in one line as well

return script.Execute();

 

A little problem which stopped me for a few minute was, how do I return something from my script?

Well a simple value is an expression and the last computed expression is the returned value. For example “1” is a valid script which return 1.

Script.NET doesn’t support the (bool_expr ? true_expr : false_expr) operator, but you can express it as:

if (bool_expr)true_expr;elsefalse_expr; 

 

First Solution

Now let’s write my script converter.

ScriptConverter.cs

[ContentPropertyAttribute("Expression")]public class ScriptConverter : IValueConverter{Script script;TypeDictionary knownTypes = new TypeDictionary();string expression;public string Expression{get { return expression; }set{expression = value;script = Script.Compile(expression);SetTypes(script, knownTypes);}}public class TypeDictionary : Dictionary<string, Type> { }public TypeDictionary KnownTypes{get { return knownTypes; }set{knownTypes = value;SetTypes(script, knownTypes);}}static void SetTypes(Script ascript, TypeDictionary types){foreach (var item in types)ascript.Context.SetItem(item.Key, ContextItem.Type, item.Value);}public object Convert(object value, Type targetType, object parameter, CultureInfo culture){script.Context.SetItem("value", ContextItem.Variable, value);script.Context.SetItem("param", ContextItem.Variable, parameter);script.Context.SetItem("culture", ContextItem.Variable, culture); 
return script.Execute();}}

 

Armed with this ultra cool converter, my XAML is now ready to rock!
You will notice that I initialized the Script with a list of type it need to know to evaluate the expression.

Window1.xaml

<Window.Resources><local:ScriptConverter x:Key="int2color"><local:ScriptConverter.KnownTypes><local:TypeDictionary><x:Type x:Key="Brushes" TypeName="Brushes"/></local:TypeDictionary></local:ScriptConverter.KnownTypes>if( value % 2 == 0 )Brushes.Red;elseBrushes.Green;</local:ScriptConverter></Window.Resources><Grid><ListBox ItemsSource="{Binding List, ElementName=root}"><ListBox.ItemTemplate><DataTemplate><TextBlock Text="{Binding}"Background="{Binding Converter={StaticResource int2color}}"/></DataTemplate></ListBox.ItemTemplate></ListBox></Grid>

 

Further Simplification

Okay now I have done it all in XAML, and it works well. But I exchanged a useless C# file for a bloated XAML! smile_embaressed

What I would like to is just put the expression in the converter, like a lambda expression.

It’s where MarkupExtension(s) will come to the rescue. Basically extension are custom way to create object with code running in the XAML. {x:Type …}, {x:Static …}, {Binding …} are all MarkupExtensions.

Create your own extension is easy. Okay let’s write the simplified XAML I really would like to see, and then write the extension:

<ListBox ItemsSource="{Binding List, ElementName=root}"><ListBox.ItemTemplate><DataTemplate><WrapPanel Orientation="Horizontal"><TextBlock Text="{Binding}"Background="{Binding 
Converter={local:Script
'if(value%2==0) Brushes.Red; else Brushes.Green;',
{
x:Type Brushes}}}"/></WrapPanel></DataTemplate></ListBox.ItemTemplate></ListBox>

Here we go, it’s a much simpler XAML code! In the Converter parameter of the binding I passed an extension which directly created my converter. This extension will take the following parameter: a script string and a list of type necessary for the script to run.

Initially I was planning to use an extension constructor like that:

public ScriptExtension(string code, params Type[] types){//....}

But it won’t work because XAML won’t recognize the “params Type[]” construct, and it will expect 2 and only 2 parameter, the second being array of types. There are also a few other problems with markup extension parameter (XAML choose them sorely on the number of parameter, it doesn’t do any type matching). Finally I used this code

public class ScriptExtension : MarkupExtension{public ScriptExtension(string code) { Init(code); }public ScriptExtension(string code, Type type) { Init(code, type); }public ScriptExtension(string code, Type type, Type t2) { Init(code, type, t2); }protected ScriptExtension(string code, params Type[] types) { Init(code, types); }void Init(string code, params Type[] types){Code = code;TypeDictionary dict = new TypeDictionary();foreach (var aType in types)dict[aType.Name] = aType;KnownTypes = dict;}public string Code { get; private set; }public TypeDictionary KnownTypes { get; private set; }

// return the converter herepublic override object ProvideValue(IServiceProvider isp){return new ScriptConverter(Code) { KnownTypes = KnownTypes };}}

 

 

 

 

 

Designer Issue

It worked quite nicely at runtime. But there was a problem with the designer. It just could not work with those multiple constructor. In the end I created multiple ScriptExtension subclass called Script0Extension, Script1Extension, Script2Extension, etc… depending on the number of type parameters.

Hence the final XAML look like that

<ListBox.ItemTemplate><DataTemplate><WrapPanel Orientation="Horizontal"><TextBlock Text="{Binding}"Background="{Binding 
Converter={local:Script1
'if(value%2==0) Brushes.Red; else Brushes.Green;',
{
x:Type Brushes}}}"/></WrapPanel></DataTemplate></ListBox.ItemTemplate>

 

Alternate Solution

At this stage we got a pretty good solution for many problem. But then I investigated this LambdaExtension. It’s really cool and I added it to my personal toolbox and to this ExpressionExplorer project as well.

It lets you define converters with Lambda expression, for exemple:

<TextBlock Text='{Binding Source={x:Static s:DateTime.Now},Converter={fix:Lambda "dt=>dt.ToShortTimeString()"}}'>  

It’s pretty good and I imagine Lambda expression would be way faster that my script expression. However it suffers from a few problems:

  • you cannot use the other parameters of the converter method (parameter and culture).
  • you cannot reference any type, you cannot return a Brush, i.e. it cannot solve my simple problem!

But I guess that, even with these shortcomings, it can still make an excellent converter in DataTriggers.

 

Additional Information

Here are some people or pages that have inspired me while working on this code.

Later on I had these additional feedback which proved to be very valuable.

First Orcun Topdagi has improved his LambdaExtension further, as you can check out on his blog about WPFix2 and WPFix3. Wow those are real hot goodies. I might even ditch my extension in his favor! But I have to spend some more time playing with it first (kind of super busy right now).

Also Daniel Paull has some very interesting blog posts (here, here and here) on how to do something similar with the DLR. What I really like about these article it’s that they are an easy introduction to the DLR.


source code.

 

 


Categories: Source Code | WPF
Permalink | Comments (1) | Post RSSRSS comment feed