## Hello World in Win32 API

    1 DLGINCLUDE "generic.h"

    AboutDlg DIALOG FIXED 6, 21, 198, 99
    STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION "About Hello World"
    FONT 8, "MS Shell Dlg"
    BEGIN
     DEFPUSHBUTTON   "&OK", IDOK,                72, 74, 40,  14
     LTEXT           "Hello World!",            104, 45, 14, 128, 8
     LTEXT           "Written using",           105, 45, 35,  59, 8
     LTEXT           "Microsoft API",           106, 45, 45,  98, 8
    END

    DBDlg DIALOG FIXED 6, 21, 198, 99
    STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION "Hello from DB"
    FONT 12, "Arial"
    BEGIN
     DEFPUSHBUTTON   "&OK",     IDOK,            20, 74, 40,  14
     DEFPUSHBUTTON   "&Cancel", IDCANCEL,       150, 74, 40,  14
     LTEXT           "Hello World!",            104, 45, 14, 128, 8
     LTEXT           "Written using",           105, 45, 35,  59, 8
     LTEXT           "Microsoft API",           106, 45, 45,  98, 8
    END

    DLG_0100 DIALOG FIXED 6, 21, 206, 99
    STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION "Hello from DB again"
    FONT 12, "Arial"
    BEGIN
     CONTROL         "", 104, "Static", SS_BLACKFRAME, 5, 5, 201, 90
     DEFPUSHBUTTON   "&OK",       IDOK,        10, 10, 40, 15
     DEFPUSHBUTTON   "&Cancel",   IDCANCEL,    51, 10, 40, 15
     CONTROL         "Name", ID_DBEDIT, "edit", ES_LEFT, 10, 50, 190, 12
    END

    #include <windows.h>
    #include "generic.h"
    #include "generic.dlg"

    AppMenu MENU
    {
       POPUP "&File"
       { MENUITEM "&Open",  ID_OPEN
         MENUITEM "&Close", ID_CLOSE
       }

       POPUP "&Help"
       { MENUITEM "&Help",     ID_HELP
         MENUITEM "&About",    ID_ABOUT
         MENUITEM "Dialog &1", ID_DLG1
         MENUITEM "Dialog &2", ID_DLG2
       }
    }

    //windres generic.rc generic.o
    //gcc -o gen gen.c generic.o -mwindows -DDEBUG
    //gcc -o gen gen.c generic.o -mwindows
    //

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

    #define MESG1 "Hello World! About 170 lines of code for Hello World!. Not bad, eh?"
    #define MESG2 "No wonder it takes about 100 million lines of code for Win 2000."
    #define MESG3 "I suppose Bill Gates gets about a $1 per line."
    #define BUFSZ 100

    LRESULT WINAPI MainWndProc  ( HWND, UINT, WPARAM, LPARAM );
    LRESULT WINAPI AboutDlgProc ( HWND, UINT, WPARAM, LPARAM );
    LRESULT WINAPI DBDlgProc    ( HWND, UINT, WPARAM, LPARAM );
    LRESULT WINAPI DLG_0100Proc ( HWND, UINT, WPARAM, LPARAM );
    BOOL    GetFileName         ( HWND, LPSTR, BOOL);

    HANDLE ghInstance;
    static HINSTANCE g_hInst = NULL;

    char dlgMsg[BUFSZ];

    int WINAPI WinMain( HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpszCmdLine,
                        int nCmdShow )
    {  WNDCLASS wc;
       MSG msg;
       HWND hWnd;

       if( !hPrevInstance )
       {
          wc.lpszClassName = "GenericAppClass";
          wc.lpfnWndProc = MainWndProc;
          wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
          wc.hInstance = hInstance;
          wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
          wc.hCursor = LoadCursor( NULL, IDC_ARROW );
          wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 );
          wc.lpszMenuName = "AppMenu";
          wc.cbClsExtra = 0;
          wc.cbWndExtra = 0;

          RegisterClass( &wc );
       }

       ghInstance = hInstance;
       strcpy(dlgMsg,"David Beech");

       hWnd = CreateWindow( "GenericAppClass",
          "Generic Application",
          WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,
          0,
          0,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          NULL,
          NULL,
          hInstance,
          NULL
       );

       ShowWindow( hWnd, nCmdShow );

       while( GetMessage( &msg, NULL, 0, 0 ) )
        { TranslateMessage( &msg );
          DispatchMessage( &msg );
        }

       return msg.wParam;
    }

    LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
       PAINTSTRUCT ps;
       HDC hDC;
       char szFileName[MAX_PATH];

       switch( msg )
        { case WM_PAINT:
           hDC = BeginPaint( hWnd, &ps );
           TextOut( hDC, 10, 10, MESG1, strlen(MESG1) );
           TextOut( hDC, 10, 30, MESG2, strlen(MESG2) );
           TextOut( hDC, 10, 50, MESG3, strlen(MESG3) );
           EndPaint( hWnd, &ps );
           break;

          case WM_CREATE:
            CreateWindow("EDIT", "",
                         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE |
                         ES_WANTRETURN,
                         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                         hWnd, (HMENU)IDC_MAIN_TEXT, g_hInst, NULL);

             SendDlgItemMessage(hWnd, IDC_MAIN_TEXT, WM_SETFONT,
                (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0));
          break;

          case WM_COMMAND:
           switch( wParam )
            { case ID_ABOUT:
               DialogBox( ghInstance, "AboutDlg", hWnd, (DLGPROC) AboutDlgProc );
               break;
              case ID_DLG1:
               if (!DialogBox( ghInstance, "DBDlg", hWnd, (DLGPROC) DBDlgProc ))
                MessageBox(hWnd, "Unable to execute dialog 1", "Error", MB_YESNOCANCEL);
               break;
              case ID_DLG2:
               if (DialogBox( ghInstance, "DLG_0100", hWnd, (DLGPROC) DLG_0100Proc ))
                {
    #ifdef DEBUG
                  MessageBox(0, dlgMsg, "Received", MB_OK);
    #endif
                  SetWindowText(hWnd, dlgMsg);
                }
               else
                MessageBox(hWnd, "Unable to execute dialog 2", "Error", MB_YESNOCANCEL);
               break;
              case ID_OPEN:
               if (!GetFileName(hWnd, szFileName, FALSE))
                break;
               else
                { HANDLE hFile;
                  if (( hFile = CreateFile
                         ( (LPCSTR) szFileName,
                           GENERIC_READ,
                           FILE_SHARE_READ,
                           NULL,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           (HANDLE) NULL)) == (HANDLE) (-1))
                   { MessageBox(hWnd, "File open failed.", NULL, MB_OK);
                     break;
                   }
                  else //read the file into a buffer
                   { char inBuffer[200];
                     int nBytesToRead = 199;
                     int nBytesRead = 0;
                     BOOL bResult;
                     MessageBox(hWnd, "File open OK.", "OK", MB_OK);
                     bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL);
                     if (bResult)
                       MessageBox(hWnd, "File read OK.", "OK", MB_OK);
                   }
                }

               break;

            }
          break;

          case WM_DESTROY:
           PostQuitMessage( 0 );
           break;

          default:
           return( DefWindowProc( hWnd, msg, wParam, lParam ));
     }

     return 0;
    }

    LRESULT CALLBACK AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
      switch( uMsg )
       { case WM_INITDIALOG:
          return TRUE;
         case WM_COMMAND:
          switch( wParam )
           { case IDOK:
              EndDialog( hDlg, TRUE );
              return TRUE;
           }
          break;
       }

       return FALSE;
    }

    LRESULT CALLBACK DBDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
      switch( uMsg )
       { case WM_INITDIALOG:
          return TRUE;
         case WM_COMMAND:
          switch( wParam )
           { case IDOK:
              EndDialog( hDlg, TRUE );
              return TRUE;
           }
          break;
       }

       return FALSE;
    }

    LRESULT CALLBACK DLG_0100Proc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
    { char buf[BUFSZ];
      int  count;

    #ifdef DEBUG
      char b[20];
    #endif

      switch( uMsg )
       { case WM_INITDIALOG:
          count = SendDlgItemMessage(hDlg, ID_DBEDIT, EM_SETLIMITTEXT,
                                     (WPARAM) BUFSZ - 1, (LPARAM) 0);
          count = SendDlgItemMessage(hDlg, ID_DBEDIT, WM_SETTEXT,
                                     (WPARAM) 0, (LPARAM) dlgMsg);
          return TRUE;
         case WM_COMMAND:
          switch( wParam )
           { case IDOK:
              count = SendDlgItemMessage(hDlg, ID_DBEDIT, WM_GETTEXT,
                                        (WPARAM) BUFSZ - 1, (LPARAM) buf);
              strncpy(dlgMsg, buf, BUFSZ - 1);
    #ifdef DEBUG
              sprintf(b,"%d chars", count);
              MessageBox(0, b, dlgMsg, MB_OK);
    #endif
              EndDialog( hDlg, TRUE );
              return TRUE;
           }
          break;
       }

       return FALSE;
    }

    BOOL GetFileName(HWND hwnd, LPSTR pszFileName, BOOL bSave)
    {
     OPENFILENAME ofn;
     char pszTitle[20];

     ZeroMemory(&ofn, sizeof(ofn));
     pszFileName[0] = '\0';

     ofn.lStructSize = sizeof(ofn);
     ofn.hwndOwner = hwnd;
     ofn.lpstrFilter = "C/C++ files\0*.cpp;*.cc;*.cx;*.c\0"
                       "Text Files (*.txt)\0*.txt\0Header files\0*.h;"
                       "*.hpp\0All Files (*.*)\0*.*\0\0";
     ofn.lpstrFile = pszFileName;
     ofn.nMaxFile = MAX_PATH;
     ofn.lpstrDefExt = "TXT";
     ofn.lpstrInitialDir = ".";

     if (bSave)
      { strcpy(pszTitle,"File Dialog");
        strcat(pszTitle," - Save.");
        ofn.lpstrTitle = pszTitle;
        ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY |
                    OFN_OVERWRITEPROMPT;
        if ( !GetSaveFileName(&ofn) )
         return FALSE;
      }
     else
      { strcpy(pszTitle,"ASE File Dialog");
        strcat(pszTitle," - Open.");
        ofn.lpstrTitle = pszTitle;
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
        if ( !GetOpenFileName(&ofn) )
         return FALSE;
      }
     return TRUE;
    }