Wie man den Namen einer RegisterWindowMessage bekommt

Manchmal muss man Software verstehen. D.h. auch andere Software, die man selbst nicht geschrieben hat 😉

In meinem Fall war es hier ein Client, den ich geschrieben habe, der eine andere Software startet. Diese Software verwendete interne Nachrichten zur Kommunikation, die mit RegisterWindowMessage registriert wurden. Ich wollte nun hier einen Eingriff machen, der ein Fehlverhalten unter Windows 7 und Vista vermeiden soll.

Hilfreich wäre für mich nun gewesen an den Namen der registrierten Nachrichten zu kommen. Spy++ kann es auch und der importiert auch keine mystischen Funktionen. Also muss es einfach gehen.

Und ein wenig Recherche und ein Verweis eines Community Eintrags brachte mich auf diesen Thread:
http://groups.google.it/group/microsoft.public.vc.mfc/browse_thread/thread/f83f7c12c80e4ada/460bc4c43a844a37

Siehe da GetClipboardFormatName löst das Problem. Der nachfolgende Code lieferte mir nun im Detail, was das so hin und her läuft und der Name der Nachrichten war zum Glück sprechend. Ich konnte das Problem lösen.

if (uiMsg>=0xC000)
{
  TCHAR szName[MAX_PATH];
  ::GetClipboardFormatName(uiMsg,szName,MfxCountOf(szName));
  TCHAR szOut[MAX_PATH*2];
  _stprintf(szOut,_T(__FUNCTION__) _T(" %s, wp=0x%08x, lp=0x%08x\n"),
            szName, wParam, lParam);
  OutputDebugString(szOut);
}

ExitInstance gibt für dialogbasierende MFC Anwendungen Unfug zurück

Wer eine dialogbasierende Anwendung mal mit etwas mehr Aufmerksamkeit debuggt oder analysiert wird feststellen, dass der Returncode der Anwendung irgendwie ziemlich zufällig ist. Beobachtet man dies genauer dann stellt man folgendes fest:

  • Beendet man die Anwendung mit der Maus (Klick auf X) oder OK/Cancel so ist der Returncode 0
  • Hält man die Strg-Taste beim Klick fest ist der Returncode 8
  • Beendet man die Anwendung mit Alt+F4 bekommen wir 2.
  • Und jedermann kann jetzt schon mal raten was passiert, wenn wir die Umschalttaste festhalten. Genau dann bekommen wir 4 als Returncode.

Die Mystik hinter dem Ganzen ist die Behandlung von (Afx)PostQuitMessage. Eigentlich sollte mit dieser Nachricht auch der Exitcode gesetzt werden, der mit WM_QUIT versendet wird. Und wenn eben bei einer MDI/SDI Anwendung alles normal läuft, dann ist diese Nachricht die letzte, die aus der Messsagequeue gezogen wird. Und was passiert in CWinApp::ExitInstance? Genau… aus dem statischen Thread Puffer für die Windowsnachrichten wird mit  AfxGetCurrentMessage die letzte Windowsnachricht (normalerweise WM_QUIT) geholt und der wParam Wert bestimmt. Dieser wird dann zurückgegeben.

Leider ist aber WM_QUIT in manchen Fällen aber nicht die letzte Nachricht, die zum Beenden eines Programms führt. Ganz besonders eben nicht bei einer dialogbasierenden MFC-Anwendung. Da ist die letzte Nachricht ist dann eben ein WM_COMMAND oder ein WM_LBUTTONUP der das Schließen der Anwendung auslöst ❗ Und der wParam Wert ist eben entsprechend dieser Nachricht belegt!

Gleiches passiert natürlich, wenn man nach dem Beenden der Messageloop noch andere interne Fenster zerstört. Auch in diesem Fall kann noch mal die interne AfxWndProc durchlaufen werden und dann wird der Returncode auch wieder verändert.

Wer also wirklich Wert auf den Returncode legt (im wahrsten Sinne des Wortes), der sollte sich nie auf den Wert verlassen, der durch CWinApp::ExitInstance zurückgegeben wird oder den Wert, den man selbst mit AfxPostQuitMessage evtl. versucht zu setzen. Eine Variable in CWinApp tut hier einen besseren Dienst. Ebenfalls sollte man ExitInstance überschreiben und immer 0 zurückgeben, wenn man sowieso keine Verwendung für den Returncode des Prozesses hat oder haben möchte.

BTW:
Die Geschichte, wie ich darauf gekommen bin ist schon eigentümlich genug.
Ich habe komplexere Batch-Dateien, die die gesamte Erstellung einer produktiv-Version regelt. Darin kommen im Problemfall auch ein paar Userinteraktionen vor. Diese werden durch Windows Anwendungen ausgelöst, die evtl. einen Dialog anzeigen. Jedem ist klar, dass ohne Dialog und ohne Fenster keine Nachricht abgearbeitet wird. Der Returncode ist also 0! Der Batch verwendet 4NT Syntax und dort kann man ON ERROR definieren und somit sofort eine Fehlerbehandlung auslösen, wenn der Returncode eines Programms nicht 0 ist.
Nun kann sich jeder schon denken was passiert ist. Die Userinteraktion wurde ausgelöst. Der Benutzer machte eine Angabe und… der Batch terminierte erstaunlicherweise mit einem Fehler… (s.o.)

Tipp: Hörbuch Mutige Menschen (von Christian Nürnberger)

Für längere Autofahrten haben meine Frau und ich es uns angewöhnt Hörbücher aus der Bücherei auszuleihen.
In den meisten Fällen sind es Kabarett, kurze humorvolle Geschichten, christliches, politisches oder gesellschaftskritisches.

Diesmal hat meine Frau ein wirklich besonderes Hörbuch ausgesucht Mutige Menschen von Christian Nürnberger. Die Texte werden von den Söhnen Mannheims gesprochen, wobei dies hier nicht unbedingt für Qualität bürgt 😉

Der Inhalt ist aber echt stark und wirklich hörenswert! Die Personen (Ayaan Hirsi Ali, Peter Benenson, Mahatma Gandhi, Martin Luther, Nelson Mandela, Rosa Parks und Anna Politkowskaja), die ausgewählt wurden für dieses Hörbuch, sind besonders.
Besonders beeindruckt hat mich die Geschichte von Ayaan Hirsi Ali und Rosa Parks. Man muss es sich selbst anhören.
Die Gedanken, die von Ayaan Hirsi Ali über den Islam geäußert werden, sind wirklich nachdenkenswert.

Mich hat vor allem begeistert, dass Christian Nürnberger in die Lebensgeschichten dieser Menschen geschaut hat. Die Texte sind intelligent gesetzt und ansprechend und vor allem eine Aufforderung selbst Mut und Zivilcourage zu haben in dieser Welt etwas zu verändern.

Ein Hörbuch mit Klasse, dass auch animiert sich das gleichnamige Buch mal anzuschauen, zumindest auf meiner Wunschliste steht es schon ❗

Tipps & Tricks: Mal ganz schnell das MS-SQL Server 2008 Managment Studio Express nachinstallieren

Bei dem Management Studio für die 2005 EE war noch alles ganz einfach. Man schmeißt einfach den Installer an. Man klickt ein paar mal weiter und das war es auch schon. Nachdem ich VS-2010 installiert hatte wollte ich nun auch das passende Management Studio für die 2008 EE installieren. Also:

  • Download gemacht 
  • Setup gestartet
  • und 😕 was nun?

Das Setup und das was ich hier alles einstellen kann ist alles andere als intuitiv.

Ich mache es kurz. Man kann sich das ganze durch-die-Dialoge-hangeln sparen.
Man startet einfach die Installation mit dem folgenden Befehl von einer Befehlszeile:

SQLManagementStudio_x86_xxx.exe /q /FEATURES= SSMS /ACTION=Install

Statt xxx gebe man bitte einfach in DEU oder ENU an, je nachdem was man für eine Sprache hat.

Gefunden habe ich das hier auf diesem Link, hier finden sich auch weitere Anweisungen wie man sich durch die Dialoge quälen muss:
http://blogs.msdn.com/billramo/archive/2009/02/20/sql-server-2008-management-studio-express-released-to-the-web.aspx

Das Management Studio Express findet sich hier zum Download:
http://www.microsoft.com/downloads/details.aspx?familyid=08E52AC2-1D62-45F6-9A4A-4B76A8564A2B&displaylang=de

Tool: Screen-OCR Version 2.0, einfach mal Texte vom Monitor aus Bildschirmausschnitten und Grafiken in die Zwischenablage kopieren

Am 15. Mai hatte ich eine erste Version meines Freeware Screen-OCR Programmes veröffentlicht. Siehe Tool: Screen-OCR, einfach mal Texte vom Monitor aus Bildschirmausschnitten und Grafiken in die Zwischenablage kopieren

Nun habe ich etwas Zeit für Version 2.0 gefunden ❗
Folgende Verbesserungen wurden eingebaut:

  • Etwas schönere UI für das Auschneiden aus dem aktuellen Desktop.
  • Deutsches und englisches Benutzerinterface.
  • Das Programm kann nur noch einmal gestartet werden. Mehrfaches Starten macht hier keinen Sinn.
  • Das Tool kann nun auch das letzte aktive Fenster per OCR erfassen, oder auch eine Bitmap in der Zwischenablage. Es wurde ein entsprechendes Drop-Down Menü eingebaut.
  • Es gab bei mehrfachen Aufrufen ab und zu Crashs, was offensichtlich daran liegt, dass die MODI-DLLs es nicht mögen geladen, entladen und wieder geladen zu werden.

Download hier  MRi-Screen-OCR Version 2.0

Falls man MODI nicht hat, hier kann man es kostenlos bekommen:
http://support.microsoft.com/kb/982760