#include <windows.h>
#include <string.h>

char szAppName[20];   // Klassen-Name für dieses Window
HWND hInst;           // Instanz-Handle
HWND hWndMain;        // Window-Handle

// Prototypen (siehe unten)
LONG FAR PASCAL WndProc(HWND, WORD, WORD, LONG);
int nCwRegisterClasses(void);
void CwUnRegisterClasses(void);


int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
                   LPSTR lpszCmdLine, int nCmdShow)
{
 /***************************************************
  * Hier startet das Programm.                      *
  * Diese Funktion wird nur von Windows aufgerufen! *
  ***************************************************/

 MSG        msg;  // Message-Struktur
 int        nRc;  // Return-Wert von RegisterClasses

 strcpy(szAppName, "Demo");
 hInst = hInstance;
 if(!hPrevInstance)
   {
    // Wenn es die erste Instanz ist, Klasse registrieren
    if ((nRc = nCwRegisterClasses()) == -1)
      {
       // Wenn Fehler beim Registrieren
       MessageBox(NULL, "Konnte Klase nicht registrieren",
                  "Sorry", MB_ICONEXCLAMATION);
       return nRc;
      }
   }

 // Klasse gibt es, also Window anlegen:
 hWndMain = CreateWindow(
             szAppName,         // Name der Applikation
             "Text des Titels", // Das sog. Caption
             WS_CAPTION      |  // Hat Titelleiste und
             WS_SYSMENU      |  // System-Menü und
             WS_MINIMIZEBOX  |  // Minimum-Box und
             WS_MAXIMIZEBOX  |  // Maximum-Box und
             WS_THICKFRAME   |  // Malt nicht in Child-Windows
             WS_OVERLAPPED,     // Kann überlappen
             CW_USEDEFAULT, 0,  // Default für links oben
             CW_USEDEFAULT, 0,  // Default für rechts unten
             NULL,              // Ist keine MDI-Applikation
             NULL,              // Default ist Klassen-Menü
             hInst,             // Instanz dieses Windows
             NULL);             // Kein Struct für WM_CREATE


 if(hWndMain == NULL)
   {
    MessageBox(NULL, "Konnte Window nicht anlegen",
               "Sorry", MB_ICONEXCLAMATION);
    return 1;
   }

 ShowWindow(hWndMain, nCmdShow);     // Window anzeigen

 while(GetMessage(&msg, NULL, 0, 0)) // Endlos
   {
    TranslateMessage(&msg);              // Keys übersetzen
    DispatchMessage(&msg);               // Message an WndProc

   }                                 // bis WM_Quit-Message

 // Rückzugsgefechte und Ende
 CwUnRegisterClasses();
 return msg.wParam;
} //  End of WinMain


/***********************************************
 *                                             *
 * WndProc (Main Window Procedure)             *
 *                                             *
 * Hierher sendet Windows Messages über alle   *
 * Events, egal ob das User-Aktionen sind oder *
 * Windows-Messages.                           *
 ***********************************************/

LONG FAR PASCAL WndProc(HWND hWnd, WORD Message,
                        WORD wParam, LONG lParam)
{
 HDC         hDC;    // Handle für Display-Device-Context
 PAINTSTRUCT ps;     // Hält PAINT-Informationen
 int         nRc=0;  // Return-Code

 switch (Message)
   {
    case WM_PAINT: // Neuzeichnen evtl. nötig
         memset(&ps, 0x00, sizeof(PAINTSTRUCT));
         hDC = BeginPaint(hWnd, &ps); // Melde Start
         SetBkMode(hDC, TRANSPARENT); // Hintergrund löschen
         TextOut(hDC, 20, 20, "Hallo Welt!", 11);
         EndPaint(hWnd, &ps); // Melde, daß Painting fertig
         break;

    case WM_CLOSE: // User schließt Window
         DestroyWindow(hWnd);   // Window abbauen.
         if (hWnd == hWndMain)  // Wenn es das letzte ist,
           PostQuitMessage(0);  // Ende melden
        break;

    default:
         // Für alle Messages, die keine Service-Routine haben,
         // Messages an Windows für Default-Prozess zurück:
         return DefWindowProc(hWnd, Message, wParam, lParam);
   }
 return 0L;
}     // End of WndProc

/*************************************************
 *                                               *
 * Generelle Funktion.                           *
 *                                               *
 * Registriert alle Klassen aller Windows,       *
 * die zur Applikation gehören.                  *
 * Return: 0, wenn erfolgreich, sonst Error-Code *
 *                                               *
 *************************************************/

int nCwRegisterClasses(void)
{
 WNDCLASS   wndclass; // Struct der Windowsklasse
 memset(&wndclass, 0x00, sizeof(WNDCLASS));


 // Stuktur laden:
 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
 wndclass.lpfnWndProc = WndProc;
 // Kein Extra-Storage für Klassen- und Windows-Objekte:
 wndclass.cbClsExtra = 0;
 wndclass.cbWndExtra = 0;
 wndclass.hInstance = hInst;
 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 // Brush für Hintergrund-Löschen anlegen:
 wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
 wndclass.lpszMenuName = szAppName;  // Menü-Name = App.-Name
 wndclass.lpszClassName = szAppName; // Klassen-Name = App.-Name

 return RegisterClass(&wndclass); // Registrieren
} // End of nCwRegisterClasses

/********************************************
 *  CwUnRegisterClasses-Funktion            *
 *                                          *
 *  Löscht alle Refrenzen zu den Resourcen  *
 *  und alle Handles und gibt Speicher frei.*
 ********************************************/

void CwUnRegisterClasses(void)
{
 WNDCLASS   wndclass;
 memset(&wndclass, 0x00, sizeof(WNDCLASS));

 UnregisterClass(szAppName, hInst);
}
