Win32-Programmierung mit VC++ und der Win-Api

2.3 - Ein- und Ausgabefelder

Im letzten Kapitel hatten wir schon die Eingafelder behandelt. Jetzt gehts damit auch weiter! Das tolle an diesen Feldern ist, dass sie sowohl für Eingaben, als auch für Ausgaben gemacht sind. Das heißt, wir können rein theoretisch Werte in ein Feld eingeben, etwas damit machen, und dann in das gleiche auch wieder ausgeben. Das macht zwar in der Praxis wenig Sinn, aber …

Ich hab’ hier mal ne kleine Übersicht, was wir alles mit den Eingabefeldern machen können:

  • Int lesen - variable = GetDlgItemInt(hwnd, IDC_xxx, &BOOLVARIABLE, FALSE)
  • String lesen - GetDlgItemText(…)
  • Int schreiben - SetDlgItemInt(hwnd, IDC_xxx, variable, FALSE);
  • String schreiben - SetDlgItemText(hwnd, IDC_xxx, variable);

Ich glaub’ ich brauch an dieser Stelle nicht zu erklären, was die einzelnen Methoden machen. Deshalb weiter. Wir modeln unser letztes Programm (Timer & Eingabefeld) ein wenig um, erweitern es, wie auch immer. Letztendlich läuft es darauf hinaus, dass wir im Ressourceneditor unseren Dialog ein Eingabeelement, hier aber mit der Funktion einer Ausgabe, hinzufügen. Geben wir dem - jetzt Anzeigeelement - die ID “IDC_ANZEIGE”. Da es sich hier um ein Anzeigeelement handelt, sollten wir in den Eigenschaften die Option Schreibgeschützt aktivieren. Damit verhindern wir, dass der DAU (Dümmste anzunehmende User) vielleicht auf die Idee kommt, hier was reinzuschreiben.

Das was unser Programm jetzt machen soll, ist den aktuellen Wert der Variable position auf unser neues Anzeigeelement auszugeben.Dazu ändern wir unseren Quellcode folgendermaßen ab:

void Init ...

void CALLBACK IncTimer1 (HWND hwnd, UINT iMsg, UINT iTimer, DWORD dwTime)
{
    progress++;

    if(progress<100)
    {
        Init(hwnd);
    }

    if(progress>=100)
    {
        progress=0;
        Init(hwnd);
    }

    SetDlgItemInt(hwnd, IDC_ANZEIGE, progress, FALSE);
}

LRESULT CALLBACK WindProc ...

Hier haben wir soeben unserem Programm mitgeteilt, dass, wenn unser Timer gestartet wurde und der Balken somit automatisch inkrementiert, der Fortschrittswert (progress) in unser neues Anzeigeelement geschrieben werden soll. Das wars schon!

Weiter gehts mit den Text (strings).

Hier funktioniert der Kram genauso! Nur dass anstatt einer z.B SetDlgItemInt(..)- eine SetDlgItemText(…) Funktion verwendet wird. Hier muss natürlich anstatt einer Int-Variable ein Char[xx] verwendet werden.

Wir fügen also unserem Dialog ein neues Anzeigefeld ein. Diesmal mit der ID “IDC_STATUS”. In dieses Element soll der Status ausgegeben werden, ob der Automatikmodus aktiviert oder deaktiviert ist, bzw. wurde.

Dazu fragen wir in unsererm WindProc(…) die Buttons Start (IDC_AUTO) und Stop (IDC_STOP) ab und senden je nachdem welcher betätigt wurde, den Text “Aktiv” oder “Deaktiviert”.

Um nun aber einen Text zu schicken sollten wir vorher die beiden Strings in zwei Char-Variablen definieren.Um das zu machen, müssen wir aber auch eine Header Datei neu einbinden:

#include <stdio.h>
...
char aktiv[10];
char deaktiv[10];

Hiermit haben wir aber erst 2 leere Chars angelegt. Die müssen wir noch mit Inhalt füllen. Ich persönlich bevorzuge die Methode sprintf(…). Das sei nun aber jedem selber überlassen, wie er einen Text seiner Wahl einer Variable zuweist.

Erweitern wir nun unseren Quellcode um folgende 2 Zeilen:

case WM_CREATE: 
{
    sprintf(aktiv, "aktiv");
    sprintf(deaktiv, "deaktiv");
}
break;

Jetzt muss unser Text noch angezeigt werden. Dazu muss eine Codeänderung vorgenommen werden:

...
case IDC_AUTO:
{
    SetDlgItemText(hwnd, IDC_STATUS, aktiv);
    BOOL bSuccess;
    zeit = GetDlgItemInt(hwnd, IDC_ZEIT, &bSuccess, FALSE);
    SetTimer(hwnd, INCTIMERID1, zeit, (TIMERPROC) IncTimer1);
}
break;

case IDC_STOP:
{
    SetDlgItemText(hwnd, IDC_STATUS, deaktiv);
    KillTimer(hwnd, INCTIMERID1);
}
break;
...

Auch hier gilt wieder: Ausprobieren und antesten. Wenn’s nicht funzt, hier ist der Quellcode: Ein-Ausgabefeld.zip - 50KB