Komfortabler Dateimanager mit vielen Funktionen

Visual Studio 2003

Was stört in Visual Studio 2003?

By Sven on 03.02.2005 - 12:20 in Visual Studio 2003 with 1 Kommentar

Obwohl das Visual Studio 2003 nun schon seit 2 Jahren auf dem Markt ist, arbeite ich immer noch mit Visual C++ 6.0. Bisher habe ich mich zweimal an den Umstieg herangewagt, aber jedesmal bin ich reumütig zum VC6 zurückgekehrt. Die Gründe für die Unzufriedenheit liegen nicht im Compiler und im Debugger, denn die sind eine wirkliche Verbesserung. Das Problem ist die IDE selbst, der man anmerkt, dass sich ihre Zielgruppe eher aus .netten Entwicklern zusammensetzt.

Da ich immer wieder verwundert gefragt werde, warum ich immer noch am VC6 hänge, habe ich einmal das aufgelistet, was das effektive Arbeiten im VS2003 enorm behindert:

  • Nach der Bearbeitung eines Dialoges verschwindet das Tool-Fenster nicht wieder automatisch
  • Im VC6 bekam man im Dialogeditor mit <Enter> den Eigenschaftendialog (z.B. für ein Kontrollkästchen) angezeigt und konnte dann den Text ändern. Im VS2003 löscht <Enter> einfach den gesamten Text (auch noch ohne Undo!). Ist mir desöfteren passiert und nervt ungemein!
  • Die Stringtabelle wird nicht sortiert, bei jeder Anzeige muss man dies jedesmal per Hand machen.
  • Beim Einfügen von neuen Strings werden diese ständig hinten angehangen, der VC6 fügt sie an der entsprechenden Stelle ein.
  • Im VC6 wurden in der Stringtabelle alle 16 Einträge eine Linie gezeichnet, das hat die Übersichtlichkeit sehr erhöht.
  • Die Eigenschaften (z.B. für einen Button) sind jetzt alle in einem Eigenschaftenfenster. Im VC6 waren sie logisch gruppiert, daher sucht man im VS2003 jedesmal nach der richtigen Option.
  • In meinen Projekten verwende ich einige Ordner, um die Dateien zu gruppieren. VS2003 sortiert ab Ebene 2 grundsätzlich die Dateien vor die Ordner. So sucht man jedesmal nach einer Datei, weil sie nicht da ist, wo man sie vermutet.
  • Wenn man mehrere Ordner in einem Projekt aufgeklappt hat, dann merkt sich VS2003 den Aufklappstatus (auch nach dem Beenden). Ich bin es gewohnt, dass die Ordner beim nächsten Mal wieder alle geschlossen sind.
  • Mit F4/Umschalt+F4 bewegt man sich nach dem Kompilieren durch die einzelnen Fehler. Im VC6 wird der Cursor automatisch auf die jeweilige Zeile gesetzt, im VS2003 bleibt der Fokus auf der Fehlerliste und man muss nach F4 jedesmal <Enter> drücken, um in das Quellcodefenster zu gelangen.
  • Beim Suchen durch Dateien konnte man sich im VC6 auch mit F4/Umschalt+F4 durch die Ergebnissliste bewegen und die entsprechende Datei wurde mit der Fundstelle geöffnet.
  • Im Dialogeditor werden beim Design nur Tastenkürzel angezeigt, wenn die globale Windows-Option ‘Unterstrichene Buchstaben für Tastaturnavigation ausblenden (mit Alt-Taste einblenden)’ aktiviert ist. Ich habe diese standardmäßig ausgeschaltet, und damit kann man die Tastenkürzel für die einzelnen Elemente nur durch Raten vergeben.
  • Bei den Projektoptionen ist es nicht möglich, die Optionen für mehrere Projekte gleichzeitig zu ändern. So muss man den Dialog jedesmal öffnen/schließen.
  • Der Build-Befehl gilt immer für das Projekt, was gerade im Solution-Explorer bzw. im Quelltextfenster aktiv ist. Im VC6 wählt man ein Startprojekt aus und die Befehle gelten dafür. Allerdings gibts für VS2003 auch ein entsprechendes AddIn (Fast Solution Build), das funktioniert aber nicht immer zu 100%.
  • Wenn man eine Datei zum Bearbeiten aus der Quellcode-Verwaltung auscheckt, dann braucht man im VC6 im Bestätigungsdialog nur <Enter> drücken. Im VS2003 ist da aber ein mehrzeiliges Kommentarfeld und <Enter> geht dann natürlich dahin. Kann man zwar hart in den Ressourcen ändern, stört aber.
  • Für den VC6 nutze ich WndTabs, das die geöffneten Dateien logisch gruppiert und ständig sichtbar hält. Im VS2003 hat man nur eine Leiste und muss ständig mit der Maus hin- und herscrollen. Dazu wechselt <Strg+Tab> anhand der MDI-Reihenfolge und nicht anhand der in der Tableiste angezeigten Reihenfolge.
  • Das wichtigste: Der Class-Wizard fehlt, alles geht nun umständlich über Eigenschaftenfenster. Die überschriebenen Methoden und Windows-Nachrichtenhandler werden nicht mehr geordnet in die Header-Datei geschrieben, im VC6 gab es jeweils dafür bestimmte Sektionen. Meine Projekte gleichen sich in den Hauptklassen und Dateinamen (z.B. MainFrame.cpp). Mir ist es hier öfters passiert, dass der neue Handler in einem anderen Projekt eingefügt wurde, wenn die Datei- und Klassennamen in mehreren Projekten vorkommen. Dazu wird in der Quelltextdatei “#include “.\MainFrame.h” eingefügt, obwohl “#include “MainFrame.h” schon vorkommt.

Leider macht es einen Microsoft immer schwerer, mit dem VC6 weiter zu arbeiten. Mit den LIB-Dateien vom letzten Platform SDK für XP SP2 kann der VC6 nicht mehr umgehen und auch mit den Symboldateien vom SP2 kommt er nicht mehr klar. Mein großer Wunsch ist immer noch, dem VC6 die Fähigkeit verpassen zu können, mit dem neuen PDB-Format des VS2003 umgehen zu können. Dann könnte man einfach den Compiler und Linker austauschen und wäre wieder auf dem neuesten Stand. Aber das wird wohl leider nur ein Wunschtraum bleiben.

In den nächsten Wochen werde ich einmal testen, inwieweit die aktuelle Preview von VS2005 das eine oder andere Problem abstellt oder ob ich auch in Zukunft weiter auf den VC6 zurückgreifen muss.

Benannte Threads

By Sven on 17.01.2005 - 10:46 in Visual Studio 2003, Visual Studio 6

Beim Debuggen von Anwendungen mit mehreren Threads fragt man sich mitunter, in welchem Thread man sich gerade durch den Debugger quält. Im VC6 gibt es ein Thread-Fenster, was aber nur den Namen der Startfunktion des Threads bzw. den der aktuellen Funktion anzeigt. Sobald man mehrere Threads mit den gleichen Funktionen zu debuggen hat, wird die Unterscheidung schwer, welcher Thread gerade aktiv ist:

Normale Threadanzeige

In der MSDN-Library ist beschrieben, wie man durch das Auslösen einer bestimmten Exception die einzelnen Threads benennen kann. Hierzu wird eine Struktur definiert, die u.a. mit dem Namen und der entsprechenden Thread-ID initialisiert wird. Anschließend wird eine Exception ausgelöst. Erfolgt der Aufruf zum Setzen des Namens für den aktuellen Thread, so kann als Thread-ID auch -1 übergeben werden. Zu beachten ist, dass der Name des Threads immer in Ansi (und nicht in Unicode) angegeben wird.

typedef struct tagTHREADNAME_INFO {

    DWORD       dwType;             // Typ (muss 0x1000 sein)
    LPCSTR      pszName;            // Zeiger auf den Threadnamen (ANSI)
    DWORD       dwThreadID;         // Thread-ID (-1 fuer den aufrufenden Thread)
    DWORD       dwFlags;            // Reserviert (muss 0 sein)

} THREADNAME_INFO;

void Lwl_SysSetThreadName(DWORD dwThreadID, LPCSTR pszThreadName)
{
    // Struktur initialisieren
    THREADNAME_INFO info;
    info.dwType = 0x1000;
    info.pszName = pszThreadName;
    info.dwThreadID = dwThreadID;
    info.dwFlags = 0;

    // Exception generieren
    __try
    {
        RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD_PTR*) &info);
    }

    //
    __except(EXCEPTION_CONTINUE_EXECUTION)
    {
    }
}

Beim Aufruf des Thread-Fensters werden die Threads nun mit ihrem Namen angezeigt. Beim VC6 besteht leider eine Limitierung des Namens auf 9 Zeichen, die im aktuellen Visual Studio 2003 aber aufgehoben ist.

Threadanzeige mit angepasstem Namen

Auch in der .netten Welt mag es manchmal hilfreich sein, wenn man mehrere Threads anhand des Namens unterscheiden kann. In der Regel präsentiert sich das Thread-Fenster wie folgt:

Normale Threadanzeige (.NET)

Der Threadname für den Debugger lässt sich direkt über die Eigenschaft Name der Thread-Klasse des .NET-Frameworks festlegen.

Public Class Form1 : Inherits Form
    Class Needle

        ' This method will be called when the thread is started
        Sub Baz()
            Console.WriteLine("Needle Baz is running on another thread")
        End Sub

    End Class

    Public Shared Sub Main()
        Console.WriteLine("Thread Simple Sample")
        Dim oNeedle As New Needle()

        ' Create a Thread object
        Dim oThread As New Thread(AddressOf oNeedle.Baz)

        ' Set the Thread name to "MainThread"
        oThread.Name = "MainThread"

        ' Starting the thread invokes the ThreadStart delegate
        oThread.Start()

    End Sub

End Class

Der Zugriff auf das Thread-Objekt des Prozesses erfolgt über Thread.GetCurrentThread. Nach dem Setzen der Threadnamen sieht das Fenster im Debugger nun so aus:

Threadanzeige mit angepassten Namen (.NET)

Top