Filed under: C#,F# — Steffen Forkmann at 11:08 Uhr
I recently had the problem to register a global hotkey, but my “old” Win32-API calls didn’t work with WPF. I looked around the web and found the “Managed Windows API”, but I didn’t want to add another external dependency to my project, so I extracted the core functions for registering hotkeys and condensed the code to a new version.
As the original “Managed Windows API” is licensed by the GNU Lesser General Public License (LGPL) I want to provide my modifications here.
First we need a Window which can dispatch the window messages to our event handlers:
///<summary>
/// A Win32 native window that delegates window messages to
///handlers. So several
/// components can use the same native window to save
Filed under: English posts,F# — Steffen Forkmann at 16:02 Uhr
One of the nice properties of functional programming languages is the easy extensibility of custom functions. Let’s consider a simple F# function (from “FAKE – F# Make”) for a recursive directory copy:
open System
open System.IO
/// Copies a directory recursive
/// Thanks to Robert Pickering http://strangelights.com/blog/
/// param target: target directory : string
/// param source: source directory : string
let CopyDir target source =
Directory.GetFiles(source, "*.*", SearchOption.AllDirectories)
|> Seq.iter (fun file ->
let newFile = target + file.Remove(0, source.Length)
printf "%s => %s" file newFile
Directory.CreateDirectory(Path.GetDirectoryName(newFile)) |> ignore
File.Copy(file, newFile, true))
If we want to allow users to set custom file filters, we can add a third parameter:
/// Exclude SVN files (path with .svn)
/// excludeSVNFiles: string -> boollet excludeSVNFiles (path:string) = not <| path.Contains ".svn"
/// Includes all files
/// allFiles: string -> boollet allFiles (path:string) = true
Now it is possible to use CopyDirFiltered in the following ways:
/// Copies all files <=> same as CopyDir
CopyDirFiltered "C:\\target" "C:\\source" allFiles
/// Copies all files except SVN files
CopyDirFiltered "C:\\target" "C:\\source" excludeSVNFiles
/// Copies all files only if random number <> 2
let r = new Random()
CopyDirFiltered "C:\\target" "C:\\source" (fun path -> r.Next(5) <> 2)
Extensibility of functions in C#
Of course we can do the same thing in C# 3.0:
/// <summary>
/// Copies a directory recursive
/// and allows to filter the files
/// </summary>
/// <param name="target">The target.</param>
/// <param name="source">The source.</param>
/// <param name="fileFilter">The file filter.</param>
public static void CopyDirFiltered(string target, string source,
Func<string, bool> fileFilter)
{
string[] allFiles = Directory.GetFiles(
source, "*.*", SearchOption.AllDirectories);
foreach (string file in from f in allFiles
where fileFilter(f)
select f)
{
string newFile = target + file.Remove(0, source.Length);
Console.WriteLine("{0} => {1}", file, newFile);
Directory.CreateDirectory(Path.GetDirectoryName(newFile));
File.Copy(file, newFile, true);
}
}
Now it is easy to use the C# function with lambdas:
“A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.”
Func<string, bool> filterSVN = x => !x.Contains(".svn");
Func<string, bool> allFiles = x => true;
/// Copies all files <=> same as CopyDir
CopyDirFiltered("C:\\target", "C:\\source", allFiles);
/// Copies all files except SVN files
CopyDirFiltered("C:\\target", "C:\\source", filterSVN);
/// Copies all files only if random number <> 2
var r = new Random();
CopyDirFiltered("C:\\target", "C:\\source", path => r.Next(5) != 2);
Keeping this simple technique in mind allows to create very flexible functions.
Claus Lundstrøm zeigt in einem schönen Blogpost wie man in NAV2009 den Code auf Seite der ServiceTier (also auch remote) debuggen kann – und zwar über Visual Studio 2008 direkt im generierten C#-Code. Mit dieser Variante ist man nicht mehr gezwungen das Debugging über den Classic-Client zu tun, sondern kann direkt aus dem Dynamics NAV RoleTailored-Client debuggen.
Dummerweise ist der generierte C#-Code, wie das bei generiertem Code eigentlich immer der Fall ist, nicht gerade “optisch schöner” C#-Style und hat auch nur noch wenig mit dem Original-C/AL-Code zu tun – ist aber immerhin lesbar.
Das ist ein wirklich interessanter Ansatz und erlaubt mit etwas Geschick auch UnitTesting für NAV 2009. Dafür werde ich demnächst mal versuchen ein kleines Beispiel zu bloggen.
Florian Mätschke hat soeben seine auf der BASTA! 2008 in Mainz angekündigte Umfrage auf seinem Blog veröffentlicht. Dabei wurden die BASTA!-Speaker zu der Technologie befragt, die sie im Moment am meisten fasziniert. “Gewinner” ist übrigens Silverlight 2 geworden, dicht gefolgt von funktionaler Programmierung (in F# bzw. LINQ) – wofür ich mich übrigens auch entschieden habe.
Insgesamt ist das Umfrageergebnis, wie für die BASTA! zu erwarten war, sehr .NET-lastig. Obwohl auf der Abendveranstaltung noch Technologien wie Waschmaschine und Auto als faszinierend erachtet wurden, haben sich die meisten Speaker schlussendlich für ihr Vortragsthema im weitesten Sinne entschieden.
Ich muss sagen, dass ich das Konzept der Umfrage sehr interessant finde. Das Problem ist nur, dass man z.B. auf einer Java-Konferenz natürlich vollkommen konträre Ergebnisse erzielt. Um die wirklichen “Technologie Highlights“ zu ermitteln müsste man die Umfrage selbstverständlich viel größer und anonymisiert anlegen.
Microsoft hat am 31.3.2008 auf PartnerSource die erste Version von Dynamics Mobile veröffentlicht. Dabei handelt es sich primär um ein auf .NET basierendes Architekturkonzept mit dem man Mobile Endgeräte (mit Windows Mobile 5.0 oder 6.0) an ERP-Systeme (Dynamics NAV oder AX) anbinden kann. Weiterhin wird mit “Mobile Sales” jedoch eine umfangreiche Beispielanwendung mitgeliefert.
ReSharper ist ein Plugin der Firma JetBrains für Visual Studio, das sich speziell die Produktivitätssteigerung beim Entwickeln als Ziel gesetzt hat. Besonderes Augenmerk wird dabei auf die Refactoring-Unterstüzung gelegt, also auf das nachträgliche Umgestalten von Quellcode. JetBrains wirbt damit das “intelligenteste AddIn für Visual Studio” entwickelt zu haben – doch was kann ReSharper wirklich?
Am 06.07.2007 findet ab 19:30 ein sehr interessantes Event in Leipzig statt. Roland Weigelt wird über die Entwicklung seines mehrfach ausgezeichneten Plugins GhostDoc berichten und einen Einblick in die Visual Studio Erweiterbarkeit geben. GhostDoc ist für mich neben ReSharper das wichtigste Plugin für Visual Studio überhaupt.
Der Vortragende wird folgende Features vorstellen:
Für Java-Programmierer bzw. VB-Programmierer die gern in C# einsteigen wollen, gibt es eine Schnellreferenz mit den wichtigsten Syntaxunterschieden. Das funktioniert natürlich auch umgekehrt – aber wer würde schon freiwillig von C# weg wollen?