BUG: VS-2010 vergisst regelmäßig die Tastaturkürzel für Extensions und Addins

 Toll ist, das es für VS-2010 wirklich viele nützliche Extensions gibt. Das heißt aber auch, dass man des öfteren mal ein Update einer solchen Extension installiert. Und jetzt wird es ärgerlich. Jedesmal wenn man ein Update einer Extension installiert dann sind alle Tastaturzuordnungen auf ALLE Extensions und Addins futsch.

Mich hat das so genervt, dass ich einen entsprechenden Bugreport eingereicht habe:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=621929

Wie man lesen kann: „A known issue!“. Na dann hoffen wir mal auf einen Hotfix… 😉 (also bitte gebt Eure Votes ab), wie immer stirbt die Hoffnung zuletzt..

Ich kann jedem nur raten, die eigenen Einstellungen des Visual-Studios über die Import/Export Funktionen regelmäßig zu sichern. Dann kann man bei Bedarf auch die Tastaturmappings alleine wieder zurückspielen…

TFS-2010 zeigt nicht alle Historien Einträge für Dateien

Ein Kunde meldete ein Problem und ich entdeckte einen Fehler. Ich wollte wissen wann dieser Fehler in die Software kam oder ob er evtl. schon immer vorhanden war. Also bemühte ich die Historie des Team Foundation Servers. Allerdings erschien mir diese nicht komplett.

Vor ca. 2 Jahren habe ich einige Projekte umstrukturiert und dabei auch Verzeichnisse verschoben. Und genau bis zu diesem Punkt konnte ich die Historie einsehen.

Nach ein bisschen Recherche im Netz fand ich diesen Report auf Connect:
https://connect.microsoft.com/VisualStudio/feedback/details/538032/tfs-2010-does-not-display-history-for-a-renamed-folder
Und in dieser Meldung fand ich dann auch den entsprechenden Workarround.

Erst der Befehl:
tf.exe history  „C:\Dev\Root\Projects\the file name I am looking for.cpp“   /itemmode
zeigt die komplette Historie:

Frag mich bitte keiner warum das so sein muss 😉 Slotmode / Itemmode? Brauchen wir das wirklich?

In VS-2010 SP1 wird sich einiges bzgl. des Help-Viewers tun…

Das sich doch relativ viele Entwickler (wie auch ich hier in meinem Blog) negativ über die MSDN-Hilfe Integration in VS-2010 geäußert haben hat scheinbar Spuren hinterlassen, wie in Jeff Brattens Blog zu lesen ist:

http://thirdblogfromthesun.com/2010/10/the-story-of-help-in-visual-studio-2010/
http://thirdblogfromthesun.com/2010/10/the-story-of-help-in-visual-studio-2010-part-2/
http://thirdblogfromthesun.com/2010/10/the-story-of-help-in-visual-studio-2010-part-3/

Besonders Teil 3 mit dem Ausblick auf SP1 ist interssant. Ich zitiere direkt aus Part 3:

New Features in Visual Studio SP1

We’ve made three major changes to the Help Viewer in SP1. First, we’ve abandoned the browser-as-local-help-viewer and implemented a simple client application for offline help. The help window is no longer lost in the set of browser tabs you have open and the help application icon can be easily located in the taskbar. F1 Help re-uses the currently active tab instead of creating a parade of open tabs that must be manually managed. The help application can be sized and placed anywhere on your desktop and retains its size and placement across sessions. The navigation panel width is resizable and it can be placed to the right or the left of the content.

Second, with the flexibility we gain from building a client application, we’ve re-introduced many of the productivity/efficiency features found in Document Explorer. The viewer features four navigation tabs: a fully-expandable table of contents that can be explored without reloading the current topic, a keyword index, a Favorites and History tab, and a search results pane. The search results pane allows you to refine your search queries without losing your current topic context. In addition, context menus and shortcut keys allow you to access features quickly without excessive need for a mouse.

TFS Unshelve mit Merge

Ich und meine Kollegen benutzen gerne Shelvesets um uns Code gegenseitig zuschieben zu können, oder Testcode auszuprobieren.

Problematisch ist allerdings, dass die Dateien alle nicht ausgechecked sein dürfen, die man mit dem Shelveset laden möchte. Doof! Ein Merge ist mit VS-2010 nicht möglich, wenn man ein Shelveset lädt.

Glücklicherweise gibt es aber die Team Foundation Server Powertools. Und in diesem genialen Tool-Paket ist auch netterweise der Befehl: tfpt unshelve verfügbar! Und damit kann man in gewohnterweise, ein Shelveset in die eigenen bereits bearbeiteten Source hinein-mergen.

Erstaunen: CMemDC ist Bestandteil der MFC!

Wer Double Buffering benötigt und die MFC nutzt, der kennt auch CMemDC. Vermutlich eine der meist genutzten und kopierten Klassen, die auf CodeProject und CodeGuru vorgestellt wurden.
http://www.codeproject.com/KB/GDI/flickerfree.aspx
http://www.codeguru.com/cpp/misc/misc/flickerfreedrawing/article.php/c389/Flicker-free-drawing-using-memory-DC.htm

Ich habe meine Erweiterung hier im Blog vorgestellt und die liegt normalerweise in einem separaten Namespace, wie alle meine Tool-Klassen.

Nicht schlecht staunte ich, als ich keinen Compilerfehler bekam obwohl ich CMemDC nutzte aber keinen Namespace angab. Siehe da: CMemDC hat in einer eigenen Implementierung den Weg in die MFC gefunden. Man findet sie in:
C:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include\afxcontrolbarutil.h

Im Großen und Ganzen ist es die bekannte Standard-Implementierung, allerdings verfügt diese CMemDC Version auch Code, der auf Windows Vista und Windows 7, die fest im Betriebssystem verankerten Funktionen nutzt: BeginBufferedPaint, EndBufferedPaint
Siehe http://msdn.microsoft.com/en-us/library/bb773178(VS.85).aspx
Diese Funktionen werden innerhalb des Themeings von Windows Vista und Windows 7 verwendet und in dieser Funktionsgruppe ist auch Alphablending direkt verankert. (BufferedPaintSetAlpha). Ich vermute sogar, dass diese integrierten Klassen effektiver arbeiten, als die eigenen Klassen (ein Test steht noch aus), denn Windows weiß intern natürlich viel besser was wie zu puffern und zu zeichnen ist, als wir, wenn WM_PAINT aufgerufen wird.

Vielleicht ein guter Grund, die eigene CMemDC Klasse auch auf Vista/Windows 7 Funktionen zu erweitern oder die integrierte Klasse in der MFC zu verwenden.

Tipp: Übrigens hat die MFC CMemDC Klasse einen statischen Member, der es auf einfache Weise erlaubt das Double-Buffering abzuschalten (CMemDC:: m_bUseMemoryDC), dass ist besonders interessant beim Debuggen von grafischen Operationen, deren Ergebnisse man auch gleich sehen will, allerdings wird dieser Member nicht benutzt wenn das interne Windows Double-Buffering genutzt werden kann, schade eigentlich.

PS: Aber eigentlich muss man sich auch die Frage stellen, warum die Entwickler genau diesen Klassennamen verwendet haben, denn er provoziert ja auch direkt den Konflikt mit existierendem Code.

Breaking-Change: In VC-2010 in der STL wird 0 bzw. NULL nicht mehr gültiger Zeiger akzeptiert

Die STL Implementierung wurde klar hinsichtlich „perfect forwarding“ überarbeitet (Siehe C++0x). Allerdings sind dabei auch einige Sachen reingerutscht die dazu führen, dass sich mancher Code nicht mehr kompilieren lässt.

So führen die nachfolgenen Zeilen zu einem Compiler Fehler:

std::pair<void*,void*> p(0, NULL);
// fails with error C2440: 'initializing' : cannot convert from 'int' to 'void *'

Gleiches negatives Ergebnis erhält man, wenn man die folgenden Zeile kompiliert:

vector<void*> v; 
v.insert(v.begin(),NULL);

Der Hintergrund wird hier in dieser Connect Meldung beleuchtet:
https://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair?wa=wsignin1.0

Das Problem ist, das 0 (NULL) sich zwar brav in einen Zeiger umwandeln lässt. 0 (NULL) bleibt aber deshalb dennoch vom Typ her ein int ist wird nicht zu einem Zeiger. Die typensichere Implementierung in der STL führt nun dazu, dass 0 (NULL) nicht als void* akzeptiert wird.

Einzige Lösung und auch mein Rat:
Man verwendet nicht mehr 0 oder NULL, wenn ein NULL-Zeiger gemeint ist, sondern nullptr
Wer Code kompatibel zu VC-2008 und früher halten muss, kann ja in seinen Headern den folgende Definition einführen:

#if  _MSC_VER<1600
const int nullptr = 0;
#endif

Mehr zu perfect forwarding liest man hier:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
http://thbecker.net/articles/rvalue_references/section_07.html

Wie auch aus dem Connect Artikel zu entnehmen ist kann man damit rechnen, dass sich in VC11 alles wieder etwas zurückentwickeln wird. D.h. std::pair und auch die insert Befehle der Container sollen wirde brav 0 aktzeptieren können, wenn Zeiger gemeint sind. Gleiches bekam ich auch über meine Kontakte zur Produktgruppe zu höhren. Aber was VC11 betrifft ist alles sowieso nur Zukunftsmusik und alles noch im dichten Nebel und was wirklich Realität wird  muss man dann wohl erst mal sehen 😉

Nachtrag vom 09.09.2010:
Dravere hat in einem Kommentar auf eine geniale Implementierung für nullptr hingewiesen:
http://www.c-plusplus.de/forum/viewtopic-var-t-is-220511.html
Die ist weitaus besser als meine Definition als const int.

const class
{
public:
  template<class T> operator T*() const {return 0;}
  template<class C, class T> operator T C::*() const {return 0;}
private:
  void operator&() const;
}
nullptr = {};

Bug: VC-2010 MFC CFormView zeichnet Buttons beim Rollen falsch, es erscheinen schwarze Blöcke

In der MFC 10.0 hat sich ein Bug eingeschlichen, der sich unter Windows Vista und Windows 7  bemerkbar macht. Unter Windows XP tritt der Fehler nicht auf. Das Problem tritt in jedem Stil auf, der DWM verwendet. D.h. nicht wenn Windows klassisch ausgewählt wird.

Wenn auf einen CFormView mehrere Buttons liegen und der CFormView gerollt wird, dann kommt es unter Umständen zu Fehlern beim Neuzeichnen von Buttons. Dies schließt alle Button-Formen ein: Check-Buttons, Radio-Buttons und normale Buttons.

Das Ganze sieht nach dem Rollen in etwa so aus:

Der Text einiger Buttons erscheint nach dem Rollen als schwarze Blöcke. Es kann auch vorkommen, dass nur Teile der Buttons falsch gezeichnet werden.

Um das Problem gezielt nachzuvollziehen habe ich ein kleines Sample gebaut. Man kann durch zwei Schalter den CScrollView gezielt nach oben oder unten Rollen. Beim Rollen nach unten und bei bestimmten Fenstergrößen tritt dann der Fehler auf. Ich habe das Main-Window entsprechend beim Start in der Größe angepasst.

Das Problem liegt in einer Implementierung von WM_PRINTCLIENT in CScrollView (CScrollView::OnPrintClient), die ein Double-Buffering verwendet, dass entweder falsch ist oder sich eben mit der Standardimplementierung eines Dialoges beißt. Auf den ersten und zweiten Blick konnte ich in der Implementierung selbst keinen Fehler sehen. Deshalb vermute ich, dass sich dieses Double-Buffering mit dem auch vorhandenen Double-Buffering in den Standardimplementierungen der Dialogklasse beißt bzw. nicht korrekt berücksichtigt, dass auch Child-Windows neu gezeichnet werden müssen.

Die Lösung ist entsprechend einfach:

  • Man fügt einfach einen Handler für WM_PRINTCLIENT in seiner von CFormView abgeleiteten Klasse ein.
  • Dieser Handler ruft dann nicht die Implementierung der Basisklasse CFormView auf, sondern die Implementierung in CView (CView::OnPrintClient).
...
ON_MESSAGE(WM_PRINTCLIENT,&CScrollDialogMFCView::OnPrintClient)
...

LRESULT CScrollDialogMFCView::OnPrintClient( WPARAM wp, LPARAM lp )
{
  // Bypass the CScrollView::OnPrintClient implementation
  return CView::OnPrintClient(wp,lp);
}

Dieser Fehler ist in keiner der vorhergehenden MFC Versionen vorhanden (auch nicht in MFCNext), weil einfach kein entsprechender Handler vorhanden war..

Es stellt sich wohl bei einigen jetzt die Frage warum dieser Handler eingebaut wurde. Auch die Antwort ist einfach:
Seit Windows Vista wird stark von AnimateWindow Gebrauch gemacht und auch DWM intern scheint des öfteren WM_PRINT/WM_PRINTCLIENT zu verwenden. Entsprechend haben fast alle Klassen in der MFC entsprechende Handler ergänzt bekommen.

Das Sample kann man hier herunterladen: ScrollDialogMFC – VS-2010.
Ich habe in der stdafx.h einen define FIX_CSCROLLVIEW_PROBLEM eingebaut mit dem man den Fix einfach aktivieren und deaktivieren kann.

Bug: CSimpleMap und CSimpleArray führen bei Verwendung von SetAtIndex zu einem Leak

Wieder einmal ein Bug, der seit VC-2005 bekannt ist und in meinen Augen unmöglich als by design abgetan werden darf.

Das Problem ist simpel, wenn man die Funktion SetAtIndex in den Klassen CSimpleMap und CSimpleArray angewendet wird, dann wird für das bestehende Element in der Map oder im Array kein Destruktor aufgerufen. D.h. eine CSimpleMap<CString,…> bzw. ein CSimpleArray<CString> führt mit der Verwendung von SetAtIndex sofort zu Leaks.

Tückisch in reinen ATL Projekten, weil hier der CRT Heap nicht benutzt wird und die Speicherleaks durch die CRT nicht entdeckt werden, weil der Win32 Heap zum Einsatz kommt.

Hier ist der Bug zu finden, inkl. der in meinen Augen korrekten Implementierung:
https://connect.microsoft.com/VisualStudio/feedback/details/298324/csimplemap-setatindex-do-not-call-a-ditructor

Für mich ist besonders diese Antwort äußerst fragwürdig:

CSimpleMap wasn’t really designed to work for types that needed destruction. The docs state it is limited and you should use CAtlMap instead.

Dieser Satz und dieser Hinweis ist in keiner Doku zu finden. Die Doku liest sich ganz anders:
http://msdn.microsoft.com/en-us/library/d1xc3983(VS.100).aspx

CSimpleMap provides support for a simple mapping array of any given type T, managing an unordered array of key elements and their associated values.

Man kann nur raten SetAtIndex nicht zu verwenden, sondern nur SetAt oder den operator[] ❗

MFC-Next 9.0 > MFC 10.0 denn CMFCRibbonPanel::EnableLaunchButton gibt es nicht mehr

Sehr erfreut waren viele C++ Entwickler darüber das es mit der MFC in VC-2008 weiter ging und MFC-Next veröffentlicht wurde. Das ganze wurde dann fest in VS-2008 SP1 integriert. Normalerweise sind wir es gewohnt, dass zur MFC nur Dinge hinzukommen und nichts wegfällt.

Für die MFC 10.0 aus VS-2010 gilt das diesmal nicht: MFC 10.0 < MFC-Next 9.0!

Irgendwie hat es CMFCRibbonPanel::EnableLaunchButton nicht in die MFC 10.0 geschafft, obwohl die Funktion vollständig in der MFC-Next 9.0 implementiert war. Das soll mal einer verstehen 😕 ich jedenfalls nicht!

Diese Funktion sorgt für den kleinen netten Schalter in einem Panel:

Erstaunlicherweise gibt es diese Funktion nun nicht mehr! Wer also 100% Office-kompatible Anwendungen schreiben will ist hier schon mal aufgeschmissen, wenn er das mit MFC 10.0 machen will.
Im Header finden wir diese Funktion noch mit einem #ifdef auskommentiert. Allerdings nützt es nichts diesen #define zu setzen, denn es gibt keine Implementierung und entsprechend keinen Code in der DLL/Library. Ja und in der MFC Doku finden wir die Funktion auch noch.

Und auch dieses Problem war noch in der Beta-Phase bekannt und wurde abgebügelt, wie man in den nachfolgenden Links lesen kann.
http://social.msdn.microsoft.com/Forums/en/vcmfcatl/thread/29ad2859-6341-4ffb-85c2-f5f056a6ca48
https://connect.microsoft.com/VisualStudioJapan/feedback/details/533876/cmfcribbonpanel-enablelaunchbutton?wa=wsignin1.0
Wem es möglich ist, sollte hier bitte Abstimmen und diesen Bug als wichtig kennzeichnen!

Langsam frage ich mich ob es nicht gescheiter gewesen wäre bei MFC-Next 9.0 zu bleiben und mit VS-2008 weiter zu arbeiten.
Tja und so hat die BCG-Library in Verbindung mit VS-2010 auch eine Daseinsberechtigung. Die kann diesen LaunchButton natürlich darstellen.

PS: Auf Nachfrage bei Microsoft bekam ich eine Antwort aber keinerlei Begründung. Jetzt habe ich eine Support-Anfrage dies bzgl. laufen, allerdings mit wenig Hoffnung. 🙁

PPS: (Nachtrag 01.09.2010) Auch der Microsoft Support kann mir dies bzgl. keine Antwort geben aufgrund eines offenen Rechtsstreits. Siehe auch Kommentar von Samsa.

Achtung: Alle Visual Studio 2010 Express Editionen müssen registriert werden

In den Express Editionen für Visual Studio 2005 und 2008 war es nur nötig die Versionen zu registrieren, die mit dem Online Installer installiert wurden. Die Installationen die mit dem ISO-Image durchgeführt wurden dies nicht nötig.

Das hat sich mit den VS-2010 Express Editions (VS-EE) geändert. Es spielt keine Rolle ob es sich hier um die EE von C#, C++, VB oder eine der anderen verfügbaren Versionen handelt.
Alle diese Versionen müssen registriert werden. Die Laufzeit ohne Registrierung beträgt 30 Tage.

Ich rate dringend dazu, sofort nach der Installation auch die Registrierung durchzuführen. Und wenn es nicht klappt am nächsten Tag gleich wieder zu versuchen. Die Seite funktioniert leider oft genug nicht. So klagen zumindest nicht wenige Benutzer in den Foren.

Infos zur Registrierung hier:
http://www.microsoft.com/germany/express/registration/default.aspx

Download Link für alle Express Editionen (inkl. ISO-Image) hier:
http://www.microsoft.com/germany/express/download/default.aspx

Nachtrag:
Die FAQ ist ziemlich ungenau. Das jedes Produkt einen eigenen Schlüssel braucht habe ich ausprobiert. Aber man benötigt nur einmal eine Nummer für die Registrierung von VC#-2010 EE oder VC++-2010 EE ❗
Man kann ohne weiteres diese Registrierungsnummer auf mehreren Rechnern für mehrere Installationen benutzen (probiert auf Windows XP und Windows 7 Starter). Zumindest bei mir hat das geklappt. Es ist scheint nicht notwendig zu sein jede Version separat auf jedem neuen Rechner wieder zu registrieren ❗