tomaschku
Goto Top

Eigene Zeichenfunktion tut nichts, Rückgabewert sagt was anderes

Hallo Leute!

Ich habe mir eine Funktion erstellt, die simple, gefärbte Rechtecke auf dem Bildschirm ausgeben soll.
Ich habe von dieser Funktion zwei Versionen:

1. 'drawRect' Nimmt einen Startpunkt (von links oben aus gesehen) und Breite & Höhe.

2. 'drawRectSym' Nimmt 4 Parameter (exkl. Farbe):
Left und Top sind als Startpunkt (von links oben),
Right und Bottom sind als Endpunkt (von rechts unten) gedacht.

Die 1. Version funktioniert tadellos, allerdings die 2 nicht.
Zuerst hatte ich keinen Rückgabewert festgelegt (void), bis dieser Fehler auftrat. Dann habe ich den Wert von 'FillRect()' getestet (eigentliche Zeichenfunktion),
aber da kam immer true, also Erfolgreich zurück.

Da ich den Fehler aber selber nicht finde, möchte ich euch bitten, euch den Code mal anzuschauen.
Vielleicht fällt euch ja etwas auf. face-plain
//Header
bool drawRect(int X_Start, int Y_Start, int Width, int Height, HBRUSH brush);
bool drawRectSym(int Left, int Top, int Right, int Bottom, HBRUSH brush);

bool drawRect(int X_Start, int Y_Start, int Width, int Height, HBRUSH brush) {
	HDC screen = GetDC(0);

	const RECT coordinates = {X_Start, Y_Start, X_Start+Width, Y_Start+Height};

	if(FillRect(screen, &coordinates, brush) != 0) {
		return true;
	} else {
		return false;
	};
};

bool drawRectSym(int Left, int Top, int Right, int Bottom, HBRUSH brush) {
	HDC screen = GetDC(0);

	const RECT coordinates = {Left, Top, Right, Bottom};

	if(FillRect(screen, &coordinates, brush) != 0) {
		return true;
	} else {
		return false;
	};
};

//Main.cpp

int main() {	
	HBRUSH Bred = CreateSolidBrush(RGB(255, 0, 0));
	HBRUSH Bgreen = CreateSolidBrush(RGB(0, 255, 0));
	HBRUSH Bblue = CreateSolidBrush(RGB(0, 0, 255));
	bool returns[3] = {false, false, false};
	
	while(true) {
		printf("R: %s  |  G: %s  |  B: %s\n", returns ? "true" : "false", returns[1] ? "true" : "false", returns[2] ? "true" : "false");  
		returns = drawRectSym(100, 100, 100, 100, Bred);
		returns[1] = drawRectSym(200, 200, 200, 200, Bgreen);
		returns[2] = drawRectSym(400, 400, 400, 400, Bblue);
		Sleep(1000);
	};
	
	pause(); //Eig. unnötig, weil Endlosschleife
	return 0;
}

System & IDE:
Windows 10 vor dem Creators Update
Dev-C++ mit gcc Compiler und manuell hinzugefügte Bibliothek GDI32

Gruß,
tomaschku

Content-ID: 365601

Url: https://administrator.de/contentid/365601

Ausgedruckt am: 21.11.2024 um 22:11 Uhr

rubberman
rubberman 21.02.2018 um 21:29:02 Uhr
Goto Top
Ich würde ja mal versuchen für Right und Bottom größere Werte zu übergeben, als für Left und Top. Sind sie gleich, dann zeichnest du (wenn überhaupt) einen Punkt.

Steffen
tomaschku
tomaschku 22.02.2018 aktualisiert um 13:24:34 Uhr
Goto Top
Guter Ansatz, als ich aber mit FillRect direkt herumgespielt habe, ist mir aufgefallen, dass Right und Bottom nicht von Links oben aus geht.
Heißt: drawRectSym(100, 100, 100, 100) würde ein Rechteck erstellen, das rundherum 100px von Bildschirmrand entfernt wäre. Deshalb habe ich auchviel 2 Versionen: Eine, für symmetrische Darstellung (geht nicht) und die mit Breite und Höhe (geht).
Vielleicht steht in der Dokumentation von Microsoft etwas, bin aber nicht sicher.

tomaschku
rubberman
Lösung rubberman 22.02.2018 um 16:37:17 Uhr
Goto Top
Zitat von @tomaschku:
Heißt: drawRectSym(100, 100, 100, 100) würde ein Rechteck erstellen, das rundherum 100px von Bildschirmrand entfernt wäre.
Wie kommst du darauf?
https://msdn.microsoft.com/en-us/library/windows/desktop/dd162719(v=vs.8 ...
lprc [in]
A pointer to a RECT structure that contains the logical coordinates of the rectangle to be filled.
Heißt, das RECT deren Adresse du übergibst wird gefüllt.

In den Bemerkungen findet sich dann noch
FillRect does not include the rectangle's right and bottom sides. GDI fills a rectangle up to, but not including, the right column and bottom row, regardless of the current mapping mode.
Mein "wenn überhaupt" von oben kann ich also noch mit einem Ausrufezeichen versehen, denn in der Realität sollte also nicht mal ein Punkt gezeichnet werden.

Ergo: Du übergibst ein RECT mit gleichen Werten für left und right, sowie gleichen Werten für top und bottom. Somit sagst du der Funktion, dass sie nichts füllen soll, was wunschgemäß gemacht wird und darum zur Erfolgsmeldung führt.

Steffen
tomaschku
tomaschku 22.02.2018 aktualisiert um 18:23:26 Uhr
Goto Top
Zitat von @rubberman:
Ergo: Du übergibst ein RECT mit gleichen Werten für left und right, sowie gleichen Werten für top und bottom. Somit sagst du der Funktion, dass sie nichts füllen soll, was wunschgemäß gemacht wird und darum zur Erfolgsmeldung führt.

Du hattest vollkommen Recht! Als ich drawRect und drawRectSym mit den Werten {100, 100, 100, 100} und zwischenpause getestet habe, sah ich, das bei drawRectSym nichts rauskam. Beim Test mit {100, 100, 101, 101}, also einer 2x2 Pixelfäche, zeichnete er 1 Pixel. Ich habe diesen Hinweis áuf der Microsoft Seite vollkommen überlesen. Was ich aber seltsam finde: Ich habe einen ähnlichen Code in Visual Studio (Am TowerPC, Dev-Cpp am Laptop wegen Speicherplatz) und dort wurden die Werte als Abstand vom Bildschirmrand genommen. Also entweder habe ich FillRect() von der Funktionsweise her falsch in Erinnerung, oder ich habe zuviel in Visual Studio rumgebastelt, dass ich die Codeschnippsel verwechselt habe. Aber wieso gibt FillRect() keinen Error zurück? Man kann ja schlecht prüfen, ob wirklich dieser Pixel verändert wurde.

Naja, wenigstens kenn ich jetzt den Fehler und kann weiterarbeiten. Danke!

Gruß,
tomaschku
rubberman
Lösung rubberman 22.02.2018 um 20:45:44 Uhr
Goto Top
Um zu erreichen was du vorhast, brauchst du die GetSystemMetrics Funktion
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.8 ...
die du mit Argument SM_CXSCREEN bzw. SM_CYSCREEN fütterst. So bekommst du Breite und Höhe des (Haupt-)Monitors. Was fehlt ist ein bisschen Mathe. Left und Top lässt du bei 100, Right ist Breite - 100 und Bottom ist Höhe -100. Um Fehler zu vermeiden müsstest du natürlich noch prüfen dass Right nicht kleiner als Left und Bottom nicht kleiner als Top wird.

Steffen
tomaschku
tomaschku 22.02.2018 um 22:55:42 Uhr
Goto Top
Danke, hab die Funktion schon angepasst!

tomaschku