Thursday, 15. March 2007Einfärben von ListBox und ListView controls
Die Aufgabenstellung selbst erscheint relativ simpel: Man möchte in einer ListBox bzw. in einem ListView einen Eintrag mit einer Hintergrundfarbe hinterlegen, um diesen z.B. besonders hervorzuheben.
Leider unterscheiden sich die Methoden hierfür bei ListBox und ListView erheblich. Beim ListView ist das Ganze relativ einfach zu lösen: Das ListView sendet eine WM_NOTIFY Message an den Parent-Dialog, der das Control beinhaltet. Als lParam erhält man eine LPNMLISTVIEW Struktur, welche im hdr Member wiederum einen Member code enthält, welcher den eigentlichen Notification code angibt. Für das ListView ist hier für uns der Code NM_CUSTOMDRAW interessant. Durch Erhalt der Message ist sichergestellt, dass es sich bei der in lParam an uns übergebene Struktur um eine NMLVCUSTOMDRAW Struktur handelt. In deren Member nmcd befindet sich die zur Message zugehörige Struktur NMCUSTOMDRAW , welche wiederum den Member dwDrawStage beinhaltet, der uns über den aktuellen Zeichnungsstatus informiert. Erhalten wir hier die Nachricht CDDS_PREPAINT , wissen wir, dass das Zeichnen des ListViews gerade beginnt. An dieser Stelle müssen wir nun unser Interesse an den Notifications für die einzelnen Items der Liste anmelden. Das geht ganz einfach mit folgendem Kommando:SetWindowLong (hWnd, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW); Mit besagtem Kommando teilen wir dem Notifier unsere Antwort mit, die da eben lautet CDRF_NOTIFYITEMDRAW .Nun können wir den Drawstage pro Item mit der Nachricht CDDS_ITEMPREPAINT dispatchen.An dieser Stelle können wir nun auf den Zeichenprozess einfluss nehmen, indem wir die Members de rStruktur in lParam entsprechend modifizieren und den Notifier diese Änderung zur Kenntnis bringen. Hier ein Beispiel, welches den Text rot färbt: lplvcd->clrText = RGB(255,0,0); Den kompletten Source zur besseren Übersicht gibt's hier Bei der ListBox ist das Ganze leider nicht ganz so einfach. Diese bietet nämlich leider keinen so bequemen WM_NOTIFY -Mechanismus. Stattdessen muss man sich hier mit einem owner-Drawn control aushelfen, was natürlich einiges an Arbeit mit sich bringt. Daher sollte man als Style für das Control LBS_OWNERDRAWFIXED verwenden. Ein LBS_HASSTRINGS könnte sich auch als nützlich erweisen.Bei einem Owner-Drawn control erhält der Parent eine WM_DRAWITEM Notification, welche entpsrechend behandelt werden muss.Als lParam erhält man ein LPDRAWITEMSTRUCT , welches den Member itemAction hat. Interessant sind hierbei die Actions ODA_SELECT und ODA_DRAWENTIRE .Ein Zeichnen des ListBox-Eintrags im entsprehcenden Style erreicht man hier mittels Modifikation des device contexts, welcher sich im hDC Member des DRAWITEMSTRUCT s befinder.Je nach itemState Member sollte man die Vordergrund- und Hintergrundfarbe des Eintrags entsprechend setzen. Um die Systemfarben zu ermitteln, empfiehlt sich der Einsatz der Funktion GetSysColor .Mit FillRect die Auswahlmarkierung erzeugen und mit TextOut schließlich den Text zeichnen. Also ein relativ hoher Aufwand, um nur die Farbe des Textes zu ändern.Ein Codebeispiel gibt's wie immer hier. Wednesday, 21. June 2006Grid control für Win32
Die Standard WIN32-Forms und Common Controls sind ansich sehr praktisch, um benutzerfreundliche Forms anzulegen. Allerdings besitzen sie von Haus aus keine Funktionalität für Grids, wie diese z.B. von Excel her bekannt sind. Nun gibt es zwar zahlreiche Implementierungen von Grids im Internet (die meisten funktionieren mit Hilfe eines ListView-Controls), diese basieren jedoch leider zumeist auf der MFC, sodass hier wieder unnötiger Overhead entsteht. Was aber macht der normale Win32-API Programmierer in diesem Fall? Erst nach langem Suchen bin ich über den Artikel Win32 Grid Control with Low Overhead (BABYGRID) auf codeguru.com gestoßen, welcher eine Implementierung mittels normaler WIN32-API zeigt. Mit ein paar kleinen Fixes lässt sich der Code auf C portieren (es werden leider standardmäßig einige C++ Features verwendet, das Ganze lässt sich jedoch sehr einfach reparieren. Bei Interesse an dem korrigierten Code einfach einen Kommentar hinterlassen). Praktischerweise wird das Control zur Gänze selbst gezeichnet, sodass man auch leicht auf die Optik des Controls Einfluss nehmen kann. Ich habe beispielsweise erfolgreich ein Sudoku-Lösungsprogramm damit realisiert.
Friday, 19. May 200680Bit IEEE float in 64Bit double in MS VC++ umwandeln
Verwendete man beispielsweise unter Borland Turbo C 3 in DOS einen
float oder double Wert, so wurde der als IEEE 80Bit float dargestellt, was logisch erscheint, da die FPU der Intel x86 CPU ebenfalls intern mit dieser Auflösung arbeitet. Ein long double wird beim gcc C-Compiler ebenfalls in diesr Form repräsentiert. Es ist daher auch üblich, in binären Dateiformaten solche Werte vorzufinden.Möchte man nun solche Werte im MS VC++ auslesen, steht man vor einem Problem: Wie der MSDN-Dokumentation zu entnehmen ist, wird dieser Datentyp nicht unterstützt:
Jetzt stellt sich daher die Frage, wie solche Werte ausgelesen und dann auf einen 64Bit breiten double (real*8) konvertiert werden können. Wie ja bereits in der MSDN steht, gibt es auf Assemblerebene Unterstützung für 80Bit breite float Zahlen.Es reichen daher auf der x86 CPU 2 kleine FPU-Assemblerkommandos zur Konvertierung. Man kann sich daher folgende kleine Funktion erstellen, welche eine Konvertierung vornimmt:
Sunday, 6. November 2005leitfaden.at - Ratgeber, Leitfäden usw.
ein kleiner hinweis in eigener sache: seit gestern gibt es die seite www.leitfaden.at.
das ganze ist ein wiki das eben für ratgeber, anleitungen und leitfäden jeglicher art gedacht ist, mitarbeit ist jederzeit willkommen, alle arten von ratgebern sind erwünscht - beteiligt euch!
(Seite 1 von 1, insgesamt 4 Einträge)
|
SucheBlog abonnierenTop ReferrerVerwaltung des Blog |