Farb - Variable

Windowsspezifische Probleme, WinAPI, conio.h
Antworten
Tonio
Beiträge: 7
Registriert: Fr Nov 13, 2015 8:39 am

Farb - Variable

Beitrag von Tonio » Mo Jan 11, 2016 2:01 pm

Hallo,

ich bin dabei WinApi zu lernen und hab auch schon bischen was erreicht.
Jetzt möchte ich von mir mittels RGB definierte Farben in Variablen so abspeichern, dass sie in allen Api-Funktionen verwendbar sind, also z.B.

angefangen beim Bildschirmhintergrund, über Objekte, Texte etc.

Es klappt aber nicht. Irgendwas mache ich bei der Wahl und / oder Umwandlung der Datentypen falsch.

bis jetzt habe ich nur definiert

Code: Alles auswählen

static int Weiss = RGB(255,255,255) // ich muss das Object ja nicht unbedingt "iColor" nennen.
static int Schwarz = RGB(0,0,0) klingt sehr simpel aber es kommen noch ein paar dazu, die ich selbst definiere,
Dann habe ich:

Code: Alles auswählen

wc.hbrBackground = Schwarz   // [Warning] assignment makes pointer from integer without a cast, in den Tutorials wurde hbrBackground als Variable beschrieben die initiert werden muss.
Es gilt doch:

Code: Alles auswählen

Variable = 5
VARIABLE = Variable
also ist der Wert von VARIABLE auch = 5

Dann habe ich noch die Funktionen SetTextColor =
und SetBkColor =
Da bemängelt der Compiler, das die Variablen nicht deklariert seien.

Bei den Schriften hat das über HFONT ASchrift = CreateFont(Parameter....) wunderbar geklappt.

Kann mir jemand helfen?

Danke im Voraus

Tonio

Edit by Xin: Hab mal ein paar Code-Tags zur Strukturierung eingefügt

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Farb - Variable

Beitrag von Xin » Mo Jan 11, 2016 4:44 pm

Tonio hat geschrieben:ich bin dabei WinApi zu lernen und hab auch schon bischen was erreicht.
Da drängt sich mir direkt eine Frage auf: WARUM!?
Tonio hat geschrieben:Jetzt möchte ich von mir mittels RGB definierte Farben in Variablen so abspeichern, dass sie in allen Api-Funktionen verwendbar sind, also z.B. angefangen beim Bildschirmhintergrund, über Objekte, Texte etc.

bis jetzt habe ich nur definiert

Code: Alles auswählen

static int Weiss = RGB(255,255,255) // ich muss das Object ja nicht unbedingt "iColor" nennen.
static int Schwarz = RGB(0,0,0) klingt sehr simpel aber es kommen noch ein paar dazu, die ich selbst definiere,
Naja, laut Doku kommt da ein COLORREF raus, was ein DWORD ist, was vermutlich ein unsigned int ist.
Tonio hat geschrieben: Dann habe ich:

Code: Alles auswählen

wc.hbrBackground = Schwarz   // [Warning] assignment makes pointer from integer without a cast, in den Tutorials wurde hbrBackground als Variable beschrieben die initiert werden muss.
Es gilt doch:

Code: Alles auswählen

Variable = 5
VARIABLE = Variable
Naja, hbrBackground ist kein COLORREF, sondern ein HBRUSH...
Also erstmal einen HBRUSH erstellen, bevor Du es zuweist.
Tonio hat geschrieben: Dann habe ich noch die Funktionen SetTextColor =
und SetBkColor =
Da bemängelt der Compiler, das die Variablen nicht deklariert seien.
Keine Ahnung, kein Quelltext, keine Fehlermeldung... da musst Du schon konreter werden.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Tonio
Beiträge: 7
Registriert: Fr Nov 13, 2015 8:39 am

Re: Farb - Variable

Beitrag von Tonio » Di Jan 12, 2016 12:09 pm

:D Hallo Xin,

danke erst mal, dann muss ich wohl doch ein bisschen ausführlicher werden.

Ich lerne die Winapi weil das Erscheinungsbild etwas über die Möglichkeiten der Konsole hinausgehen soll und ich keine andere Tools z.B GTK zur Verfügung habe.

Nach meinen Informationen ist die WinApi in C geschrieben und ich habe mal windows.h in den Compiler geladen, um zu sehen, was da includiert ist und dann habe ich das dort Includierte geladen um diese Header -Dateien zu sehen und so habe ich das weiter aufgetröselt bis ich ursprüngliche C-Header gefunden habe.- Das nur zu meinem Verständnis. Daraus schließe ich aber auch, dass man eine Anwendung mit graphischer Benutzer-Oberfläche auch in rein ursprünglichem C schreiben kann, wenn man den Code für jede spezifische WinApi-Funktion ausschreibt.

Du hast mir mal Code für eine Cursor-Position geschrieben. Das habe ich dann einfach als curspos.h im Header-Verzeichnis des Compilers abgespeichert und includiert. Und so verstehe ich auch die WinApi vom Wirkungsprinzip her.

Soweit es nicht direkt mit der Oberfläche zu tun hat, schreibe ich alles was hinter dem Bildschirm als Programmablauf passiert grundsätzlich in C ohne ungarische Notation. Also z.B. statt LPTCTSTR schreibe ich const char *, statt DWORD unsigned int. Soweit ich bis jetzt vestanden habe ist C allgemeiner, weniger spezifisch, universeller. Und diese Methode hilft mir beides ein bischen besser zu verstehen, auch wenn es noch nicht so aussieht, denn nur Code-Bausteien zu lernen ohne vVerständnis ist wie das Tel-Buch zu lernen.

Das Problem mit der undeclared Variable hat sich inzwischen gelöst, was daran lag, dass ich sie nicht am Anfang dekleriert hatte sondern in einer anderen Funktion später:

Code: Alles auswählen

static int Schwarz	= RGB(  0,  0,  0);
static int Weiss	= RGB(255,255,255);
Jetzt stet's am Anfang und klappt. Aber COLORREF = DWORD = unsigned int. Jedoch reichen für 16 Mill Farben auch 2 Mrd integer im pos Bereich weshalb ich bei static int bleibe.

Aber ich habe noch die Frage warum dieses so nicht geht:

Code: Alles auswählen

wc.hbrBackground =	Schwarz;
Das Fenster bleibt durchsichtig und der Compiler meldet: "[Warning] assignment makes pointer from integer without a cast"

Es funktioniert nur so:

Code: Alles auswählen

wc.hbrBackground =	CreateSolidBrush(Schwarz);
Aber wo soll da ein Zeiger sein? Laut Erklärung ist hbrBackground eine Variable und es gilt:

Code: Alles auswählen

Variable1 = Wert1
Variable2 = Variable1
Also hat Variable2 auch den Wert1
Wozu brauche ich die Funktion CreateSolidBrush?

Ich bitte um Korrektur, wenn ich entsprechend meinen Erklärungen was falsch verstanden habe oder etwas unsinnig ist in meiner Vorgehensweise.

Danke

Gruß, Tonio :)

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Farb - Variable

Beitrag von Xin » Di Jan 12, 2016 1:35 pm

Tonio hat geschrieben:Daraus schließe ich aber auch, dass man eine Anwendung mit graphischer Benutzer-Oberfläche auch in rein ursprünglichem C schreiben kann, wenn man den Code für jede spezifische WinApi-Funktion ausschreibt.
Man kann in C GUI machen... aber WinAPI ist wirklich nicht schön...
Du lernst damit quasi die grausamste Art GUI zu machen, kombiniert mit der grausamsten Art C zu programmieren.
Tonio hat geschrieben:Du hast mir mal Code für eine Cursor-Position geschrieben. Das habe ich dann einfach als curspos.h im Header-Verzeichnis des Compilers abgespeichert und includiert. Und so verstehe ich auch die WinApi vom Wirkungsprinzip her.
Äh... zum einen sollten Funktionen nicht im Header stehen, sondern in .c Dateien.
Das kann man statisch zusammenkompilieren oder - und so funktioniert auch die WinAPI - man greift auch DLLs zu.
Tonio hat geschrieben:Soweit es nicht direkt mit der Oberfläche zu tun hat, schreibe ich alles was hinter dem Bildschirm als Programmablauf passiert grundsätzlich in C ohne ungarische Notation. Also z.B. statt LPTCTSTR schreibe ich const char *, statt DWORD unsigned int.
Du solltest die Typen benutzen, die die WinAPI vorgibt, auch in C.
Tonio hat geschrieben:Soweit ich bis jetzt vestanden habe ist C allgemeiner, weniger spezifisch, universeller. Und diese Methode hilft mir beides ein bischen besser zu verstehen, auch wenn es noch nicht so aussieht, denn nur Code-Bausteien zu lernen ohne vVerständnis ist wie das Tel-Buch zu lernen.
Die WinAPI ist eher die Telefonbuch-Variante.
Tonio hat geschrieben:Das Problem mit der undeclared Variable hat sich inzwischen gelöst, was daran lag, dass ich sie nicht am Anfang dekleriert hatte sondern in einer anderen Funktion später:

Code: Alles auswählen

static int Schwarz	= RGB(  0,  0,  0);
static int Weiss	= RGB(255,255,255);
Jetzt stet's am Anfang und klappt. Aber COLORREF = DWORD = unsigned int. Jedoch reichen für 16 Mill Farben auch 2 Mrd integer im pos Bereich weshalb ich bei static int bleibe.
...und damit die Typ-Information vernichtest.
Tonio hat geschrieben:Aber ich habe noch die Frage warum dieses so nicht geht:

Code: Alles auswählen

wc.hbrBackground =	Schwarz;
Das Fenster bleibt durchsichtig und der Compiler meldet: "[Warning] assignment makes pointer from integer without a cast"

Es funktioniert nur so:

Code: Alles auswählen

wc.hbrBackground =	CreateSolidBrush(Schwarz);
Aber wo soll da ein Zeiger sein?
CreateSolidBrush liefert einen Zeiger zurück.
Tonio hat geschrieben:Laut Erklärung ist hbrBackground eine Variable und es gilt:

Code: Alles auswählen

Variable1 = Wert1
Variable2 = Variable1
Also hat Variable2 auch den Wert1
Wozu brauche ich die Funktion CreateSolidBrush?
Weil hbrBackground, wie ich schon schrieb, ein HBRUSH ist. Ein HBRUSH ist ein Zeiger. Und weil hbrBackground ein HBRUSH ist, darfst Du da eben kein int drauf zuweisen.

Du wirst den HBRUSH vermutlich auch zu gegebener Zeit wieder freigeben müssen. Die WinAPI reagiert sehr empfindlich, wenn das Muster von Allokation und Freigaben nicht genauso läuft, wie sie sich das vorstellt.

Vielleicht denkst Du doch eher mal über die Installation von GTK, WxWidgets oder Qt nach. WinAPI muss heute nicht mehr sein.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Farb - Variable

Beitrag von cloidnerux » Di Jan 12, 2016 2:16 pm

Ich lerne die Winapi weil das Erscheinungsbild etwas über die Möglichkeiten der Konsole hinausgehen soll und ich keine andere Tools z.B GTK zur Verfügung habe.
Die WinAPI ist alt und es gibt bessere Möglichkeiten. Eine davon ist WinForms in .NET, daher C# programmieren. Sehr viel angenehmer, vor allem dank Visual Studio.
Aber wo soll da ein Zeiger sein? Laut Erklärung ist hbrBackground eine Variable und es gilt:
Richtig, es ist eine Variable. Aber ein Apfel ist keine Orange und wenn du einen Apfel erwartest wunderst du dich auch, wenn du Orangen erhälst. Das selbe gilt hier. hbrBackground ist eine Variable vom Typ "Pointer", du möchtest aber eine Variable vom Typ DWORD(Schwarz) übergeben. Der Compiler sagt dir, dass das inkompatible typen sind. Wertherin ist ein Pointer nicht einfach eine Variable. Es ist ein Zeiger auf eine Stelle im Arbeitsspeicher: https://www.proggen.org/doku.php?id=c:tutorial:pointer.

Warum funktioniert es dann mit "CreateSolidBrush"? Nun weil diese Funktion einen DWORD entgegen nimmt, und einen Pointer darauf erzeugt.
Soweit es nicht direkt mit der Oberfläche zu tun hat, schreibe ich alles was hinter dem Bildschirm als Programmablauf passiert grundsätzlich in C ohne ungarische Notation. Also z.B. statt LPTCTSTR schreibe ich const char *, statt DWORD unsigned int.
Ungarische Notation hat nichts mit dem Typspezifizierer zu tun. Weiterhin machst du dein Programm weniger Kompatibel und fehleranfälliger. In C ist die Byte-Größe von int, short und long nicht normiert, diese können sich je nach Compiler ändern. Du compilierst auf einem anderen Rechner/compiler und dein Programm kann auf einmal nicht mehr Funktionieren. Zudem holst du dir Inkompatibilitäten mit der WinAPI ins haus, da ein "LPTCTSTR" eben nicht immer ein "const char*" ist, sondern abhängig vom "_UNICODE" flag auch mal ein "wchar_t *".
Du kannst in deinem eigenen Code Datentypen verwenden wie du möchtest, sobald du aber mit externen API arbeitest, musst du sehr darauf aufpassen, welche Datenytpen du verwendest.
Jetzt stet's am Anfang und klappt. Aber COLORREF = DWORD = unsigned int. Jedoch reichen für 16 Mill Farben auch 2 Mrd integer im pos Bereich weshalb ich bei static int bleibe.
Punkt 1: Du brauchst höchst wahrscheinlich an der stelle kein "static".
Punkt 2: Signed-ness von Variablen macht einen unterschied. Verwende immer den korrekten Datentyp, da du ansonsten im Probleme läufst, wenn die Werte doch zu groß werden(z.B durch einen zusätzlichen Alpha kanal)
Redundanz macht wiederholen unnötig.
quod erat expectandum

Antworten