seeseekey.net - Invictus Deus Ex Machina

Ein Sin­gle­ton ist grob gesagt eine Klasse wel­che nur ein­mal initia­li­siert wer­den kann. Dies ist ganz prak­tisch für glo­bale Objekte wie z.B. einen ID Gene­ra­tor, der nur ein­mal exis­tie­ren darf. Doch wie schreibt man ein sol­ches Sin­gle­ton? Laut MSDN-Mag sieht das ganze so aus:

sealed class Singleton
  {
    private Singleton() {}
    public static readonly Singleton Instance = new Singleton() ;
  }

Diese Klasse kann man nun über Singleton.Instance auf­ru­fen. Sie wird dabei bei der ers­ten Benut­zung initia­li­siert. Da der Kon­struk­tor pri­vate ist, kann sie von kei­ner ande­ren Klasse initia­li­siert wer­den. So wird dafür gesorgt das es nur eine Instanz gibt.

Wei­tere Infor­ma­tio­nen gibt es unter:
http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)

Ich nutze bei der Ent­wick­lung ein sehr hilf­rei­ches Tool namens Resource Refac­to­ring Tool. Nor­ma­ler­weise taucht die­ses im Menü Refac­tor als Extract to Resource auf. Bei mir ist es aller­dings ein­fach ver­schwun­den. Hier hilft es das Addin zu reset­ten. Dazu geht man in den Ord­ner C:\Program Files (x86)\Microsoft Visual Stu­dio 10.0\Common7\IDE und öffnet dort eine Kom­man­do­zeile. In diese gibt man dann

devenv.exe /resetaddin Microsoft.VSPowerToys.ResourceRefactor.Connect 

ein und schon ist das Pro­blem gelöst :)

Wei­tere Infor­ma­tio­nen gibt es unter:
http://seeseekey.net/blog/1038

Die Über­set­zung von .NET Pro­gram­men gestal­tet sich doch recht schwie­rig. Wobei schwie­rig in die­sem Fall das fal­sche Wort ist. Umständ­lich trifft es in die­sem Fall bes­ser. Vor allem wenn als Ent­wick­ler das Qt Über­set­zungs­sys­tem mit Qt Lin­gu­ist ken­nen­ler­nen dürfte. Ein Pro­blem bei der Über­set­zung ist, dass man zu jedem Pro­gramm meh­rere Res­sour­cen (resx) Dateien in den unter­schied­lichs­ten Spra­chen hat z.B. translate.resx, translate.de.resx und translate.nl.resx.

An die­ser Stelle ist ein Tool wün­schens­wert wel­ches diese gan­zen Dateien neben­ein­an­der dar­stellt und eini­gen Kom­fort bei der Bear­bei­tung bie­tet. Basie­rend auf dem Resx Resource Trans­la­tor (http://resxtranslator.codeplex.com) von Hakan Lin­des­taf habe ich dabei ein Tool namens Vert­i­mas (litau­isch für Über­set­zung) geschaf­fen wel­ches einem die­sem Arbeit leich­ter von der Hand gehen lässt.

Vert­i­mas ist dabei ein Open Source Pro­jekt wel­ches unter der GPL steht. Die offi­zi­elle Pro­jekt­seite ist dabei unter vertimas.googlecode.com zu fin­den. Über Feed­back, Ver­bes­se­run­gen und Kri­tik freue ich mich :)

Manch­mal sucht man den Feh­ler an der fal­schen Stelle, wie ich ges­tern bei einem Quell­text fest­stel­len dürfte wel­cher auf .NET und Mono lau­fen sollte. Man nehme fol­gen­den C# Code:

    Bitmap bmp=new Bitmap((int)width, (int)height, PixelFormat.Format32bppArgb);
    BitmapData data=bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

    Marshal.Copy(intern.imageData, 0, data.Scan0, (int)(width*height*4));

    bmp.UnlockBits(data);
    data=null;
    return bmp;

Die­ser Code kopiert Daten in ein Bit­map. Unter .NET funk­tio­niert dies tadel­los. Also lag der Gedanke nah das dies ein Mono Pro­blem ist. Nach etli­chen Tests ergab sich dann aber das es genau umge­kehrt ist. Es liegt an der Zeile:

    BitmapData data=bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

und zwar spe­zi­ell an dem ImageLockMode.ReadOnly. Dort könnte z.B. ImageLockMode.ReadWrite ste­hen und schon würde es unter .NET und Mono funk­tio­nie­ren. Doch warum geht es nun bei .NET trotz­dem mit der fal­schen Vari­ante? Die .NET API reicht die Para­me­ter kor­rekt an die GDI+ wei­ter, diese igno­riert sie aber. Aus die­sem Grund funk­tio­nierte es unter .NET. Sprich Mono hat alles rich­tig gemacht :)

Erstaunt stellte ich ges­tern fest das der neue Stan­dard­fo­to­ma­na­ger unter Ubuntu (Shot­well) in Vala geschrie­ben ist. Bei Vala han­delt es sich um eine Pro­gram­mier­spra­che wel­che stark an C# und Java ange­lehnt ist. Dabei benö­tigt sie aber keine Lauf­zeit­um­ge­bung. Man hat dann also eine Spra­che wel­che eine moderne Syn­tax bie­tet und keine Lauf­zeit­um­ge­bung benö­tigt son­dern nativ auf dem Sys­tem läuft. Im Gegen­satz zu .NET/Mono hat die Spra­che kei­nen Gar­bage Collec­tor son­dern imple­men­tiert auto­ma­ti­sche Refe­renz­zäh­lung zur Speicherverwaltung.

Beim durch­schauen der Syn­tax (ver­gli­chen mit C#) sind mir einige Unschön­hei­ten auf­ge­fal­len wel­che einige Kon­strukte nicht sehr ele­gant aus­se­hen las­sen, aber das muss man sich wahr­schein­lich mal in einem klei­nen Pro­jekt anschauen. Es ist mög­lich mit Vala platt­for­mu­n­ab­hän­gige Anwen­dun­gen zu schrei­ben. Als Stan­dard­bi­blio­thek steht einem die glibc sowie die Geelib zur Ver­fü­gung. Der Vala Com­pi­ler wan­delt den Quell­code in C Code um und kom­pi­liert die­sen dann anschlie­ßend. Defi­ni­tiv eine Spra­che die man sich mal anschauen sollte :) Die offi­zi­elle Seite von Vala ist unter http://live.gnome.org/Vala zu finden.

Wei­tere Infor­ma­tio­nen gibt es unter:
http://de.wikipedia.org/wiki/Vala_%28Programmiersprache%29

Im Visual Stu­dio gibt es eine wun­der­bare Funk­tio­na­li­tät zum docken von Fens­tern. Möchte man so etwas nach­bauen kann man natür­lich sein Geld in eine Kom­po­nen­ten­samm­lung inves­tie­ren. Die andere Vari­ante ist es die Dock­Pa­nel Suite zu benut­zen wel­che unter der MIT Lizenz steht. Sie bie­tet dabei eine sehr große Fle­xi­bi­li­tät was das Fens­ter­ma­nage­ment angeht und ist erstaun­lich robust gebaut. Zu fin­den ist die Suite unter http://sourceforge.net/projects/dockpanelsuite/.

Das Ding hat auch ein klei­nes Pro­blem mit dem Rah­men im Full­screen­mo­dus. Dazu kom­men­tiert man ein­fach ein paar Zei­len in der DockWindow.cs aus:

		public virtual Rectangle DisplayingRectangle
		{
			get
			{
				Rectangle rect = ClientRectangle;
				// if DockWindow is document, exclude the border
				if (DockState == DockState.Document)
				{
					//rect.X += 1;
					//rect.Y += 1;
					//rect.Width -= 2;
					//rect.Height -= 2;
				}

                                ...

Danach ist das Pro­blem Geschichte und das Con­trol ange­nehm rah­men­los :)

Wei­tere Infor­ma­tio­nen gibt es unter:
https://sourceforge.net/projects/dockpanelsuite/forums/forum/402316/topic/2011982/index/page/1

Nach der Umstel­lung auf Visual Stu­dio 2010 hatte ich einige Pro­bleme mit eini­gen C/C++ Pro­jek­ten. Ein­fach weil Micro­soft bei man­chen Sachen stan­dard­kon­for­mer gewor­den ist. Dadurch funk­tio­nier­ten einige Dinge nicht mehr. Sehr gehol­fen bei sol­chen Pro­ble­men hat mit der Blog von Mar­tin Rich­ter wel­cher unter http://blog.m-ri.de/ zu fin­den ist. Rein­schauen lohnt sich ;)

In C bzw. C++ muss man den Spei­cher wel­chen man allo­ziert auch irgend­wann wie­der frei­ge­ben. Macht man dies nicht ent­ste­hen soge­nannte Memory Leaks, der Spei­cher füllt sich so immer wei­ter. Es wäre doch schön wenn es auch unter C/C++ einen Gar­bage Collec­tor gäbe wel­cher am Ende (und zwi­schen­durch) ein­fach den Spei­cher von Objek­ten berei­nigt wel­che nicht mehr benö­tigt wer­den. C wäre nicht C wenn nicht schon irgend­je­mand so etwas imple­men­tiert hat. Und so fin­det man unter http://www.hpl.hp.com/personal/Hans_Boehm/gc/ eine Imple­men­ta­tion des­sel­ben. Aus­pro­bie­ren lohnt sich, denn es schont die Ner­ven ;)

Wei­tere Infor­ma­tio­nen gibt es unter:
http://de.wikipedia.org/wiki/Memory_leak
http://de.wikipedia.org/wiki/Garbage_Collection

Ich wollte unter Mono­De­ve­lop ein Pro­jekt wei­ter­ent­wi­ckeln wel­ches ursprüng­lich für .NET in Visual Stu­dio geschrie­ben wurde. In die­sem Pro­jekt wollte ich dann ein For­mu­lar bear­bei­ten. Mein Pro­blem war das ich nicht in den Desi­gner kam. Aber warum nur? Mono­De­ve­lop besaß doch einen Designer…

Nach eini­gem stö­bern in der Doku­men­ta­tion däm­merte es mir. Der GTK# Desi­gner wel­cher Mono Deve­lop bei­liegt ist nicht für Win­Forms gedacht. Dazu benö­tigt man den Win­Forms Desi­gner wel­cher nicht Bestand­teil des Pake­tes ist. Eine inter­es­sante Seite mit Infor­ma­tio­nen rund um den Win­Forms Desi­gner gibt es unter http://www.mono-project.com/WinForms_Designer.

Möchte man den But­ton für die Kon­text­hilfe in Qt Fens­tern aus­blen­den so reicht für das ent­spre­chende Fens­ter im Kon­struk­tor fol­gen­des zu schreiben:

FormProgress::FormProgress(QWidget *parent) : QDialog(parent)
{
  setupUi(this);

  //WindowsFlags
  setWindowFlags(windowFlags() & (~(Qt::WindowContextHelpButtonHint)));
}

Und schon ist der ent­spre­chende But­ton in der Titel­leiste weg :)

Möchte man im Qt Desi­gner ein QGL­Wid­get für OpenGL in den Dia­log ein­set­zen so wird man fest­stel­len das kei­nes exis­tiert. Darum setzt man zunächst ein Wid­get in das For­mu­lar. Anschlie­ßend klickt man mit der rech­ten Maus­taste auf das For­mu­lar und wählt dort Pro­mote to… aus. Anschlie­ßend öffnet sich fol­gen­der Dialog:

Dort gibt man dann bei Pro­mo­ted class name QGL­Wid­get (das Hea­der File wird auto­ma­tisch ein­ge­tra­gen) ein und drückt anschlie­ßend auf Add und been­det den Dia­log mit Pro­mote. Schon hat man das ent­spre­chende Wid­get im Qt Desi­gner angelegt.

Möchte man das Qt Frame­work und Visual Stu­dio benut­zen so sollte man sich das ent­spre­chende Addin unter http://qt.nokia.com/downloads/visual-studio-add-in anschauen. Neben dem Addin wird dann noch das Frame­work benö­tigt wel­ches unter http://qt.nokia.com/downloads/windows-cpp-vs2008 bezo­gen wer­den kann. Anschlie­ßend fin­det man im Visual Stu­dio einen neuen Menü­punkt Qt. Das Addin ist damit installiert.

Nun sollte noch die Umge­bungs­va­ria­ble Path um das bin Ver­zeich­nis des Qt Fram­works erwei­tert wer­den (z.B. C:\Qt\4.6.3\bin) sowie eine neue Umge­bungs­va­ria­ble namens QTDIR ange­legt wer­den in wel­cher der Pfad des gesam­ten Fram­works steht (z.B. C:\Qt\4.6.3\). Nun kann mit Qt gear­bei­tet werden.

Wei­tere Infor­ma­tio­nen gibt es unter:
http://mm-werkstatt.informatik.uni-augsburg.de/documents/tutorials/qt2005.pdf

Vor ein paar Tagen teste ich eine .NET Anwen­dung auf einem Ubun­tu­sys­tem. Anschlie­ßend wollte ich in eine von der Anwen­dung geschrie­bene Kon­fi­gu­ra­ti­ons­da­tei hin­ein­schauen. Doch ich fand sie erst ein­mal nicht. Die Anwen­dung ließt sich dabei den Pfad der loka­len Anwen­dungs­da­ten mit­tels SpecialFolder.LocalApplicationData aus. Unter Ubuntu ist das ent­spre­chende Ver­zeich­nis dabei unter ~/.local/share/myapp/ zu finden.

Da ich pri­vat wie beruf­lich die meiste Zeit in C# pro­gram­miere ist der Umstieg dank Mono nicht all zu schwer gefal­len. Ges­tern wollte ich dann mal meine Pro­jekte unter Mono kom­pi­lie­ren und wurde dabei auf einen Feh­ler beim kom­pi­lie­ren einer resx Datei hin­ge­wie­sen. Es fehlte wohl die Anwen­dung resgen2. Glü­cker­lich­weise lässt sich er Feh­ler schnell durch die Instal­la­tion eini­ger Pakete behe­ben:

sudo apt-get install mono-gmcs mono-mcs mono-2.0-devel

Neben die­sen Pake­ten sind für die Mono­ent­wick­lung außer­dem noch fol­gende Pakete:

sudo apt-get install monodoc-browser mono­de­ve­lop monodevelop-versioncontrol

von Inter­esse.

Wei­tere Infor­ma­tio­nen gibt es unter:
http://de.wikipedia.org/wiki/Mono-Projekt
http://de.wikipedia.org/wiki/MonoDevelop