Intellisense Hotfix für VS-2005 ist verfügbar

Soeben wurde ein Hotfix veröffentlicht der einige Performance Probleme mit dem Intellisense in Visual-Studio 2005 beheben soll.

Infos über diesen Hotfix gibt es im Visual C++ Team Blog.
Weitere Infos und die Liste der betroffenen Dateien findet man auch in in diesem KB-Artikel 943969

Hier der aktuelle Download Link für die englische Version.
Ob andere Sprachversionen (Deutsch) verfügbar sein werden wurde bereits bei der Produktgruppe intern nachgefragt.

Wichtig ❗ SP1 für VS-2005 muss installiert sein für diesen Hotfix.

Anmerkung: Nutzer von VisualAssist von http://www.wholetomato.com  bemerken von diesen Problemen kaum etwas.

VS-Tipps & Tricks: Anpassen von Kontextmenüs

Manchmal hätte man gerne eigene Befehle in einem Kontextmenü, oder man möchte evtl. einen speziellen Befehl aus einem Kontextmenü verschieben oder entfernen. Dies geht, allerdings nur mit einem kleinen Trick, denn die Kontextmenüs befinden sich normalerweise ja nicht in der Anzeige:

  • Mit der rechten Maustaste klickt man auf irgend einen Toolbar.
  • Man wählt Customize aus dem Kontextmenü.
  • Im Karteireiter Toolbars wählt man Context Menus aus. Es erscheint ein neuer Toolbar mit allen Kontextmenüs.
  • Nun kann man das entsprechende Menü durch anklicken öffnen (also z.B. Project and Solution Context Menu).
  • Nun kann man einfach die entsprechenden Anpassungen durchführen. 

Wenn man den Haken in dem Customize Dialog bei Context Menus drin lässt werden automatisch die Kontextmenüs angezeigt, wenn man den Customize Dialog öffnet.

Microsoft und sein Bekenntnis zu C++

Eigentlich ist es ja schön, dass Microsoft sich endlich mal zu etwas mehr durchgerungen hat, als nur partieller Kosmetik im Bereich der nativen Softwareentwicklung mit C++.

Nach meiner Meinung kommt das ganze allerdings um Jahre zu spät! Ich hätte spätestens mit VS-2005 erwartet, dass Microsoft den verbalen Bekenntnissen, dass es weiterhin auch native Entwicklung mit C++ geben wird, auch Taten folgen lässt.

Microsoft hat sich mit der einfältigen Umbenennung von Visual Studio in ein VS.NET 2002 keinen Gefallen getan. Die Verunsicherung unter den vielen C++ Entwicklern durfte ich damals in Neuss beim großen Launch des VS.NET 2002 als ATE (Ask the Expert) am eigenen Leib erfahren.

Geändert hat sich nicht viel in den Jahren danach. Die Verunsicherung ist geblieben und Vertrauen wurde keines zurück gewonnen. Ein vorbehaltloses Prüfen der neuen Compiler und Visual Studio Versionen hat in vielen Firmen nicht stattgefunden. Die Änderungen waren gravierend sicherlich, wenn man den Compiler und die IDE von VC++ 6.0 mit der von VC++ 2005 vergleicht, da liegen einfach Welten dazwischen.

Irgendwie hatten zu viele Firmen und Entwickler das Gefühl „nun stirbt C++“, „jetzt  ist die vielfach totgesagte MFC wirklich tot“. Zuversicht in die bestehende Technologie zu setzen war einfach nicht da.

Das Micrsoft natives C++ nicht abschreibt wurde zwar ab und zu gesagt, aber das hörte sich eher wie Pfeifen im dunklen Wald an. Die ganze Situation machte es C# und .NET Entwicklern leicht auf C++ Entwicklern herumzuhaken und sie zutiefst zu bemitleiden (natürlich immer mit einem hämischen Grinsen). Und teilweise geschah dies sogar aus den eigenen Reihen von Microsoft. Hatte man auf einmal mit C++ keine zukunftsweisende Technologie mehr?
Die Tracks bei Kongressen füllten sich mit .NET Beiträgen. Und was sich in C++ getan hat (und es hat sich noch einiges getan) wurde kaum veröffentlicht oder nicht gehört. Auch was Dokumentationen betrifft, hat sich die C++ Gruppe nicht mit Ruhm bekleckert.

Noch „besser“ wurde es als schwachsinnige Aussagen die Runde machte, dass die nächsten Betriebssysteme nur noch .NET erlauben würden, und demnächst alles, bis zum Treiber mit .NET entwicklet würden. C++ braucht man nicht mehr.
Schaut man sich heute an, wieviel .NET in Vista und Windows 2008 Server steckt, dann merkt man, wie blödsinnig diese Annahmen waren und das es kaum Ersatz gibt für native Entwicklung in C++.
Fakt ist: bis heute wurde keine wirklich weitreichende und wichtige Schnittstelle in Win32 geschaffen die nur aus der managed Welt anzusprechen wäre. Und selbst wenn, so ist die Brücke aus C++ in die managed Welt ist kurz…

Warum wurden keine Walkthroughs und Dokumentationen geliefert , die einem bei der Umstellung von Code der unter VC6 entwickelt wurde auf VC++2003/2005 erklären und leichter machen? Walkthroughs, die gezielt auf die speziellen Warnungen eingehen, die einem um die Ohren fliegen, oder konstruktiv bei Problemen mit dem Umstieg helfen, finden wir heute höchstens in der Community entsprechende Beiträge.

Wäre es zu viel verlangt gewesen, zum Beispiel sofort bei der Umstellung eines VC6 Projektes bestimmte Projekteinstellungen so zu gewährleisten, dass möglichst wenig Warnungen entstehen, aber der Programmierer auf die Änderungen, die seinen Code sicherer und kompatibler machen, klar hinweisen?

Es ist verschlafen worden! Ja es wurde Jahre lang geschlafen. MFCnext ist schön, nett. Das TR1 kommt ist prima. Ich frage mich aber ob es wirklich genügt das verloren gegangene Vertrauen wieder zurück zu gewinnen?

Just my 2 cents…

MFC Updates for Visual Studio 2008 and Beyond: MFCnext

Was ich hier schreibe ist an sich viel zu viel für einen einzigen Blog Artikel, deshalb behalte ich mir hier nur eine kurze Zusammenfassung vor. Kommentieren und diskutieren werde ich dies noch in den nächsten Wochen.

Was ❓
Heute in den C++ Sessions der TechEd 2007 in Barcelona wurde ein Geheimnis gelüftet. Das war uns MVPs schon etwas länger bekannt aber leider war es uns bis heute durch NDA (non-disclosure aggreement) untersagt davon zu berichten.
Microsoft wird der MFC einen neuen gewaltigen Schub geben und seit Jahren die ersten wirklich gravierenden Erweiterungen verpassen. Das Ganze wird unter dem Namen MFCnext laufen.

In diesem Bog will ich nur summarisch aufzählen was alles an Neuem kommen wird:

  • Office 2007 UI Stil. Ribbons und alles was dazu gehört
  • Tabbed MDI
  • Integration neuer Controls (Advanced button, Shell tree and list, Mask edit, Property list)
  • Erweiterter Applikations Assistent
  • Rückwärts kompatibel bis Windows 2000
  • Docking wie wir es von Visual Studio her kennen
  • Visual Styles (Skins)
  • Die Standard Template Library wird um TR1 erweitert (tr1::shared_ptr, tr1:: mem_fn, tr1:: bind, tr1::regex, tr1::tuple, tr1::array, unordered containers hash-based, tr1::type_traits)
  • Microsoft bekennt sich klar und offen zur weiteren Entwicklung und Unterstützung der nativen C++ Programmierung.
  • und vieles andere mehr…

Die MFC wird sich in Anzahl der Klassen und Größe verdoppeln.

Wann kommt das ❓
Das Ganze wird bereits im März 2008 nachgeliefert, in einem Update für VS-2008. Ein Release Kandidat (RC) wird bereits im Dezember 2007 zur Verfügung stehen.  So die bisherige Planung.

Die MFC ist tot… lange lebe MFCnext 😀

Weitere Infos:
Auch in Deutschland bei dieser Veranstaltung werden die Vortargenden aus Barcelona zu sehen und hören sein:
München 15.11.2007: Visual C++ 2008 und danach, Ask the Experts

Noch mehr Infos gibt es auch in dem Blog von Jochen Kalmbach, der live aus Barcelona von der TechEd 2007 berichtet.

München 15.11.2007: Visual C++ 2008 und danach, Ask the Experts

Visual C++ 2008 und danach, Ask the Experts

Das ganze findet am 15.11.07 im Hilton Park Hotel München statt. Die Veranstaltung beginnt um 18:00 Uhr. Die Anschrift vom Veranstaltungsort ist
Hilton Park Hotel
Am Tucherpark 7
80538 München

Eine Veranstaltung zu der ich gerne gehen würde. Aber ich habe leider keine Zeit und die Strecke ist zu weit.
Die Redner haben was zu sagen, denn Sie kommen direkt von der TechEd Barcelona und dort haben sie die Decke über einiges neues in der Zukunft von nativem C++ gelüftet.

Ich kann nur jedem raten dieses Event zu besuchen, sofern er in der Nähe ist oder es erreichen kann. Die Alternative ist natürlich die TechED 2007 in Barcelona…

Ich werde ab dem 07.11.2007 auch dazu bloggen, denn dann bindet mich auch kein „Schweigegelübde“ mehr. 😉

Quote aus der Ankündigung:
Es wird Brezeln und Getränke geben und das Beste an der Sache ist:. Es ist absolut kostenfrei!

Registrieren kann man sich per Email. In die Registrierung bitte unbedingt Anschrift, Telefonnummer und primäre Email Adresse eintragen.

Wichtig: Der Veranstaltungsort ist auf 50 Plätze limitiert. First come, first serve!

Noch gilt: Noch Plätze frei! Visual C++ 2008 and Beyond

VS-Tipps & Tricks: Synchronisation und Navigation mit dem Solution Explorer

Die Navigation über den Solution Explorer ist der übliche weg andere Sourcedateien zu öffnen. Außer man nutzt VA-X da geht noch mehr 😉 

Der Solution Explorer wird über die Hotkeys Strg+Alt+L, geöffnet oder man verwendet das View Menü. Bei mir ist der Solution Explorer (außer im Debug Modus), am recten Rand gedockt, teilt sich das Fenster aber mit dem Resource View (Strg+Umschalt+E) und Class View (Strg+Umschalt+C).

Unter dem Menü Tools -> Options -> Projects and Solution findest man die Checkbox „Track item in Solutiuon Explorer„. Mit dieser Option wird die aktuelle Datei, die man gerade bearbeitet auch im Solution Explorer angezeigt und selektiert. Da ich die Dateien in Unterordnern der Solution auch nach Themen gruppiere kann man relativ schnell thematisch nahe Datein öffnen.  Dies kommt meine Arbeitsweise sehr nahe und ich verwende diese Einstellung immer.

Dieses Verhalten lässt sich auch direkt über den Befehl View.TrackActivityinSolutionExplorer ein- bzw. ausschalten. Dieser Befehl hat allerdings keinen Hotkey.  Das geht natürlich auch schnell über das Command Window (Strg+Alt+A)

PS: Bzgl. Unterordner. Ich verwende meistens nur Ordner im Solution Explorer, keine Ordner in der Verzeichnisstruktur.

Mal ganz schnell sich selbst reingelegt mit Excel und CRecordset::optimizeBulkAdd

Um eine größere Datenmenge in Excel über eine ODBC Verbindung zu erzeugen habe ich einen entsprechenden Recordset geöffnet und Daten massenweise hineingepumpt. Die Tabelle (das Worksheet), das erzeugt wurde enthielt Spalten mit Text-, Numerischen-, und Zeitdaten. Einige der Daten sollten wurden mit NULL Werten erzeugt werden.

Entsprechend den Tipps in der Doku habe ich die zusätzliche Option CRecordset::optimizeBulkAdd zu CRecordset::appendOnly verwendet um das zu beschleunigen.

m_recordSet.Open(CRecordset::snapshot,
                NULL,
                CRecordset::appendOnly|CRecordset::optimizeBulkAdd);

Laut der Doku sollte das erste Statement entsprechend für alle weiteren Operationen, den Dirty-Status setzten. Fein (dachte ich), alle Daten des Recordsets werden gesetzt, entweder auf den entsprechenden Wert oder NULL.

Alle Tests waren „erstmal“ positiv. Die Daten wurden in guter Geschwindigkeit erzeugt.
Leider stellten Kunden dann fest (allerdings Wochen später), dass unter bestimmten Umständen ganze Spalten leer waren. Sobald in der ersten Zeile einmal in einer Spalte NULL ausgegeben wurde, dann wurde auch in allen folgenden Spalten kein Wert eingetragen. Das Ganze, obwohl die Daten korrekt gebunden und als dirty markiert wurden. An das Open Statement dachte ich nicht…

Nach langem Testen nahm ich schon an, einen Bug in dem ODBC Treiber gefunden zu haben. Stutzig wurde ich aber, dass alles prima klappte, wenn ich pure SQL INSERT-Statements mit ExecuteSQL  direkt auslöste, ohne den Recordset zu bemühen. Was nun?

Relativ ratlos wollte ich schon einen Supportfall bei Microsoft öffnen, bis ich den Code noch einmal Schritt für Schritt durchsah und wieder über das das Open Statement stolperte.

Bingo: Sobald ich dieses Flag entfernte arbeitete alles korrekt. Nach meinem Verständnis müsste auch ein NULL Wert ein Wert sei, der gültig ist, solange ich alle Spalten beim ersten INSERT/AddNew angebe. Ich nahm an, dass auch ein Einfügen eines NULL Wertes ein „Dirty“ für die entsprechende Spalte auslöst. Das ist aber nicht so.

Wird – zumindest beim ODBC Treiber für Excel – in dem ersten INSERT eines Datensatzes ein NULL Wert ausgegeben , dann werden auch keine Daten für alle nachfolgenden Zeilen eingefügt. Und das NULL eingefügt wird, geschieht ganz schnell, wenn z.B. ein leeres Textfeld (Länge 0) ausgegeben werden soll. Ob dies auch für Access oder andere Treiber gilt habe ich noch nicht ausprobiert.

Schnelle binäre Algorithmen

Manchmal tauchen in Foren richtig nette Sachen, die einen in Erstaunen setzen, wie schnell und einfach manches zu lösen ist. (siehe Thread)
Zwei interessante Fragen, die mich auch schon öfter beschäftigt haben sind hier mal erwähnt und als C++ Code wiedergegeben. Bisher habe ich diese immer mit einer entsprechenden Schleife und Shift-Operatoren gelöst.

1. Wie kann man schnell prüfen ob ein Integer eine 2er Potenz ist?

Der Algorithmus ist so verblüffend einfach, dass man sich fragen muss, warum man noch nicht von selbst drauf gekommen ist:

bool IsPowerOf2(int n) 
{ 
 return (n & (n - 1))==0; 
}

Tricky: Wenn mehr als zwei Bits gesetzt sind, bleibt bei der gegebenen Arithmetik mindestens das höchste Bit stehen.

❗ Nach diesem Algorithmus ist 0 übrigens auch eine Power of 2!

2. Wie findet man die nächste 2er Potenz einer gegebenen Zahl?

Diese Frage stellt sich für mich immer wieder, wenn ich binäre Suchen durchführe.
Auch hier gibt es eine statische Lösung, die ich hier mal wiedergebe und die sowohl für 32bit als auch für 64bit funktioniert und direkt in entsprechende Assembler Befehle umgesetzt wird.
Der Code vermeidet einen 32bit shift, da das Ergebnis in einem 32bit C++ Compiler undefiniert ist (Warning C4293).

int GetNextPowerOf2(int n) 
{ 
 // Code works for 32bit and 64bit 
 ­­­­-­-n;    
 n |= n >> 1; 
 n |= n >> 2; 
 n |= n >> 4; 
 n |= n >> 8; 
 n |= n >> 16; // Sufficient for 32bit 
 n |= n >> 16; // for a 64bit System we need a new 32bit shift (n>>32) 
 n |= n >> 16; // but this operation is undefined on a 32bit system 
               // so we use 2 16bit shifts. (C4293) 
 return n+1; 
}

Oft genug wird das höchste gesetzte Bit gesucht. In diesem Fall einfach den Startwert oder das Ergebnis um eine Bitposition shiften.

Tricky: Das höchste Bit wird nach der Subtraktion einfach auf alle niederen Bits übertragen.

❗ Auch hier ist das Verhalten bei 0 eigentümlich. Die nächste 2er Potenz auf 0 ist mit diesem Algorithmus 0!

Die entsprechenden Algorithmen sind hier auf dieser Seite beschrieben:
http://en.wikipedia.org/wiki/Power_of_two#Fast_algorithm_to_check_if_a_number_is_a_power_of_two

Google Code Search…

Irgendwie ist das total an mir vorbeigegangen: Google Code Search.
Ich glaube ich gehe zu wenig auf Entdeckungsreise im Netz ;)…

Genial einfach nach Code suchen! Wirklich beeindruckend, vor allem auch durch die Nutzungsmöglichkeit von Regular Expressions.
Mich begeistert vor allem, die Möglichkeit den Sourcecode direkt einsehen zu können. Auch die Nachbardateien aus der Projektstruktur zu sind nur einen Mausklick weit entfernt. Man kann ganze Projekte zu studieren ob sie einem bei einem Problem helfen können ohne das man sie gleich herunter lädt und entpacken muss.

Einzig die Reihenfolge (Ranking) ist irgendwie suboptimal. Man muss schon einiges an Code ansehen oder entsprechend viel Stichworte angeben um die vielen Hits effektiv zu reduzieren.

Warum eigentlich CallWindowProc aufrufen, wenn man einen Zeiger auf die alte WndProc hat?

Wenn man mit GetWindowLong(Ptr) und GWL_WNDPROC die Adresse einer Fenster Prozedur ermittelt hat, warum muss man eigentlich CallWindowProc aufrufen und nutzt nicht direkt den Zeiger? Geht das denn überhaupt? 😕

Nein es geht nicht und man sollte es gar nicht versuchen ❗

In Win16 ging das noch. Aber das was durch GWL_WNDPROC geliefert wird ist seit Einführung von Win32 nicht unbedingt ein Funktionszeiger mehr.  Oft ist es eine Struktur.
Warum? Das ganze wurde gemacht um Unicode Kompatibilität zu erreichen.
Fenster sind nicht nur Thread afin, nein, sie sind auch Unicode bzw. MBCS afin (wenn man das so sagen kann). Je nachdem ob es eben mit CreateWindow(Ex)A oder CreateWindow(Ex)W erzeugt wurde.

Wenn also ein Unicode Fenster von einer Nicht-Unicode Fenster-Prozedur gesubclassed wird (oder umgekehrt), dann muss hier eine Konvertierung stattfinden. Seit dem wir Themed Style mit XP bekommen haben, tritt dies übrigens häufig auf. Denn die Fenster im XP-Stil werden meistens intern als Unicode Fenster verwaltet oder angelegt.
Für diese Konvertierungsarbeit wird eine Struktur angelegt und diese Struktur wird dann in GWL_WNDPROC eingetragen. Dann haben wir eben keinen Funktionszeiger mehr, sondern eher ein Handle. Und nur CallWindowProc weiß wie man eben damit umzugehen hat…

Details hier in dem Artikel Safe Subclassing in Win32