Ich tauch dann mal bis zum Ende der Woche ab: Dive Deeper

Ab Dienstagmorgen bis Sonntagmittag werde ich mit meiner Frau als freiwilliger Mitarbeiter am 15. Weltjugendkongress der Baptisten unter dem Thema Dive Deeper in Leipzig sein.

Ich bin richtig gespannt und auch schon etwas nervös an solch einem Event, mit über 6000 Leuten aus aller Herren Länder, mitarbeiten zu können. Das ganze wird auf dem Gelände der Leipziger Messe stattfinden.
Aus meiner Gemeinde (EFG-Meerholz) werden auch über 15 Jugendliche plus Pastor teilnehmen.

Und auch meine drei Töchter werden dort sein:
Die Jüngste im Kids-Camp, die Mittlere alsTeilnehmer und meine älteste Tochter mit Ehemann als Familiengruppenleiter.
Also ein richtiges Familientreffen 😉 obwohl wir uns wahrscheinlich kaum sehen werden…

VS Tipps & Tricks: Fehler in Custom Build Steps ermitteln

Manchmal macht man ja schon komplexere Sachen in den Custom-Build-Steps, wie zum Beispiel auch das Erzeugen der HTML-Help Include Datei. Aber es geht ja noch viel komplizierter, zumindest benutze ich solche komplexen Custom-Build Funktionen ziemlich häufig!

Was nun, wenn man eine Fehlermeldung erhält in solch einem Custom-Build-Step, aber gar nicht weiß wo der Batch eigentlich aussteigt, oder was er gerade getan hat ❓ Besonders wenn die Ausgabe im Build-Fenster so informativ ist wie:
Das System kann den angegebenen Pfad nicht finden.

Das eigentliche Problem ist, dass die Batch-Zeilen bei der Ausführung nicht angezeigt werden.
Man könnte meinen, dass Visual Studio dies mit einem mystischen Trick macht. Sieht man sich jedoch die Build-Log Datei an, so sieht man, dass vor einen Custom-Build-Step einfach immer ein @echo off eingebaut wird.
Was spricht eigentlich dagegen als erste Zeile ein @echo on in den Custom-Build einzusetzen? Nichts!

Gesagt getan!
Die Folge: Jede Zeile des Batches, der im Custom-Build durchlaufen wird, erscheint brav in der Build-Ausgabe. Einen Fehler zu finden, bei man z.B. einen Pfad falsch mit Makros zusammengebaut hat ist nun denkbar einfach.

TFS-2008 mit Visual Studio 2005 und anderen älteren Entwicklungssystemen benutzen

Ist man eigentlich gezwungen Visual Studio 2008 zu verwenden wenn man Team Foundation Server 2008 nutzt?

Nein! Wenn man Visual Studio 2005 und 2008 nutzt, wie auch ich für einige Projekte, dann kann man ohne weiteres trotzdem aus allen Systemen auf TFS-2008 zugreifen.
Man muss nur den passenden Team Explorer installieren. D.h. für Visual Studio 2005 installiert man einfach den Team Explorer 2005. Der 2005er Explorer steht übrigens auch kostenlos zum Download zur Verfügung, wer evtl. keine Version des TFS-2005 hat (http://www.microsoft.com/downloads/details.aspx?FamilyID=46473C2A-BB85-4461-BB27-4792A5DEF222&displaylang=ja&displaylang=en)

Es ist klar, dass man in diesem Fall einige Features des TFS-2008 nicht benutzen kann, bzw. nur über den Team Explorer 2008. Aber das ist ja auch nicht weiter tragisch.
Tunlichst vermeiden sollte man aber neue Team-Projekte aus dem 2005er Explorer heraus anzulegen, das schlägt bei mir fehl.  Also neue TFS-Projekte zuerst im Team Explorer 2008 anlegen und dann mit Visual Studio 2005 bearbeiten.

Das Source Control System von TFS-2008 lässt sich übrigens mit den entsprechenden Microsoft Source Code Control Interface (MSSCCI). Ein entsprechendes Plugin gibt es hier zum Download: http://www.microsoft.com/downloads/details.aspx?familyid=faeb7636-644e-451a-90d4-7947217da0e7&displaylang=en. Diese Liste der unterstützen Systeme ist lang:

  • Visual Studio .NET 2003
  • Visual C++ 6 SP6
  • Visual Visual Basic 6 SP6
  • Visual FoxPro 9 SP1
  • Microsoft Access 2003 SP2
  • SQL Server Management Studio
  • Sparx Systems Enterprise Architect 6.1
  • Sybase PowerBuilder 10.5
  • Toad for SQL Server 2.0

VS Tipps & Tricks: Kontextmenüs in Visual Studio anpassen

Man kann ja ohne weiteres Toolbars und die Menüs in Visual Studio anpassen, was ich auch gerne nutze.

Besonders interessant ist es aber auch die verschiedenen Kontextmenüs anzupassen. Dazu muss man zu einem kleinen Trick greifen, denn die Kontext Menüs stehen normalerweise nicht automatisch im Zugriff beim Anpassen der UI.

  • Man wählt Tools -> Customize -> Toolbars
  • Dort dann Context Menus auswählen -> Kontextmenü

Es öffnet sich nun ein neuer Toolbar, in dem die Kontextmenüs alle erscheinen und können wie gewohnt angepasst werden.

Gar nicht schwierig, man muss nur wissen wie man dran kommt 😉

Probleme beim Update auf WordPress 2.6 (Permalinks und Update)

Das Update auf die WordPress Version 2.6 war die erste Version, die mir richtig Ärger gemacht hat.

Erstes Problem:
Nach der Installation der neuen Dateien habe ich …/wp-admin/upgrade.php aufgerufen. Das DB-Update wurde angefangen (so die Meldung). Allerdings kam es niemals zu einer Meldung, dass das Update durchgeführt wurde. Nach einer gewiesen Zeit war immer nur noch das WordPress Logo zu sehen und kein Script mehr aktiv. Ich musste diese Seite bestimmt zwanzig mal aufrufen, biss ich endlich die Meldung bekam, dass die Datenbank geändert wurde.
Ich habe keine Ahnung bis heute woran dies lag.

Zweites Problem war weitaus ekelhafter:
Alle Permalinks (Tags und Kategorien) führten zu einem Fehler 404. Durch etwas googlen fand ich diesen Eintrag: http://wordpress.org/support/topic/189058
Lösung 1 entfiel, also habe ich die Lösung 3 versucht, was aber irgendwie nicht funktionierte.
Also Lösung 2, wodurch jetzt leider die Kategorie Links und Tag Links sich verändern. Schade.

Beim nächsten Mal, werde ich mal erst 10 Tage vergehen lassen bis ich wieder ein WordPress Update durchführe 🙁

Microsoft Visual Studio 2008 Service Pack 1 Release Candidate wurde veröffentlicht

Seit dem 06.07.2008 steht für Visual Studio 2008 auf Microsoft Connect ein Download für den Release Candidate des Microsoft Visual Studio 2008 Service Pack 1 zur Verfügung.

Dann kann man ja hoffen, das es bis zur Freigabe des SP1 nicht mehr lange dauert… 😉

Anmerkung: Es ist möglich, dass dieser Download nur Teilnehmern des SP1 Beta Programms zur Verfügung steht.

MFC Fenster in anderen Applikationen verwenden…

Manch ein Programmierer kommt auf die Idee und entwickelt ein Plugin mit der MFC für ein anderes Programm. Dass Plugin oder die entsprechende Funktionalität soll alleine in einer Standard-DLL leben. Die Schnittstelle wird bewusst schmal und einfach gehalten. Manche dieser kleinen Tools müssen/wollen nun auch ein Fenster nicht modal anzeigen.
Kein Problem, einfach CWnd::Create, oder CDialog::CreateIndirect und schon hat man sein Fenster.

Eines muss an dieser Stelle klar sein ❗
Man verlässt sich in einem solchen Fall, dass die hostende Anwendung eine Messageloop bereitstellt. Andernfalls bekommt das Fenster keine Nachrichten. OK!

Was einem aber auch klar sein muss in diesem Fall ❗
Man kann PreTranslateMessage nicht mehr verwenden. Das würde nur gehen, wenn man eine Extension DLL hat, oder die hostende Anwendung als auch die DLL beide die MFC als Shared DLL in derselben Version verwenden.
Damit ist nun auch verbunden, dass evtl. Tooltips in diesem Fenster ein sehr eigenwilliges Leben führen werden.

Es gibt einfach keinen vernünftigen Weg sich in die Messageloop eines Hosts auf einfache und vernünftige Art einzuklinken.
Ein Ansatz an dieser Stelle wäre sicherlich ein entsprechender WH_GETMESSAGE Hook. Denkbar wäre dann die entsprechende Nachricht abzufangen und an die eigenen Fenster via PreTranslateMessage anzubieten, sofern eben die eigenen Fenster den Focus haben oder die Nachricht für eines dieser eigenen Fenster oder Kindfenster bestimmt sind. Eben genauso wie es die MFC in seiner Messageloop macht. Dieses Verfahren wird auch für ActiveX Controls in der MSDN im KB Artikel 194292 empfohlen.

Siehe auch Wann Message Reflection nicht funktioniert!

Tipps & Tricks: MFC Command Routing in komplexen UIs

UIs werden immer komplexer. Und manche UI passt sicher nicht mehr in ein simples und einfaches Frame/Document/View Modell. Oft genug wird hier noch ein Tool-Window gedockt, dort noch ein Ausgabefenster und hier noch ein nicht modaler Dialog mit Status Infos.

Bringt man nun in einem solchen Fenster Buttons oder Toolbars unter, dann wünscht man sich in manchen Fällen, dass ein Command-Handler ausgelöst werden soll, der in einem anderen Objekt (z.B. dem aktiven View) liegt.
Oder man möchte, dass eben auch in solch einem Fenster ein Command-Handler berücksichtigt wird.
Der Ansatz andere Fenster in das Command Routing einzubauen ist die Funktion CCmdTarget::OnCmdMsg. Diese Methode hat zwei Funktionen.

  1. Sie dient dazu, dass in Menüs (auch Kontextmenüs) und auch in Toolbars Menüpunkte und Buttons ein- und auszuschalten. (ON_UPDATE_COMMAND Handler)
  2. Sie leitet die eigentliche WM_COMMAND Nachricht zur Ausführung an den entsprechenden zuständigen Handler weiter. (ON_COMMAND Handler).

Zum besseren Verständnis des Command Routings das die MFC als Standard vorsieht empfehle ich als Lektüre TN021. Um abenteuerliche Konstrukte und üble Verbiegungen der guten Vorgaben in der MFC zu vermeiden sollten die Grundlagen des Routings in Fleisch und Blut übergegangen sein.
Und dann ist es an sich nicht schwer, Anpassungen vorzunehmen, die es wirklich einfach machen auch andere Fenster in das eigene Routing aufzunehmen ohne die MFC zu verbiegen.

Nun zum Eingemachten:
Will man also Handler in anderen assoziierten Fenstern nutzen, dann muss man diese Fenster in die eigene angepasste OnCmdMsg Routing Struktur einbauen. Der beste Punkt dafür ist in vielen Fällen das hostende CMainFrame. Der Grund ist einfach: Das CMainFrame ist in 99% aller Fälle die erste Adresse, an die ein WM_COMMAND ausgeliefert wird.

Eine entsprechende Funktion kann so aussehen:

BOOL CMainFrame::OnCmdMsg(UINT nID,int nCode,void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo)
{
    // Give a special window the first chance to handle the command
    if (m_pSomeWindow->GetSafeHwnd() &&
        m_pSomeWindow->IsWindowVisible() &&
        m_pSomeWindow->IsActiveInSomeWayOrHasFocus())
    {
        if (m_pSomeWindow->OnCmdMsg(nID,nCode,pExtra,pHandlerInfo))
            return TRUE;
    }

    // Do the standard routing (View, Frame, Application)
    if (__super::OnCmdMsg(nID,nCode,pExtra,pHandlerInfo))
        return TRUE;

    // If not handled up to this point just give another window a chance
    if (m_pSomeOtherWindow->GetSafeHwnd() &&
        m_pSomeOtherWindow->IsWindowVisible() &&
        m_pSomeOtherWindow->IsActiveInSomeWayOrHasFocus())
    {
        if (m_pSomeWindow->OnCmdMsg(nID,nCode,pExtra,pHandlerInfo))
           return TRUE;
    }

    // not handled
    return FALSE;
}

Anmerkungen:

  • Meistens ist es bei diesen Fällen wichtig, dass Routing nicht immer durchzuführen. Z.B. nur dann, wenn das Fenster sichtbar ist, den Fokus hat oder ähnliches (siehe Beispielcode).
  • Weiterhin ist es für Kontextmenüs wichtig als Parent-Fenster ein von CFrameWnd abgeleitetes Fenster zu verwenden. Geschieht dies nicht, dann wird WM_INITMENUPOPUP nicht behandelt, und die Menüpunkte werden nicht enabled bzw. disabled. Wird das obige Verfahren mit OnCmdMsg korrekt angewendet, kann man als Parent Fenster für Kontextmnüs immer AfxGetMainWnd verwenden.
  • Toolbars funktionieren nur dann korrekt wenn hier der korrekte Owner gesetzt wird. Das geschieht mit CToolBar::SetOwner. Auch hier sollte das äußere Frame Window die WM_COMMAND Nachrichten erhalten, die dann über den normalen weiteren (angepassten) Weg geroutet werden.

Siehe auch Command Routing der MFC bei Kontext Menüs mit TrackPopupMenu  

Zwei Tools, die die interne Kommunikation über den TFS noch einfacher machen…

Die Dokumentation, gehört bei uns zu dem Bereich, der nicht direkt mit der Entwicklung verbunden ist.
Ein Teil der Doku wird vorab von den Entwicklern entworfen, aber erhalten letzten Endes den Feinschliff von Anderen. Auch die weitere Pflege und auch die Übersetzungen werden nicht von der Entwicklungsmannschaft durchgeführt.

Eigentlich haben wir nur „everlasting“ Projekte haben, dass heißt unsere Projekte werden immer weiter gepflegt. Das ändert sich oft erst nach so nach 6-10 Jahren wenn sie in eine neues Produkt mit einem kompletten Redesign übergehen.
Das bedeutet auch für die Dokumentation eine immer wiederkehrende Überarbeitung. In der Vergangenheit, haben oft genug Verbesserungen nicht den Weg in die Doku gefunden, weil einfach vergessen wurde eine entsprechende Notiz zu schreiben.
Großes Erstaunen herrschte dann oft, wenn der Vertrieb ein Feature anmahnte, dass die Entwicklung schon längst implementiert hatte.

Mit der Einführung des Team Foundation Server (TFS) und Visual Studio Team Systems 2008 wollte ich auch den Informationsfluss an andere Firmengruppen verbessern, insbesondere zu den Personen, die die Doku schreiben und für die Publikationen der Updates zuständig sind.

Erreicht haben wir das durch zwei ganz einfache Schritte:

  1. Haben wir Visual Studio Team System Web Access 2008 SP1 Power Tool installiert, das als CTP vorliegt. Dadurch kann jeder einfach und simpel von jedem Rechner auf den TFS und die Workitems zugreifen ohne VS installiert zu haben.
    Die entsprechenden User wurden mit „Reader“-Rechten im TFS ausgestattet, sofern sie nicht sowieso schon zum Teil die Rolle eines Testers hatten.
  2. Habe ich das Team Foundation Server Event Subscription Tool installiert.
    Die Events die man über die Menüs in VS-2008 einrichten kann sind doch etwas dürftig.
  3. Mit dem Team Foundation Server Event Subscription Tool  habe ich dann zwei WorkItemChangedEvents eingerichtet, die bei einem Status „Closed“ (für Tasks) oder „Resolved“ (für Bugs), sofort eine Email mit dem entsprechenden Infos des Workitems an eine Emailverteilergruppe sendet.

Jetzt wird jeder „Close“ eines Tasks, bzw. jedes „Resolved“ eines Bugs sofort weiter gemeldet.
Die Mitarbeiter können sich über die entsprechenden Links, die Informationen aus dem Task oder Bug holen und die Dokumentation, Readme’s, Hilfedateien und Übersetzungen anpassen.

PS: Ja man hätte dies auch noch mit eigenen Projekt-Tasks und spezielen Statis regeln können, aber der Weg, so erschien mir einfach, simpel und praktikabel.

PPS: Im dem Team Foundation Server Event Subscription Tool  kann man übrigends noch andere sehr nützliche Benachrichtigungen erzeugen…