GDI Mehrere Rectangles

Liebes Forum!

Ich habe bereits einiges gegooglet aber noch immer keine Lösung für mein Problem gefunden. Ich möchte mit der Windows GDI Rechtecke zeichnen und zwar nicht eines sondern mehrere nebeneinander. Das ganze soll dan mein Stundenplan werden. Das Problem liegt jetzt darin, dass sobald das zweite Rechteck gezeichnet wird, das erste verschwindet. Was kann ich da tun?

Mein Code:

void PaintTT(HWND hwnd)
{
 #define RECT\_WIDTH 100
 #define RECT\_HEIGHT 40

 // Variable
 HPEN hPen;
 HBRUSH hBrush;
 HDC hdc;
 PAINTSTRUCT ps;

 // Malobjekte initialisieren
 hBrush= (HBRUSH) COLOR\_WINDOW;
 hPen = CreatePen(PS\_SOLID,1,RGB(0,0,0));

 // Zeichnen Beginnen
 hdc=BeginPaint(hwnd,&ps);
 SelectObject(hdc,hBrush); // Objekte mit dem GDI verbinden
 SelectObject(hdc,hPen); //

 // Mal-Funktion(-en)
 for(int day=0;day

Irgendwo hab ich gefunden, dass das normal ist, dass das erste vom zweiten "überzeichnet" wird. Aber lässt sich das verhindern?

mfg dixxi

Hallo Dixxi,

Dein Code ist unvollständig, du hast uns die Variable „tt“ unterschlagen, also kann man es auch nicht testen. Die SYSTEMTIME kann es nicht sein, weil die Var’s da anders benannt sind. Gut, wa?

Und was soll das hier:

hBrush= (HBRUSH) COLOR\_WINDOW;

Laut Win-header is das

#define COLOR\_WINDOW 5

Wenn schon, dann muss das so aussehen:

HBRUSH hBrush = CreateSolidBrush (COLOR\_WINDOW);

Wenn Du 5 jedoch als COLORREF nimmst, wird das scharz.

Ich habe dir das aber ein wenig aufgefrischt. Die Groesse des Fensters könnte dann auch noch eine Rolle spielen, siehe Code (client).

Das Problem liegt jetzt darin, dass sobald das zweite
Rechteck gezeichnet wird, das erste verschwindet.

Bist Du sicher, dass die Werte von „day, hour“ auch als Pixel zu brauchen sind?
Solange die Rechtecke nebeneinander sind, können sie sich auch nicht verdecken.

Was kann ich da tun?

Du kannst auch einen NULL-Brush verwenden. Die Rectangle() zeichnet dann transparent, siehe Code.

lg
Martin B

HBRUSH makeNull()
{
 const tagLOGBRUSH LogBrush = {BS\_NULL}; 
 return CreateBrushIndirect(&LogBrush);
}

void PaintTT(HWND hwnd)
{
 #define RECT\_WIDTH 100
 #define RECT\_HEIGHT 40

 // wozu: PAINTSTRUCT ps; ???

 HDC hdc = GetDC(hwnd);
 // die aktuellen Handles zurueck kriegen:
 HBRUSH oldBrush = 
 (HBRUSH)SelectObject(hdc, 0xff);
 HPEN oldPen = 
 (HPEN) SelectObject(hdc, 
 CreatePen(PS\_SOLID,1,RGB(0,0,0)) 
 );

 int x, y;
 RECT client;
 GetClientRect(hwnd, &client);
 for(int day=0; day

Lieber Martin!

Erst einmal Danke für deine Antwort, hat mir aber leider nichts geholfen, weil jetzt auf einmal gar nichts mehr in meinem Fenster gezeichnet wird und wenn ich es verschiebe, verliert es seinen Rahmen und eine graue Fläche bleibt zurück. Ich kann dan nur mehr über den Taskmanager beenden.

Dein Code ist unvollständig, du hast uns die Variable „tt“
unterschlagen, …

Hier sind die Strukturen:

typedef struct tagHOUR
{
 char subject[4];
 char teacher[5];
 char room[5];
 bool bold;
} HOUR;

typedef struct tagDAY
{
 int numhours;
 HOUR\* hour;
} DAY;

typedef struct tagTIMETABLE
{
 DAY\* day;
 bool paint;
} TIMETABLE;

TIMETABLE tt;

Die Struktur sieht dan etwa so aus, dass tt 5 DAYs enthält, die jeweils wieder eine unterschiedliche Anzahl an HOURs enthalten. Das entspricht meinem Stundenplan. DAYs gibt es immer 5. HOURs gibt es tt.DAY[i].numhours viele.

Und was soll das hier:

hBrush= (HBRUSH) COLOR_WINDOW;

Laut Win-header is das

#define COLOR_WINDOW 5

Wenn schon, dann muss das so aussehen:

HBRUSH hBrush = CreateSolidBrush (COLOR_WINDOW);

Wenn Du 5 jedoch als COLORREF nimmst, wird das scharz.

Ja entschuldigung, ich wollte, dass der Brush dieselbe Farbe hat, wie mein Window. Aber das ist jetzt nicht so wichtig.

Bist Du sicher, dass die Werte von „day, hour“ auch als Pixel
zu brauchen sind?

Ja absolut sicher, day geht von 0 - 5, und hour von 0 - max 10

Du kannst auch einen NULL-Brush verwenden. Die Rectangle()
zeichnet dann transparent, siehe Code.

Gute Idee.

Ich hab das Problem aber soeben selbst gelöst. Der Fehler lag in den Parametern von Rectangle(). Ich habe die beiden letzten Parameter als relative Abstände zum zweiten und dritten Parameter genommen. Und somit war der zweite Punkt des Rechteckes immer an der selben Position. Ich bin aber gerade draufgekommen, dass hier absolute Positionen gefragt sind.

Geändert habe ich:

Rectangle(hdc, day\*RECT\_WIDTH, hour\*RECT\_HEIGHT, RECT\_WIDTH, RECT\_HEIGHT);

auf:

Rectangle(hdc, day\*RECT\_WIDTH, hour\*RECT\_HEIGHT, RECT\_WIDTH+day\*RECT\_WIDTH, RECT\_HEIGHT+hour\*RECT\_HEIGHT);

Und den Tipp mit dem transparenten Brush und strlen() habe ich ebenfalls gut brauchen können.

Der Code sieht jetzt wie folgt aus:

void PaintTT(HWND hwnd)
{
 #define RECT\_WIDTH 100
 #define RECT\_HEIGHT 40

 // Variable
 HPEN hPen;
 HBRUSH hBrush;
 HDC hdc;
 PAINTSTRUCT ps;

 // Malobjekte initialisieren
 const tagLOGBRUSH LogBrush = {BS\_NULL};
 hBrush = CreateBrushIndirect(&LogBrush);
 //hBrush= (HBRUSH) CreateSolidBrush(RGB(244,244,244));
 hPen = CreatePen(PS\_SOLID,1,RGB(0,0,0));

 // Zeichnen Beginnen
 hdc=BeginPaint(hwnd,&ps);
 SelectObject(hdc,hBrush); // Objekte mit dem GDI verbinden
 SelectObject(hdc,hPen); //

 // Mal-Funktion(-en)
 for(int day=0;day
Alles funktioniert, auch die Ausgabe des Unterrichtsgegenstandes (subject).

Ach ja, weil soviel "unnötig" war. Ich beschäftige mich zum ersten mal mit der GDI, habe zuvor nur mit OpenGL gearbeitet, aber das wäre etwas zu groß für diese Kleinigkeit. Der Code ist aus dem Internet und hat bei einem Rechteck auf Anhieb sehr gut funktioniert, darum habe ich ihn gleich übernommen.

Vielen Dank, auch wenn es mir nur indirekt zur Lösung geholfen hat
mfg dixxi

Ooops-error
habe ich übersehen:

HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, 0xff);

Ist natürlich Quatsch, ich kann eine Zahl 0xff nicht selektieren, das muss vielmehr so aussehen:

HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, 
 CreateSolidBrush(0xff)
 );

sorry,
Martin B